Your Browser is not longer supported

Please use Google Chrome, Mozilla Firefox or Microsoft Edge to view the page correctly
Loading...

{{viewport.spaceProperty.prod}}

Use of Java from a C application

The next example illustrates the use of the Java invocation API (part of the JNI) for calling Java programs from C. The example we have chosen is consciously kept simple.

A Java echo program will output all its arguments to standard output. This Java program will then be called from a C program.

Implementation of the Java code

In the file Echo.java we define the following class:

class Echo {
  public static void main(String[] args) 
  {
    for (int i = 0; i < args.length; i++)
    {
      if (i > 0)
        System.out.print(" ");
      System.out.print(args[i]); 
    } 
    System.out.println(""); 
  } 
} 

Compiling the Java code

The above defined Java class can now be simply compiled using the command

javac Echo.java

By calling

java Echo This is a test

you can prove to yourself that the program is working.

Implementation of the C code

In our example, the following C program will call the above Java program and at the same time transfer its call arguments to it. Once again you should note that all strings transferred to JNI functions must be coded in ASCII. This example will therefore be implemented and produced completely in ASCII mode.

The file Echo.c is implemented as follows:

#include <jni.h>
int
main(int argc, char *argv[])
{
   JavaVMInitArgs vm_args;
   JavaVMOption options[1];
   JavaVM *jvm;
   JNIEnv *env;
   jint res;
   jclass cls;
   jmethodID mid;
   jobjectArray args;
   int i;
   /*
   ** Prepare VM Options
   */
   options[0].optionString = "-Djava.class.path=.";
   /*
   ** Prepare VM configuration
   */
   vm_args.version = JNI_VERSION_1_4;
   vm_args.nOptions = 1;
   vm_args.options = options;
   vm_args.ignoreUnrecognized = JNI_FALSE;
   /*
   ** Create the Java VM
   */
   res = JNI_CreateJavaVM(&jvm,(void **)&env,&vm_args);
   if (res < 0)
   {
     fprintf(stderr,"Can't create Java VM\n");
     exit(1);
   }
   /*
   ** Get class Echo
   */
   cls = (*env)->FindClass(env,"Echo");
   if (cls == NULL)
   {
     fprintf(stderr,"Can't find Echo class\n");
     exit(1);
   }
   /*
   ** Get main method

   */
   mid = (*env)->GetStaticMethodID(env,cls,"main",
               "([Ljava/lang/String;)V");
   if (mid == 0)
   {
     fprintf(stderr,"Can't find main in Echo\n");
     exit(1);
   }
   /*
   ** Allocate argument array
   */
   args = (*env)->NewObjectArray(env,argc-1,
             (*env)->FindClass(env,"java/lang/String"),NULL);
   if (args == 0)
   {
     fprintf(stderr,"Out of memory\n");
     exit(1);
   }
   /*
   ** Prepare arguments
   */
   for (i=1; i<argc; i++)
   {
     jstring jstr;
     jstr = (*env)->NewStringUTF(env,argv[i]);
     if (jstr == NULL)
   {
      fprintf(stderr,"Out of memory\n");
      exit(1);
   }
     (*env)->SetObjectArrayElement(env,args,i-1,jstr);
   }
   /*
   ** Call Java method
   */
   (*env)->CallStaticVoidMethod(env,cls,mid,args);
   /*
   ** Destroy Java VM
   */
   (*jvm)->DestroyJavaVM(jvm);
   return 0;
}

The program functions in this form only with a standard JENV installation. If you want to run the program with a private installation, you must set the JAVA_HOME environment variable accordingly (see chapter "Environment variables").

Compilation of the C source code

The C source code implemented in the section above must now be compiled using the correct compiler options. For Echo.c , in addition to the standard options which have been described in detail above, the ASCII mode must also be considered:

cc -c -I/opt/java/include \
      -Kllm_keep,llm_case_lower \ 
      -Kworkspace_stack,c_names_unlimited \ 
      -Kliteral_encoding_ascii
      -Kno_integer_overflow Echo.c

This results in an object file being made available.

Linking and executing the application

When linking the application, it must be remembered that the Java runtime adapter is linked and not the “normal“ runtime systems.

The application can be statically linked with the following commands:

export BLSLIB00='$.SYSLNK.JENV.090.GREEN-JAVA' 
cc -Kno_link_stdlibs -B llm4 -o Echo \
      Echo.o -l BLSLIB

The program can be called like any other POSIX program. However, for JENV to execute, it must be installed under the default installation path. To use a JENV installed elsewhere, you must set the JAVA_HOME environment variable accordingly (see chapter "Environment variables").

The call using

Echo This is a Java echo

produces the expected output:

This is a Java echo

The program is run using the default VM described in section "Options for selecting the HotSpot™ VM type" in section "java". By selecting the environment variable JENV_VMTYPE beforehand you can determine the VM type explicitly. For example:

export JENV_VMTYPE=client

This results in the HotSpot™ client VM being used.