java.lang.NoClassDefFoundError:

时间:2014-07-08 13:38:18

标签: java java-native-interface

您好我正在编写一个c ++代码来从.jar类调用java函数。

这是:

#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;
}

编译顺利,但在执行期间,我得到以下内容:

  

java.lang.NoClassDefFoundError:JCTerminal   引起:java.lang.ClassNotFoundException:java.net.URLClassLoader $ 1.run(URLClassLoader.java:372)中的JCTerminal,java.net.URLClassLoader $ 1.run(URLClassLoader.java:361),java.security.AccessController.doPrivileged (原生方法)           在java.net.URLClassLoader.findClass(URLClassLoader.java:360)           at java.lang.ClassLoader.loadClass(ClassLoader.java:424)           at sun.misc.Launcher $ AppClassLoader.loadClass(Launcher.java:308)           在java.lang.ClassLoader.loadClass(ClassLoader.java:357)

我已经尝试从我创建的.jar中调用简单的静态java函数并且它有效! 代码类似于这个代码。

我尝试将CLASSPATH环境变量设置为C:\ path \ to \ jarFile \ offcard.jar,因为我读到在编译期间找到类但在执行期间找不到类时会发生NoClassDefFoundError ...

可能是线程问题?

哦,这是我的编译命令: 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

谢谢stackoverflowers:)

1 个答案:

答案 0 :(得分:1)

您的代码似乎在JCTerminalClass = env->FindClass("JCTerminal");

上失败了

JNIEnv-&gt; FindClass的文档说明了这一点:

  

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

     

[...]

     

name参数是完全限定的类名或数组类型   签名。例如,完全限定的类名   java.lang.String类是:"java/lang/String"

但是,您只是传递字符串"JCTerminal"而没有任何包名称。稍后在您的示例中,您将在类名称前显示包名称:"com.ibm.jc.JCTerminal()" 但是在JNI代码中,包名称分隔符不是点(。)而是斜杠(/),如上面的文档中所示。所以你需要传递给FindClass方法的是"com/ibm/jc/JCTerminal"

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