Using the Invocation API in Java

Up to now, we have considered programs in the Java programming language that made a few C calls, presumably because C was faster or allowed access to functionality inaccessible from the Java platform. Suppose you are in the opposite situation. You have a C or C++ program and would like to make calls to Java code. The invocation API enables you to embed the Java virtual machine into a C or C++ program. Here is the minimal code that you need to initialize a virtual machine:

JavaVMOption options[1];

JavaVMInitArgs vm_args;

JavaVM *jvm;

JNIEnv *env;

options[0].optionString = “-Djava.class.path=.”;

memset(&vm_args, 0, sizeof(vm_args));

vm_args.version = JNI_VERSION_1_2;

vm_args.nOptions = 1;

vm_args.options = options;

JNI_CreateJavaVM(&jvm, (void**) &env, &vm_args);

The call to JNI_CreateJavaVM creates the virtual machine and fills in a pointer jvm to the virtual machine and a pointer env to the execution environment.

You can supply any number of options to the virtual machine. Simply increase the size of the options array and the value of vm_args.nOptions. For example,

options[i].optionString = “-Djava.compiler=NONE”;

deactivates the just-in-time compiler.

Once you have set up the virtual machine, you can call Java methods as de­scribed in the preceding sections. Simply use the env pointer in the usual way.

You’ll need the jvm pointer only to call other functions in the invocation API. Currently, there are only four such functions. The most important one is the function to terminate the virtual machine:

(*jvm)->DestroyJavaVM(jvm);

Unfortunately, under Windows, it has become difficult to dynamically link to the JNI_CreateJavaVM function in the jre/bin/dient/jvm.dtt library, due to the changed linking rules in Vista and Oracle’s reliance on an older C runtime library. Our sample program overcomes this problem by loading the library manually. This is the same approach used by the java program—see the file launcher/javajnd.c in the src.jar file that is a part of the JDK.

The C program in Listing 12.20 sets up a virtual machine and calls the main method of the Welcome class, which was discussed in Volume I, Chapter 2. (Make sure to compile the Welcome.java file before starting the invocation test program.)

To compile this program under Linux, use

gcc -I jdk/include -I jdk/include/linux -o InvocationTest \

-L jdk/jre/lib/i386/client -ljvm InvocationTest.c

When compiling in Windows with the Microsoft compiler, use the command line

cl -D_WINDOWS -I jdk\indude -I Jdk\indude\win32 InvocationTest.c \

jdk\lib\jvm.lib advapi32.lib

You will need to make sure that the INCLUDE and LIB environment variables include the paths to the Windows API header and library files.

Using Cygwin, compile with

gcc -D_WINDOWS -mno-cygwin -I jdk\indude -I Jdk\indude\win32 -D  int64=”long tong” \

-I c:\cygwin\usr\include\w32api -o InvocationTest

Before you run the program under Linux/UNIX, make sure that the LD_LIBRARY_PATH contains the directories for the shared libraries. For example, if you use the bash shell on Linux, issue the following command:

export LD_LIBRARY_PATH=jdk/jre/lib/i386/client:$LD_LIBRARY_PATH

Source: Horstmann Cay S. (2019), Core Java. Volume II – Advanced Features, Pearson; 11th edition.

Leave a Reply

Your email address will not be published. Required fields are marked *