简体   繁体   中英

java.lang.NoClassDefFoundError:

Hello i'm writing a c++ code to call java functions from .jar class.

Here it is :

#include <jni.h>
int main()
{
JavaVMOption options[1];
JNIEnv *env;
JavaVM *jvm;
JavaVMInitArgs vm_args;
long status;
jclass JCTerminalClass;
jmethodID mid;
jobject obj;
char op0[] = "-Djava.class.path=C:\\Users\\DMNX1594\\Downloads\\jcop\\jcop/offcard.jar";
options[0].optionString =op0; 
vm_args.version = JNI_VERSION_1_6;
vm_args.nOptions = 1;
vm_args.options = options;

status = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);

if (status != JNI_ERR)
{
JCTerminalClass = env->FindClass("JCTerminal");
jthrowable exc;
exc = env->ExceptionOccurred();
if (exc) 
{
jclass newExcCls;
env->ExceptionDescribe();
env->ExceptionClear();
}

if(JCTerminalClass !=0)
{
mid = env->GetMethodID(JCTerminalClass, "com.ibm.jc.JCTerminal()", "()V");
      // Call here instance function later ...
} 
.
.
.
jvm->DestroyJavaVM();
return 0;
} else
return -1;
}

Compilation goes well, but during execution, i get the following :

java.lang.NoClassDefFoundError: JCTerminal Caused by: java.lang.ClassNotFoundException: JCTerminal at java.net.URLClassLoader$1.run(URLClassLoader.java:372) at java.net.URLClassLoader$1.run(URLClassLoader.java:361) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:360) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) at java.lang.ClassLoader.loadClass(ClassLoader.java:357)

I already tried calling simple static java functions from a .jar that I created and it worked ! The code resembles a lot this one.

I tried setting the CLASSPATH environment variable to C:\\path\\to\\jarFile\\offcard.jar because i read that NoClassDefFoundError happens when the class is found during compiling but not during execution ...

Might it be a thread problem ?

Oh, and here's my compilation command : g++ -D __int64="long long" -I"C:\\Program Files\\Java\\jdk1.8.0_05\\include" -I"C:\\Program Files\\Java\\jdk1.8.0_05\\include\\win32" -L"C:\\Program Files\\Java\\jdk1.8.0_05\\jre\\bin\\server" -L"C:\\Program Files\\Java\\jdk1.8.0_05\\lib" -o jni jni.cpp -ljvm

Thank you stackoverflowers :)

It seems that your code fails on JCTerminalClass = env->FindClass("JCTerminal");

The documentation for JNIEnv->FindClass says this:

jclass FindClass(JNIEnv *env, const char *name);

[...]

The name argument is a fully-qualified class name or an array type signature . For example, the fully-qualified class name for the java.lang.String class is: "java/lang/String"

However you are just passing the string "JCTerminal" without any package name. Later in your example you show the package name before the class name: "com.ibm.jc.JCTerminal()" However in JNI code, the package name separator is not the dot (.) but the slash (/), as shown in the documentation above. So what you need to pass to the FindClass method is "com/ibm/jc/JCTerminal" :

JCTerminalClass = env->FindClass("com/ibm/jc/JCTerminal");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM