I am trying to get my feet wet with JNI because I have an application in C that needs to access a single Java library function (no C-equivalent library). I've written a very simple test program to load a Java VM from C and call a static function and get the return value.
Unfortunately, I am unable to get the class to properly load. Although it will probably boil down to it, I think my ClassPath is correct: when I use the java
command with the same ClassPath in the same directory, the class loads and executes perfectly.
Environment:
Ubuntu 8.04 server
Java JRE&SDK 1.6
gcc
My present working directory is always /home/me/project
.
Here is what I get when I run the java
command (java -Djava.class.path=/home/me/project/ -verbose my.ClassABC
):
[Loaded ...] (many loads)
[Loaded my.ClassABC from file:/home/me/project/]
Hello test
[Loaded java.lang.Shutdown from shared objects file]
[Loaded java.lang.Shutdown$Lock from shared objects file]
Here is what I get when I run my C program (./myClassABC
):
[Loaded ...]
[Loaded my.ClassABC from file:/home/me/project/]
Exception in thread "main" java.lang.NoClassDefFoundError: my.ClassABC
Failed to get class
Here is my gcc command line:
gcc -o myClassABC myClassABC.c -I/usr/lib/jvm/java-6-sun-1.6.0.16/include/ -I/usr/lib/jvm/java-6-sun-1.6.0.16/include/linux -L/usr/lib/jvm/java-6-sun-1.6.0.16/jre/lib/i386/server/ -ljvm
My C code (myClassABC.c
):
int main(int argc,char **argv)
{
JNIEnv *env;
JavaVM *jvm;
jint res;
jclass cls;
jmethodID mid;
jstring jstr;
jclass stringClass;
jobjectArray args;
JavaVMInitArgs vm_args;
JavaVMOption options[2];
options[0].optionString =
"-Djava.class.path=."; // or "-Djava.class.path=/home/me/project/";
options[1].optionString =
"-verbose";
vm_args.version = JNI_VERSION_1_6;
vm_args.options = options;
vm_args.nOptions = 2;
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);
}
if ((*env)->ExceptionOccurred(env)) {
(*env)->ExceptionDescribe(env);
}
cls = (*env)->FindClass(env,"my.ClassABC");
if (cls == NULL) {
if ((*env)->ExceptionOccurred(env)) {
(*env)->ExceptionDescribe(env);
}
printf("Failed to get class\n");
exit(1);
}
[call methods, etc.]
}
And my java code, just for #$%@s and giggles (gets compiled to /home/me/project/my/ClassABC.class
):
package my;
class ClassABC {
public static void main(String[] args) {
System.out.println(ClassABC.getPassword("test"));
return;
}
static String getPassword(String filename)
{
return "Hello "+filename;
}
}
Thanks,
Brian
You can fix NoClassDefFoundError error by checking following: Check the exception stack trace to know exactly which class throw the error and which is the class not found by java.
NoClassDefFoundError, which means the Class Loader file responsible for dynamically loading classes can not find the . class file. So to remove this error, you should set your classpath to the location where your Class Loader is present. Hope it helps!!
NoClassDefFoundError is a common error in Java that occurs if a ClassLoader cannot find a particular class in the classpath while trying to load it. The Exception in thread "main" suggests that this error has occurred in the main thread, the thread which is responsible for running the Java application.
Just replace this
cls = (*env)->FindClass(env,"my.ClassABC");
with
cls = (*env)->FindClass(env,"my/ClassABC");
and you should be fine.
Else try adding
...
JavaVMOption options[3];
...
options[2].optionString = "-verbose:jni";
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With