Category: Java/.NET runtime
Can I debug the Java parts of my application?
Yes, you can. You need to configure the runtime to allow it though and you need a Java debugger capable of attaching to a remote process. Any spec-compliant Java Runtime Environment comes with a component that allows a remote debugger to attach to a running Java process. This component is called the Java Platform Debugger Architecture (JPDA). One part of this component is the the Java Debug Wire Protocol (JDWP). All you need to debug the Java parts of your .NET process is a debugger that supports JDWP and the correct configuration information.
Before getting into the specifics of how to configure your .NET process, please check out the following links for background information:
Java Platform Debugger Architecture - JPDA Connection and Invocation
Hopefully these links give you some basic understanding of the steps required to remotely debug a java process. Translating these steps into .NET is not all too hard, but how you do it depends on which configuration mechanism you're using. In the sections below, we assume that the settings you wish to configure correspond with the following Java invocation:
java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=1044
-Djava.compiler=NONE -Xnoagent
You might have to fine-tune the options for your debugger and your application, but the general principals will hold true independent of the values that you choose based on your specifc environment.
Explicit Configuration
A nice way to support debugging explicitly is to have a conditional configuration section in your code that keys off an environment variable, for example:
IJvmLoader loader = JvmLoader.GetJvmLoader();
if( Environment.GetEnvironmentVariable( "MYAPP_JAVA_DEBUG" ) != null )
{
loader.Debug = true;
loader.Run = "jdwp:transport=dt_socket,server=y,suspend=n,address=1044";
loader.Noagent = true;
loader.DashDOption[ "java.compiler" ] = "NONE";
}
With this piece in place, all you have to do to switch into debug mode is defining the MYAPP_JAVA_DEBUG environment variable (you could of course use any variable name you wish) in the console or shell you're using to launch the application you wish to debug.
Configuration File
Configuration files have a nice feature that allows you to switch quickly and easily between different configurations by name. You can support debugging by having for example a "Production" section and a "Debug" section in your file and then just changing one attribute to select the "Debug" section during development. You can use this feature or you can simply have some commented elements in your configuration which you uncomment for debug sessions. In general, the configuration file might look like this:
<configuration>
<codemesh>
<runtime>
<Loader name="Debug" />
<Production.JvmSettings>
<add key="ClassPath" value="..\.." />
<add key="TraceLevel" value="TraceInfo" />
<add key="InitialHeapSize" value="256" />
<add key="MaximumHeapSize" value="256" />
</Production.JvmSettings>
<Production.Options>
<add key="test" value="value" />
<add key="novalue" value="" />
<add key="com.codemesh.test" value="456" />
</Production.Options>
<Production.XOptions>
<add key="X:+UseParallelGC" value="" />
</Production.XOptions>
<Debug.JvmSettings>
<add key="ClassPath" value="..\.." />
<add key="TraceLevel" value="TraceInfo" />
<add key="InitialHeapSize" value="256" />
<add key="MaximumHeapSize" value="256" />
<add key="Debug" value="true" />
<add key="Noagent" value="true" />
<add key="Run" value="jdwp:transport=dt_socket,server=y,suspend=n,address=1044" />
</Debug.JvmSettings>
<Debug.Options>
<add key="test" value="value" />
<add key="novalue" value="" />
<add key="com.codemesh.test" value="456" />
<add key="java.compiler" value="NONE" />
</Debug.Options>
<Debug.XOptions>
<add key="X:+UseParallelGC" value="" />
</Debug.XOptions>
</runtime>
</codemesh>
</configuration>
