HOWTO: Create a standalone Java DLL and invoke it from C
Notice Information in this article applies to Excelsior JET version 3.7 and below.
This article applies to Excelsior JET versions 3.7 and earlier only. Since version 4.0, our product does not incorporate the JetPerfect feature and so it does not support creation of stand-alone DLLs.
The document contains step-by-step instructions on the use of Excelsior JET v3.7 for the creation of a standalone Java DLL and on calling that DLL from a C program. On the first few steps, a DLL dynamically linked with the JET runtime is created. The remaining steps show how to convert it to a standalone DLL.
Source files and build/run scripts for this article may be found in the Supplemental Downloads section.
By default, JET links application code with the runtime dynamically, i.e. your classes are compiled and put into an executable (EXE or DLL) that requires one or more JET runtime DLLs containing precompiled Java 2 platform classes.
A standalone executable may be created with the help of Excelsior JET, Professional Edition feature — JetPerfect Global Optimizer. With JetPerfect, both application classes and required platform classes are compiled in one session. They are globally optimized and statically linked into a single executable (EXE or DLL) that does not need JET runtime DLLs and does not contain redundant code and data.
The use of JetPerfect gives you several important advantages:
- global optimizations improve code performance
- smart linking reduces executable size and memory requirements
- single component linking makes your DLL require no JET runtime DLLs
Let’s consider the sample accompanying this article. First, you have to build a DLL in the default mode.
dllClass.javawith javac to produce
Build the DLL project in the default mode:
jc =p =a dllClass.prj
dllClass.prjin the JET Control Panel and build it.
Compile the C test that accesses the DLL.
The source file
main.ccontains code that invokes
dllClassmethods using the standard Java Native Interface and Invocation API (http://java.sun.com/docs/books/jni/html/invoke.html).
Compile and link
xjvm.liblibrary that is part of your Excelsior JET installation:
cl -I%JDKDIR%\include\ -I%JDKDIR%\include\win32\ main.c %JETDIR%\lib\x86\xjvm.lib
(it is assumed that environment variables JDKDIR and JETDIR contain full paths to JDK and JET directories respectively.)
You can run the test executable:
- In order to continue, you need to download and install the JetPerfect add-on, which is available at https://www.excelsior-usa.com/jetdlperfect.html
Now, to enable global optimizations, a usage list for the DLL must be collected, which includes methods that are called and fields that are accessed at run time via the Reflection API. This cannot be done by analysing your program statically, but the JET runtime can help you build the usage list if you run your application as follows:
jet.default.classloaderproperties using the
JETVMPROPenvironment variable and run the test application again to create the usage list:
SET JETVMPROP=-Djet.usage.list -Djet.default.classloader:application main.exe
As a result, the usage list will be automatically collected during execution and will be saved in a file with the application name and “
.usg” extension. This example is very simple, but in complicated cases you may re-run your application as many times as you wish, supplying, for instance, different input data. The previously created
.usgfile will not be overwritten, but newly detected classes, methods and fields accessed via reflection will be added to it.
Re-build the DLL with the option PERFECT enabled:
jc =p =a dllClass.prj -perfect+
It will take several minutes, because the required Java 2 platform classes will be compiled together with DLL classes.
dllClass.dllcontains all the code required for
dllClassmethods to work, including the Invocation API. So you should change the C program to retrieve the Invocation API routines from that DLL using the
GetProcAdr()Windows API call. In the sample program, the change is accomplished through conditional compilation in
main.csource: defining ’DynamicUseDLL’ causes loading of Invocation API routines from
cl -I%jdkdir%\include\ -I%jdkdir%\include\win32\ -DDynamicUseDLL main.c
You can now run
- JetPerfect Global Optimizer: https://www.excelsior-usa.com/jetdlperfect.html
- Excelsior JET 3.7 User’s Guide, Chapter “JetPerfect Global Optimizer”
Article ID: 1
Last Revised On: 15-Sep-2005