Lesson 2: Running a proxy executable

Introduction

In the previous lesson you learned how to build a .NET application that can load a Java Virtual Machine. In this lesson, we're going to try to run that application. Please complete the previous lesson if you have not done so yet, otherwise you have nothing to run.

You now know that you have to link with a managed Codemesh runtime library by adding to your compilation a reference to either netrt.dll or netrtsn.dll. That was all you had to do to make the project build. Let's see what might be required to get the built application to run.

Execution

The JuggerNET-enhanced application that you built doesn't do anything useful, but it is a .NET console executable that can (theoretically) launch a Java Virtual Machine.

Let's try to run the built application and see what happens.You get a message box and an error message, probably looking like this:

 

error message

C:\juggernet\doc\tutorial\dotnet\v3\L_01>Myapp

Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'netrt, Version=3.6.0.0, 
   Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
   File name: 'netrt, Version=3.6.0.0, Culture=neutral, PublicKeyToken=null'
   at MyProduct.MyApp.Main(String[] args)
            

What happend? We referenced the netrt.dll assembly in the build and that made everything compile. Now that we're trying to run, the sample code is looking for the assembly and can't find it. You need to deploy it with the application (or in the GAC, but that's for a more advanced lesson).

Please copy netrt.dll from the dotnet\v3\bin directory into the L_01 directory and try again.

C:\juggernet\doc\tutorial\dotnet\v3\L_01>Myapp

Unhandled Exception: System.DllNotFoundException: Unable to load DLL 'xmogrt': The specified module could not be found. 
(Exception from HRESULT: 0x8007007E)
at Codemesh.JuggerNET.NativeInterface.GetJvmLoader(Int32 ctorVersion, String configFile, String vers, String conf, String reserved, Boolean bEnvOverrides, Boolean bDefaultJvm, Int32 traceFacility, Int32 traceLevel, Int32& error)
at Codemesh.JuggerNET.JvmLoader.GetJvmLoader(Boolean bEnvOverrides, Boolean bDefaultJvm, TraceFacility fac, TraceLevel level)
at MyProduct.MyApp.Main(String[] args)

This might be a little more of a surprise. What happened here? The managed runtime library is now available to the executable, but it relies on the unmanaged runtime library and that library is still missing. If you don't understand what we're talking about you should take a look at the runtime architecture. You will also need to deploy an unmanaged runtime library before the application can successfully run.

Where to find the right unmanaged runtime library

Here's where it gets a bit complicated. In the old days of 32-bit Windows, things were very easy: you located a Windows version of xmogrt.dll and your application worked just fine. We actually used to have one folder that contained both netrt.dll and xmogrt.dll and told our users to just add all DLLs in that folder to their application. Now it is more complicated. Windows comes in both 32-bit and 64-bit flavors, and, to make it more complicated, you can run 32-bit applications on 64-bit Windows. Which flavor of the unamanged runtime should you stage: the 32-bit or the 64-bit flavor? You'll have to (generally) pick one.

On a 32-bit Windows system, it's still easy: you have to pick the x86 (32-bit) version because a 32-bit operating system cannot execute 64-bit applications.

On a 64-bit Windows system, the situation is more complex. Let's consider all the factors:

  • does your application include some assemblies that have been built for a particular platform, for example mixed
    mode assemblies that were compiled for 32-bit processors?
  • do you have a 32-bit or a 64-bit JVM installed? Or maybe both? Your JVM and
    the unmanaged runtime library need to be of the same flavor to work together.
  • do you have a platform preference or requirement, possibly because of a license agreement for some third-party libraries?

In general, if you are able to freely choose a flavor, pick 64-bit. Unless explicitly coaxed into running in 32-bit mode, a .NET application will default to 64-bit mode on a 64-bit Windows system, so a 64-bit unmanaged runtime will be the right default choice.

So where do you go from here? Let's assume that you already downloaded the runtime.

Runtime Library Directory structure

The screenshot to the right shows a typical directory hierarchy of runtime library directories.

As you can see, the first level after cpp/v3/lib is an operating system identifier. For JuggerNET, you will typically only download the Windows runtime and we're only interested in the windows branch.

The second level is a processor architecture identifier. The processor architecture is used to identify both the family of processors and the bittedness. 64-bit versions of a processor architecture are represented by their own code. For example, the 32-bit version of Intel X86 compatible processors is represented by the family code x86 whereas the 64-bit version is represented by the family code amd64. We use commonly known identifiers, so you should not have any trouble locating the proper directory.

The third level is a combined compiler type and compiler version identifier. You should generally pick the latest bundled version..

Finally, there are debug and release versions of the runtime library. The fourth level distinguishes between these two flavors. Always pick the release flavor unless you have an excellent reason to try to debug into the unamanged Codemesh runtime library.

While these naming conventions are fairly straightforward, there is a possible source of confusion due to the Microsoft C++ compiler (msvc) version number. We use the compiler version number, whereas most people tend to think of the compiler version as the version of VisualStudio that the compiler shipped with. The table below contains the relationship between compiler version and VisualStudio version.

 

Compiler version vs. VisualStudio version
VisualStudio Version Compiler Version
6 12.00
.NET 13.00
7 (2003) 13.10
8 (2005) 14.00
9 (2008) 15.00
10 (2010) 16.00

So now that you understand the unmanaged runtime folder hierarchy, go and copy a proper xmogrt.dll into the example directory. On 64-bit Windows, you should generally pick cpp\v3\lib\windows\amd64\msvc-16.00\release\xmogrt.dll, on 32-bit Windows cpp\v3\lib\windows\x86\msvc-16.00\release\xmogrt.dll.

Now try to run again. If you picked the right runtime library and JuggerNET could locate a JVM, you will see this:

C:\juggernet\doc\tutorial\dotnet\v3\L_01>Myapp
Success!

C:\juggernet\doc\tutorial\dotnet\v3\L_01>

            

 

Common Runtime Issues You Might Encounter

Attempting to start an executable without xmogrt.dll present will typically cause a message box to pop up. If the Codemesh runtime library cannot be located, the message box might look like this:

error message

You will also get a more detailed error message in your console window:

C:\juggernet\doc\tutorial\dotnet\v3\L_01>Myapp

Unhandled Exception: System.DllNotFoundException: Unable to load DLL 'xmogrt': The specified module could not be found. 
(Exception from HRESULT: 0x8007007E)
at Codemesh.JuggerNET.NativeInterface.GetJvmLoader(Int32 ctorVersion, String configFile, String vers, String conf, String reserved, Boolean bEnvOverrides, Boolean bDefaultJvm, Int32 traceFacility, Int32 traceLevel, Int32& error)
at Codemesh.JuggerNET.JvmLoader.GetJvmLoader(Boolean bEnvOverrides, Boolean bDefaultJvm, TraceFacility fac, TraceLevel level)
at MyProduct.MyApp.Main(String[] args)

 

If you make an incorrect version of the Codemesh runtime library available, for example by deploying an amd64 library version on a 32-bit Windows system, you get the same dialog box, but a different error message:

C:\juggernet\doc\tutorial\dotnet\v3\L_01>Myapp

Unhandled Exception: System.BadImageFormatException: An attempt was made to load a program with an incorrect format. 
   (Exception from HRESULT: 0x8007000B)
at Codemesh.JuggerNET.NativeInterface.GetJvmLoader(Int32 ctorVersion, String configFile, String vers, String conf,
String reserved, Boolean bEnvOverrides, Boolean bDefaultJvm, Int32 traceFacility, Int32 traceLevel, Int32& error)
at Codemesh.JuggerNET.JvmLoader.GetJvmLoader(Boolean bEnvOverrides, Boolean bDefaultJvm, TraceFacility fac, TraceLevel level)
at MyProduct.MyApp.Main(String[] args)

You would get a similar error if the configured or default-selected Java Virtual Machine (JVM) were built for a processor architecture different from your application's processor architecture.

Debugging Runtime Failures

Once you think you have everything configured correctly, there are some tools that can help in debugging the causes.

Work your way down this checklist. Call of us if you reach the end and it's still not working:

  1. Is a netrt.dll deployed with your application?
    If not, copy one from dotnet\v3\bin.
  2. Is an xmogrt.dll deployed with your application?
    If not, copy one from the cpp\v3\lib folder hierarchy. See above for details on how to pick one.
  3. Are you getting a BadImageFormatException (HRESULT: 0x8007000B)?
    If it happened in Codemesh.JuggerNET.NativeInterface.GetJvmLoader(...), it is the wrong xmogrt.dll for your .NET application. If it happens later, The JuggerNET runtime is picking the wrong default JVM and you will need to configure a different jvm.dll (see next lesson).
  4. Try running the application with tracing enabled.
    Do the following:

    1. Before running, set an environment variable that will change the threshold for log messages from the runtime.

      set XMOG_TRACE_LEVEL=TraceInfo
    2. Now run the application.
      You should see some pretty detailed feedback from the runtime. The most important piece of information will be right at the beginning: the configured JVM. You can use this information to check whether the choice makes sense. If not, you will learn how to change to a different JVM in the next lesson.

Copyright 1999-2016 by Codemesh, Inc., ALL RIGHTS RESERVED

:
lesson 2
codemesh.com home gui cli tutorial runtime reference about us contact us download   

Commandline