Larry Hanson
Visual J++ Product Team
Updated March 11, 1998
This article is about developing Microsoft® Transaction Server (MTS) application components in Java using Visual J++™ 6.0. I will show you, step-by-step, how to use Visual J++ 6.0 to write and build a server-side Java MTS component that can be called by a Java client application. Next, I will show you how to debug the server-side component on your development machine. Finally, I will explain how to deploy the server component and the client application to separate machines.
To build and run the samples, you will need both Microsoft Visual J++ 6.0 Technology Preview 1 and Microsoft Transaction Server. For download information on Visual J++ 6.0 Technology Preview 1 go to http://msdn.microsoft.com/visualj/. Microsoft Transaction Server is part of the Windows NT® Option Pack 4.0. For download information go to http://www.microsoft.com/NTServer/web/exec/overview/option_pack4.asp.
I'll assume that you know the basics of the Java programming language, Component Object Model (COM), and MTS programming. If you are new to MTS programming, a good place to start is the Programmer's Guide in Microsoft Transaction Server Help. Reading the "MTS Overview and Concepts" and "Developing Applications for MTS" sections will provide more than enough background for this article.
The following explains the steps for creating a simple MTS component for Java using Visual J++ 6.0.
A Java component must be packaged as a COM DLL to be used by MTS. You can easily create a COM DLL project in Visual J++ by selecting New Project in the File menu then choosing the COM DLL project template under Visual J++, Components in the tree view. Name the project JavaServer and choose Open.
Rename the default Class1.java file to JavaServerClass.java in the Project Explorer and change the contents of the file to the following code:
import com.ms.mtx.*;
public class JavaServerClass
{
public String MTSMethod()
{
IObjectContext context = null;
boolean success = false;
String result = "No result";
try
{
// Get MTS context and set the return data
context = (IObjectContext) MTx.GetObjectContext();
result = "Hello from JavaServer";
success = true;
}
catch(Exception e)
{
success = false;
}
finally
{
if(success)
context.SetComplete(); // No errors. Complete transaction.
else
context.SetAbort(); // Error occurred. Abort transaction.
}
return result;
}
}
To use the class in MTS you must mark the class as a COM and MTS class. Visual J++ provides a simple way to mark a class as a COM and MTS class through the Class Builder. Activate the Class Builder by selecting Other Windows in the View menu and selecting Class Builder. Select the JavaServerClass class and check the MTS Support Enabled checkbox. Select Supported in the drop down list. You will notice new code appear in JavaServerClass.java marking the class as a COM and MTS class that looks something like the following:
/**
* @com.register ( clsid=A6D25C85-B6DC-11D1-9BAD-00A0C905438F, typelib=A6D25C86-B6DC-11D1-9BAD-00A0C905438F )
* @com.transaction (required)
*/
To build the project, simply choose Build under the Build menu. Building the project creates a COM-aware DLL file called JavaServer.dll. This DLL contains the JavaServerClass.class and the appropriate stub code so that the DLL can be registered just like any COM DLL written in C++ or Visual Basic. This DLL file will be deployed to MTS in the next step.
Start the MTS Explorer and create a new package named JavaServer. If you've never created a new MTS package, see "Creating MTS Packages" in the Microsoft Transaction Server Administrator's Guide in Microsoft Transaction Server Help. Add the new JavaServer.dll component to the JavaServer package you created. Be sure to select Install New Components in the MTS Explorer Component Wizard rather than Import Components.
When we use the MTS Explorer to deploy our component, it will see the required attribute that Visual J++ marked the class with and recognize our component as needing a transaction. Alternatives to required are supported, notSupported, and requiresNew.
If you make changes to the project and rebuild it after deploying to MTS, you will need to re-register your component in MTS. You can do this by right clicking My Computer in the MTS Explorer and selecting Refresh All Components.
Now that we have written, built, and deployed an MTS Java component, we need a client that can consume the component. The client can be written in Java, Visual Basic®, or C++®. The following explains the steps for creating a simple Windows Foundation Classes (WFC)-based client using Visual J++ 6.0 that can consume the MTS component for Java we created in the previous section. For more information about WFC see the "Introduction to WFC Programming" section in the Visual J++ 6.0 Programmer's Guide.
You can easily create a Windows Application project in Visual J++ by selecting New Project in the File menu, then choosing the Windows Application project template under Visual J++ Applications in the tree view. Name the project JavaClient and choose Open.
Note Visual J++ 6.0 Technology Preview 1 requires that the JavaServer and JavaClient projects be in separate solutions. To work around this problem, close the JavaServer project before creating the new JavaClient project. This problem will be addressed in the final released version of Visual J++ 6.0.
Although both the component and the client are written in Java, the client must access the component through COM rather than a direct Java call. Creating and calling the component through COM allows MTS to hook into the creation of the component and provide the right services. An additional benefit of using COM is that it allows us to communicate with this component between machines in the future.
Set up COM access to the Java MTS component by adding COM wrappers to the component. Select Add COM Wrapper in the Project menu. Check the box next to JavaServer in the list of installed COM components in the COM Wrappers dialog and press OK. You will notice a package called javaserver has been added to the JavaClient project.
Now we need to add code to the application's form to interact with the Java MTS component. First, let's add a label to the form. JavaClient has a default form called Form1. Double click Form1.java in the Project Explorer and Form1 will appear in the Form Designer. Select Toolbox in the View menu to view the toolbox and select the WFC Controls tab. Drag a Label onto the form. It will be named label1 by default.
Double click on the Form1 in the Form Designer and the code for the click event for the form will appear. Add code to import the javaserver COM wrappers by placing the following import statement after the existing import statements in Form1.java:
import javaserver.*;
Add code to call the Java MTS component from the form's click event method by placing code that calls the Java MTS component method and updates the label with the results. The Form1_click method should look something like the following:
private void Form1_click(Object sender, Event e)
{
JavaServerClass_Dispatch server = JavaServerClass_Dispatch)new JavaServerClass();
label1.setText(server.MTSMethod());
}
When JavaClient runs and we click on the form, a call will be made to the Java MTS component and a transaction will be started. If the component executes without error, the call to MTSMethod will update the result. Call SetComplete() and the transaction will be committed. The string will be returned to the client and label1 will be updated with the text "Hello from JavaServer".
Select Build under the Build menu to build the project. Building the project creates a Windows executable with all of the class files needed to execute JavaClient, including the COM wrappers for JavaServer, packaged into one executable file.
If the JavaClient project and the JavaServer project are part of the same solution, before you can run the client from the environment, you must first mark the JavaClient project as the startup project. Right click on JavaClient in the Project Explorer and select "Set as startup project" in the context menu. To run the client, select Start from the Debug menu. Run JavaClient and click on the form. After a short pause, you should see the label updated with the text "Hello from JavaServer". You can view the transaction statistics of the component as it is being called from the client in the Transaction Server Explorer.
With Visual J++ 6.0 you can debug MTS components within the Visual J++ Integrated Development Environment (IDE). To debug your Java MTS component in Visual J++ use these steps to set up debugging. Each of these steps is made either inside the MTS Explorer or inside of a Visual J++ session with your JavaServer COM DLL project.
Note You may experience problems when debugging MTS Java components with Visual J++ 6.0 Technology Preview 1. These problems will be addressed in the final release version of Visual J++ 6.0.
Once you have written and debugged the MTS Java component you will want to set up the component on a machine other than your development machine such as a staging server or a production server. It is very easy to setup your component on a different machine. All you have to do is copy the Java MTS component DLL (JavaServer.dll in this case) to the other machine and then register the component in the MTS Explorer the same way you did on the development machine. See step 5 of "Writing and Building an MTS Java Component" above for the steps to register the component in MTS.
With Visual J++ version 6.0 you can package all of the files required to run and register your client application in a single self-extracting setup executable. The excellent capabilities of Visual Studio make this very easy.
To create a self-extracting setup project, select New Project from the File menu and then select Self-Extracting Setup under Visual Studio, Distribution Units. Name the project JavaClientSetup and select Open.
The setup must contain all the files required to run the client. JavaClient.exe contains most but not all of the files required. In addition, we need to include two important files that allow the client on one machine to communicate with the MTS Java component on the separate server machine. These files are JavaServer.tlb and JavaServer.vbr.
Select Add Item in the Project menu and browse to the JavaClient project directory. Select the file JavaClient.exe and select Open to add it to the setup. Select Add Item in the Project menu, but this time browse to the JavaServer project directory. Select the files JavaServer.tlb and JavaServer.vbr and select Open.
Here is where the .tlb and .vbr files that we added to the project in the previous step come into play. The setup has to know how to configure the client machine to communicate with the MTS Java component on the server. The .tlb and .vbr file work together to supply this information to the setup. First the setup must be made aware of the remote component.
Select JavaClientSetup Properties from the Project menu and select the Remote Components tab. JavaServer should be in the list of Remote Components. Check the box next to JavaServer. Doing this activates the remote server machine options. You can choose a remote server machine that the setup will always use by entering the name of the machine in the Use Remote Server text box. Or you can check the Always Prompt User for Server so that the setup will always ask when setup is run. Press OK or Apply to commit the settings.
You can customize various settings of the setup by selecting JavaClientSetup Properties from the Project menu and selecting the Target tab. In this case, change the Application title and Installation folder to JavaClient. Check the Create an Entry in the Start Menu check box and change the Shortcut name to JavaClient. Finally, enter the following string into the Command line Program text box: <appdir>\JavaClient.exe. Now when you run your setup on a machine a Start menu item will allow you to quickly and easily run the client application.
To create the setup program select Build in the Build menu. You now have all the files and code required to set up the Java client that access the MTS Java component in a single, self-extracting setup program.
Note Self-extracting setups created with Visual J++ 6.0 Technology Preview 1 do not include redistributable files required for setting up WFC and other important files. Without these files, the client will not execute correctly. The final released version of Visual J++ 6.0 will include these files in the setup. Until then, applications installed with a self-extracting setup will only run on a machine with Visual J++ 6.0 Technology Preview 1 installed.
One great feature of the self-extracting setup project is that it automatically signs the setup for you. A test certificate is automatically used by default, but you can customize this setting by selecting the project Properties in the Project menu and selecting the Signing tab.
You can deploy your client setup from a Web page, an FTP site, or whatever way is convenient. As a simple test, run JavaClientSetup.exe on a separate machine. When prompted for the remote machine name, enter the name of the machine on which you set up the JavaServer component. Launch JavaClient from the Start menu entry. When the JavaClient form appears, click on the form. After a short pause, you should see the label updated with the text "Hello from JavaServer," except this time the data displayed is coming from a different machine!
You can see from this example that Visual J++ 6.0 makes developing, debugging, and deploying Microsoft Transaction Server–based Java solutions very easy. This sample did not need to use a transaction since it only manipulates very simple data. It's not doing any work on shared, durable backend data. It's not calling any Resource Managers. But the sample serves as a good starting point.
As a next step you could add code to manipulate a database such as a Microsoft SQL Server™ database using the Microsoft ActiveX® Data Objects (ADO) support in WFC. For more information on using ADO from Java see the Microsoft ActiveX Data Objects section in the Visual J++ online help. Microsoft SQL Server provides a Resource Manager and Microsoft Transaction Server takes full advantage of this when the database is accessed from your Java component through ADO, providing a truly robust transaction based server-side Java solution.