Need help on calling java from C using JNI

M

Maki

Could you help me on this...
Why is the following two calls returning "NULL" when called from JNI.I
tried lot of ways but failed to reslove the issue.
Thread.currentThread().getContextClassLoader(),
getClass().getClassLoader().
/>./a.out
Main-Class:class Test
Thread:Thread[main,5,main]
Thread-current-Thread:null
Main-ClassLoader:null

But,when I call Test.class file from java("java Test") its working
fine...!!!!
Main-Class:class Test
Thread:Thread[main,5,main]
Thread-current-Thread:sun.misc.Launcher$AppClassLoader@1d10ed
Main-ClassLoader:sun.misc.Launcher$AppClassLoader@1d10ed



Please find here the programs
*****************How to compile******************
#javac Test.java
#/usr/local/bin/gcc -I /usr/java1.2/include -I
/usr/java1.2/include/solaris -L/usr/java1.2/jre/lib/sparc -ljava
-ljvm invoke.c
#export LD_LIBRARY_PATH=/usr/java1.2/jre/lib/sparc
************************End of Compile******************

My java Programe is
***************************Test.java***************************

import java.io.InputStream;
import java.net.URL;

public class Test{

public static void main(String[ ] args){
try{

Test c = new Test();

System.out.println("Main-Class:"+c.getClass());

System.out.println("Thread:"+Thread.currentThread());

System.out.println("Thread-current-Thread:"+Thread.currentThread().getContextClassLoader());

System.out.println("Main-ClassLoader:"+c.getClass().getClassLoader());

}
catch(Exception e)
{
System.out.println("Error\n"+e);
e.printStackTrace();
}
}
}
******************************************End of
Test.java*********************

******************************************invoke.c****************************
#include <jni.h>

#ifdef _WIN32
#define PATH_SEPARATOR ';'
#else /* UNIX */
#define PATH_SEPARATOR ':'
#endif

#define USER_CLASSPATH "." /* where Prog.class is */

main() {
JNIEnv *env;
JavaVM *jvm;
JDK1_1InitArgs vm_args;
jint res;
jclass cls;
jmethodID mid;
jstring jstr;
jobjectArray args;
char classpath[1024];
jthrowable exc;


/* IMPORTANT: specify vm_args version # if you use JDK1.1.2 and
beyond */
vm_args.version = 0x00010001;

JNI_GetDefaultJavaVMInitArgs(&vm_args);

/* Append USER_CLASSPATH to the end of default system class path
*/
sprintf(classpath, "%s%c%s",
vm_args.classpath, PATH_SEPARATOR, USER_CLASSPATH);
vm_args.classpath = classpath;

//JNI_CreateJavaVM(JavaVM **pvm, void **penv, void *args);
/* Create the Java VM */
res = JNI_CreateJavaVM(&jvm,&env,&vm_args);
if (res < 0) {
fprintf(stderr, "Can't create Java VM\n");
exit(1);
}

cls = (*env)->FindClass(env, "Test");
if (cls == 0) {
fprintf(stderr, "Can't find Prog class\n");
exit(1);
}

mid = (*env)->GetStaticMethodID(env, cls, "main",
"([Ljava/lang/String;)V");
if (mid == 0) {
fprintf(stderr, "Can't find Prog.main\n");
exit(1);
}

jstr = (*env)->NewStringUTF(env, " from C!");
if (jstr == 0) {
fprintf(stderr, "Out of memory\n");
exit(1);
}

args = (*env)->NewObjectArray(env, 1,
(*env)->FindClass(env,
"java/lang/String"), jstr);
if (args == 0) {
fprintf(stderr, "Out of memory\n");
exit(1);
}

(*env)->CallStaticVoidMethod(env, cls, mid, args);
exc = (*env)->ExceptionOccurred(env);
if(exc)
{
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
printf("Sorry Failed in adding user\n");
}
(*jvm)->DestroyJavaVM(jvm);
}
***************************************End of
invoke.c************************************

Thanks,
Ranga
 
G

Gordon Beaton

[ comp.lang.java.developer does not exist ]

Why is the following two calls returning "NULL" when called from
JNI.I tried lot of ways but failed to reslove the issue.

You might check that vm_args.classpath contains something valid before
you attempt to use the value, here:
sprintf(classpath, "%s%c%s",
vm_args.classpath, PATH_SEPARATOR, USER_CLASSPATH);

When I tried this using your code, vm_args.classpath contained
garbage.

Using the Blackdown 1.4.1 JVM on UltraSparc Linux, I get identical
results (no NULL) with your code and the regular java launcher.

I made the following changes however:

- define _REENTRANT when compiling the launcher
- change to JNI_VERSION_1_2
- use JavaVMInitArgs instead of JDK1_1InitArgs

You should condider using (*env)->ExceptionDescribe() when your JNI
calls fail, instead of just reporting "Out of memory" or "Can't find
prog".

I'd also suggest you turn on compiler warnings (-Wall), since there
are several. For example main() must return an int, and you should
include <stdio.h> as well as <stdlib.h>.

/gordon
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top