Platform SDK: Transaction Server

Debugging Java Classes

[This product will work only on Windows NT 4.0 versions and earlier. For Windows 2000 and later, see COM+ (Component Services).]

Using Visual J++ 6.0

Because you can use Visual J++ version 6.0 to debug MTS components completely within the Visual J++ Integrated Development Environment (IDE), the debugging topics below do not apply to Visual J++ 6.0, and are included only for those using earlier versions of Visual J++.

For more information about debugging MTS components in Visual J++ 6.0, please see the Visual J++ 6.0 documentation.

Using Visual J++ 1.1 or 1.0

If you are using Visual J++ 1.1 or earlier, you cannot use the Visual J++ IDE to debug your MTS component. Once your Java class is converted into an MTS component it is not possible to step through the code in the Visual J++ debugger.

Using Visual J++ to Debug Java Classes

Microsoft Visual J++ provides a Java debugger that you can use to set breakpoints in your code. Note that when you are using Visual J++ to debug, if you set a breakpoint in a Java source file before starting the debugging session, Visual J++ may not stop on the breakpoint. For performance reasons, the debugger preloads only the main class of your project. The main class is either the class with the same name as the project or the class you specify in Visual J++. If you use the editor to set breakpoints in other classes before the classes are loaded, the breakpoints are disabled.

You can choose one of the following options to load the correct class so that the debugger stops at breakpoints.

When a method has one or more overloaded versions and shows up as a called method in the Call Stack window, the type and value for the parameters are not displayed in some cases. It appears as though the method takes no parameters. This occurs when the called method is not defined as the first version of the overloaded method in the class definition. For example, see the following class definition:

public class Test
   {
       int method(short s)
       {
           return s;
       }

       int method(int i)
       {
           return i;
       }
   }

If you were looking at a call to the second version of the method in the Call Stack window, it would appear without the type and value for the method:

method()

To view the method’s parameters, change the order of the method overloads so that the method that you are currently debugging is first in the class definition.

printf-style Debugging

You can use printf-style debugging to debug your Java classes without using a debugger. printf-style debugging involves including status text messages into your code, allowing you to "step through" your code without a debugger. You can also use printf-style debugging to return error information. The following code shows how you can add a System.out.println call to the try clause of the Hellojtx.HelloObj.SayHello sample.

try
{    
System.out.println("This message is from the HelloObj implementation");
    result[0] = "Hello from simple MTS Java sample";
    MTx.GetObjectContext().SetComplete();
    return 0;
}

The client must be a Java client class, and you must use the JVIEW console window to run that class. Note that you need to configure your component to run in the process of its caller, which is in this case JVIEW. Otherwise, this debugging technique results in your component running in the MTS server process (mtx.exe), which would put the println output in the bit bucket rather than the JVIEW console window.

Use the MTS Explorer to configure your component to run in the caller's process by following these steps.

  1. Right-click the component.
  2. Click the Properties option.
  3. Click the Activation tab and clear the In a server process on this computer checkbox.
  4. Select the In the creator’s process... checkbox.
  5. Reload the Client class. Your component's println calls will be visible in the JVIEW console window.

Using the AWT Classes

You can also use the AWT (Abstract Window Toolkit) classes to display intermediate results, even if your component is running in a server process. The java.awt package provides an integrated set of classes to manage user interface components such as windows, dialog boxes, buttons, checkboxes, lists, menus, scrollbars, and text fields.

The following example demonstrates how to use the AWT classes to display intermediate results in a dialog box:

import java.awt.*;

public final class MyMessage extends Frame
{

    private Button closeButton;
    private Label textLabel;

    // constructor
    public MyMessage(String msg)
    {
        super("Debug Window");

        Panel panel;

        textLabel = new Label (msg, Label.CENTER);
        closeButton = new Button ("Close");

        setLayout (new BorderLayout (15, 15));
        add ("Center", textLabel);

        add ("South", closeButton);

        pack();
        show();
    }

    public boolean action (Event e, Object arg)
    {

        if (e.target == closeButton)
        {
            hide();
            dispose();
            return true;
        }

        return false;
    }

}

Asynchronous Java Garbage Collection

Note that garbage collection for Java components is asynchronous to program execution and can cause unexpected behavior. This behavior especially affects MTS components that perform functions such as enumerating through the collections in the catalog because the collection count will be too high (garbage collection is not synchronized). To force synchronous release of references to COM or MTS objects, you can use the release method defined in class com.ms.com.ComLib.

Example:

Import com.ms.com.ComLib
…
ComLib.release(someMTSObject);

This method releases the reference to the object when the call is executed. Release the object reference when you are sure that the reference is no longer needed. Note that if you fail to release the reference, an application error is not returned. However, an incorrect collection count results because the object reference is released asynchronously when the garbage collector eventually runs.

You can also force the release of your reference and not call that released reference again.

Example:

myHello = null;
    System.gc();

Note that this method of forcing the release of an object reference consumes extensive system resources, and is not guaranteed to work in all cases. For more information, please see Microsoft Knowledge Base article number Q179062 available at http://support.microsoft.com/support/search/.

It is recommended that you use the release method defined in com.ms.com.ComLib class to release references to MTS objects in a synchronous fashion.