= Java Support in ZOO Kernel = This is a sample program which dynamicaly loads JVM then load a Class to run one of its static methods : {{{ #!c //sample.c file #include #include int main(int argc, char *argv[], char **envp) { JavaVMOption options[2]; JavaVMInitArgs vm_args; JavaVM *jvm; JNIEnv *env; long result; jmethodID mid; jfieldID fid; jobject jobj; jclass cls; int i, asize; options[0].optionString = "-Djava.class.path=."; options[1].optionString = "-Djava.compiler=NONE"; vm_args.version = JNI_VERSION_1_4; vm_args.options = options; vm_args.nOptions = 2; vm_args.ignoreUnrecognized = JNI_FALSE; result = JNI_CreateJavaVM( &jvm,(void **)&env, &vm_args); if(result == JNI_ERR ) { printf("Error invoking the JVM"); return 1; } else printf("JAVA VM Started\n"); cls = (*env)->FindClass(env,argv[1]); if( cls == NULL ) { printf("can't find class %s\n",argv[1]); return 1; }else{ printf("%s loaded\n",argv[1]); } (*env)->ExceptionClear(env); mid=(*env)->GetStaticMethodID(env,cls, argv[2], "([Ljava/lang/String;)I"); if(mid==0) printf("%s.%s static method not loaded \n", argv[1],argv[2]); else{ printf("%s.%s static method loaded \n",argv[1],argv[2] ); (*env)->CallStaticVoidMethod(env,cls, mid, "MID"); } (*jvm)->DestroyJavaVM(jvm); } }}} The sample program can be compiled this way (we will use {{{$SDK_ROOT}}} for the java sdk installation directory) : {{{ #!sh gcc -I $SDK_ROOT/include/ -I $SDK_ROOT/include/linux/ -o sample sample.c -L $SDK_ROOT/jre/lib/i386/ -ljavaplugin_jni -L $SDK_ROOT/jre/lib/i386/server/ -ljvm -lpthread }}} You need now to use a sample Java Class, you can use the simple code bellow : {{{ #!java // HelloWorld.java file import java.util.*; public class HelloJava { public static int HelloWorldJava(String[] args) { System.out.println("Hello from JAVA WOrld !"); return 3; } } }}} You have now to compile your small java code using javac which should create a {{{HelloWorld.class}}} file in the current directory : {{{ #!sh javac HelloWrold.java }}} To run this sample program you can simply use the following command : {{{ #!sh LD_LIBRARY_PATH=".:$SDK_ROOT/jre/lib/i386/server/:$SDK_ROOT/jre/lib/i386/" ./sample HelloJava HelloWorldJava }}} Which should result in a similar result : {{{ #!sh JAVA VM Started HelloJava loaded HelloJava.HelloWorldJava static method loaded Hello from JAVA WOrld ! }}} This method need to load the jvm for every call. The data structure selected was java.util.HashMap to share data fom/to C to/from JAVA. Sample creation of this data structure in C : {{{ #!c jclass scReplyClass,scInfo_class; jmethodID scInfo_constructor; jobject scObject,scObject1; scReplyClass = (*env)->FindClass(env, "java/util/HashMap"); scInfo_class = (*env)->NewGlobalRef(env, scReplyClass); scInfo_constructor = (*env)->GetMethodID(env, scInfo_class, "", "()V"); // no parameters if(scInfo_constructor==NULL) scInfo_constructor = (*env)->GetMethodID(env, scReplyClass, "", "()V"); // no parameters if(scInfo_constructor!=NULL){ scObject = (*env)->NewObject(env, scInfo_class, scInfo_constructor); scObject1 = (*env)->NewObject(env, scInfo_class, scInfo_constructor); jmethodID put_mid = 0; put_mid = (*env)->GetMethodID(env,scReplyClass, "put", "(Ljava/lang/Object;Ljava/lang/Object;)" "Ljava/lang/Object;"); (*env)->CallObjectMethod(env,scObject1, put_mid, (*env)->NewStringUTF(env,"demoKey"), (*env)->NewStringUTF(env,"demoValue")); (*env)->CallObjectMethod(env,scObject1, put_mid, (*env)->NewStringUTF(env,"demoKey1"), (*env)->NewStringUTF(env,"demoValue1")); (*env)->CallObjectMethod(env,scObject1, put_mid, (*env)->NewStringUTF(env,"demoKey2"), (*env)->NewStringUTF(env,"demoValue2")); (*env)->CallObjectMethod(env,scObject1, put_mid, (*env)->NewStringUTF(env,"demoKey3"), (*env)->NewStringUTF(env,"demoValue3")); (*env)->CallObjectMethod(env,scObject1, put_mid, (*env)->NewStringUTF(env,"demoInput"), scObject1); } else printf("Unable to find java.util.HashMap constructor !\n"); }}}