JNI-FindClass function returns null

I have a simple java class ("MainX") that I compile using a shell script and eclipse. When I call the function env-> FindClass ("MainX"), the MainX.class file generated from the script returns null, while the MainX.class file generated from eclipse returns the class and then executes the runMainX function.

The generated MainX.class file is located in the same folder with the C ++ JNI executable.

MainX.java

public class MainX { public static void main(String[] args) { // TODO Auto-generated method stub System.out.println(new MainX().runMainX()); } public String runMainX(){ return ("0.789"); } } 

JNIBinding.cpp

 #define USER_CLASSPATH "." .... .... JNIEnv* createVM (JavaVM **jvm) { JNIEnv *env; /* pointer to native method interface */ JavaVMInitArgs vm_args; /* JDK/JRE 6 VM initialization arguments */ JavaVMOption* options = new JavaVMOption[1]; //holds various JVM optional settings options[0].optionString = const_cast<char*>("-Djava.class.path="USER_CLASSPATH); vm_args.version = JNI_VERSION_1_6; //version of Java platform vm_args.nOptions = 1; vm_args.options = options; vm_args.ignoreUnrecognized = false; /* load and initialize a Java VM, return a JNI interface * pointer in env */ long status = JNI_CreateJavaVM(jvm, (void**)&env, &vm_args); if (status == JNI_ERR){ cout << "Fail: Unable to load JVM \t Exit" << endl; } else if (status == JNI_OK){ cout << "CreateVM:\t\tJVM loaded successfully!" << endl ; } delete options; return env; } .... .... float invokeMainX(JavaVM **jvm, JNIEnv *env){ jclass mainClass ; //Returns a class object from a fully-qualified name, or NULL if the class cannot be found. jmethodID classConstructor; //Returns the method ID for an instance (nonstatic) method of a class jobject classObject; //Constructs a new java object jmethodID methodid; float outcome = 0; mainClass = env->FindClass("MainX"); //Returns a class object from a fully-qualified name, or NULL if the class cannot be found. if (mainClass==0) return 0; classConstructor = env->GetMethodID(mainClass, "<init>", "()V"); //Returns the method ID for an instance (nonstatic) method of a class if (classConstructor==0) return -1; classObject = env->NewObject(mainClass, classConstructor); //Constructs a new java object if (classObject==0) return -2; methodid = env->GetMethodID(mainClass, "runMainX", "()Ljava/lang/String;"); if (methodid==0) return -3; jstring result = (jstring)env->CallObjectMethod(classObject, methodid); //returns the result of the calling method, an object .... .... } 

Can someone explain to me why this is happening?

I appreciate any help.

Any idea ??? thanks in advance

+7
java c ++ jvm jni
source share
3 answers

From the JNI Documentation for FindClass :

  name: a fully-qualified class name (that is, a package name, delimited by "/", 
       followed by the class name).

Thus, assuming the class is in the package your.package.name , I think you will have to replace

 mainClass = env->FindClass("MainX"); 

from

 mainClass = env->FindClass("your/package/name/MainX"); 

Hope this helps!

+15
source share

I am not sure about this problem on your platform, but I had a similar problem on the Android platform.

The FindClass method should only be called from a Java thread. The FindClass implementation searches for ClassLoader by moving the current call stack. Since you are trying to call FindClass from your own thread, ClassLoader is not looking. Take a look at JNI Questions :

If the class name looks correct, you can run the class loader problem. FindClass wants to start looking for a class in the loader class associated with your code. It checks the call stack, which will look something like this:

 Foo.myfunc(Native Method) Foo.main(Foo.java:10) dalvik.system.NativeStart.main(Native Method) 

The topmost method is Foo.myfunc. FindClass finds the ClassLoader object associated with the Foo class and uses it.

+13
source share

I have CentOS 6 x86_64 and it did not work until I changed the following lines:

 vm_args.version = JNI_VERSION_1_4; ... options[0].optionString = (char *)"-Djava.class.path=/home/oscar/Projects/Java-C++"; 

Also I need to export LD_LIBRARY_PATH:

 javac HelloWorldApp.java Bicycle.java g++ Prueba2.cpp -o Prueba2 -L/usr/lib64/gcj-4.4.4 -ljvm export LD_LIBRARY_PATH=/usr/lib64/gcj-4.4.4/ 

Hope this helps!

0
source share

All Articles