Category: Java/.NET Runtime

Q

When is the JVM loaded into my .NET process?

A

If you do nothing explicit, the JVM is loaded the first time you perform an activity with a proxy type that requires access to the Java side.

This is not as simple a statement as it sounds. Consider the following C# snippet that's part of some class declaration:

// creates a static instance that is used as a singleton
static MyJavaType SINGLETON = new MyJavaType( true, 42 );  

The above snippet is deeply flawed and will crash on startup. You start debugging and find that you don't even get to a breakpoint that you set on the first line of Main(). What's going on here? The answer is that the static variable might get initialized before your Main() really starts to execute because it's referenced by some .NET types that cause the class initializer of your type to execute. If this were a pure .NET type that wouldn't be so bad, but it's a proxy type. Calling its constructor requires a JVM to be loaded, so the framework takes care of that. Unfortunately, the framework doesn't know that you're going to set the classpath later, so it will initialize the JVM with a default classpath (only built-in types). Your constructor call will fail with a ClassNotFoundException that is thrown from within the .NET runtime. Avoid static proxy objects for this reason.

You can also explicitly load the JVM, which is something that we recommend as a best practice. Whichever factory method you might be using, have a function that does nothing but load the JVM and handle any initialization errors you can find before you start going deep into your application and end up with a hard-to-debug partial failure. Your initialization function might look something like this:

IJvm   InitJvm()
{
    IJvm result = null;

    try
    {
        // get a loader and configure it with the proper init settings
        IJvmLoader  loader = JvmLoader.GetJvmLoader( ... );

        loader.JvmPath = @"";
        loader.AppendToClassPath( ... );
        loader.MaximumHeapSizeInMB = 512;

        // check whether we already loaded a JVM and return it if yes
        result = loader.GetJvm();
        if( result == null )
        {
            // otherwise attempt to load a JVM explicitly
            result = loader.Load();
        }    
    }
    catch( JuggerNETException jne )
    {
        // handle the error in an application-specific way
    }
 
    // return the loaded JVM or null; your application can use the
    // return value to test for successful initialization
    return result;
} 

With a function such as the above, you can simply invoke it in your Main() and it handles all the JVM interactions.


Copyright 2006-2011 by Codemesh, Inc., ALL RIGHTS RESERVED

:
frequently asked questions
home products support customers partners newsroom about us contact us