JNI-C++;为什么我还需要.class和.jar? 我有一个非常简单的代码,通过C++从JNI调用java函数,但是只有在我提供了编译的.class文件和捆绑的.jar文件时,它才能工作。如果我删除其中任何一个,我的应用程序将停止工作。示例代码: void JniProvider::CreateVM(const QString compiledSource, const QString jar) throw(std::runtime_error) { QString classpath = QString("-Djava.class.path=%1;%2").arg(compiledSource).arg(jar); QByteArray cpbytes = classpath.toLocal8Bit(); char* chrpath = cpbytes.data(); // VM Arguments size: const int optionsSize = 2; // jvm options: JavaVMOption options[optionsSize]; options[0].optionString = "-Djava.compiler=NONE"; options[1].optionString = chrpath; // jvm args JavaVMInitArgs vm_args; vm_args.version = JNI_VERSION_1_6; vm_args.nOptions = optionsSize; vm_args.options = options; vm_args.ignoreUnrecognized = JNI_TRUE; // startup jvm jint responseCode = JNI_CreateJavaVM(&virtualMachine, reinterpret_cast<void**>(&environment), &vm_args); if (responseCode < 0) { virtualMachine->DestroyJavaVM(); throw std::runtime_error("Failed to create Java virtual machine."); } }

JNI-C++;为什么我还需要.class和.jar? 我有一个非常简单的代码,通过C++从JNI调用java函数,但是只有在我提供了编译的.class文件和捆绑的.jar文件时,它才能工作。如果我删除其中任何一个,我的应用程序将停止工作。示例代码: void JniProvider::CreateVM(const QString compiledSource, const QString jar) throw(std::runtime_error) { QString classpath = QString("-Djava.class.path=%1;%2").arg(compiledSource).arg(jar); QByteArray cpbytes = classpath.toLocal8Bit(); char* chrpath = cpbytes.data(); // VM Arguments size: const int optionsSize = 2; // jvm options: JavaVMOption options[optionsSize]; options[0].optionString = "-Djava.compiler=NONE"; options[1].optionString = chrpath; // jvm args JavaVMInitArgs vm_args; vm_args.version = JNI_VERSION_1_6; vm_args.nOptions = optionsSize; vm_args.options = options; vm_args.ignoreUnrecognized = JNI_TRUE; // startup jvm jint responseCode = JNI_CreateJavaVM(&virtualMachine, reinterpret_cast<void**>(&environment), &vm_args); if (responseCode < 0) { virtualMachine->DestroyJavaVM(); throw std::runtime_error("Failed to create Java virtual machine."); } },java,c++,java-native-interface,Java,C++,Java Native Interface,如您所见,我有三个依赖项作为外部jar文件。不管我喜不喜欢,java应用程序都使用了这些。编译后,以下结构将显示在项目的dist文件夹中: lib enttoolkit.jar mail.jar wm-isclient.jar Core.jar core core.class META-INF MANIFEST.MF model model.class 我有一个Core.jar,里面有编译过的类,还有一个lib文件夹,里面有外部jar文件 现在来谈谈实际的问题部分。如果

如您所见,我有三个依赖项作为外部jar文件。不管我喜不喜欢,java应用程序都使用了这些。编译后,以下结构将显示在项目的dist文件夹中:

lib
 enttoolkit.jar
 mail.jar
 wm-isclient.jar
Core.jar
 core
  core.class
 META-INF
  MANIFEST.MF
 model
  model.class
我有一个Core.jar,里面有编译过的类,还有一个lib文件夹,里面有外部jar文件

现在来谈谈实际的问题部分。如果稍后在env->Findclass上从CreateVM函数的类路径中删除.class或.jar文件,则会失败。它只是找不到任何类,如果我同时提供类文件和jar文件,它就会成功,并且我可以从类中调用任何方法,不管是静态的还是非静态的

MANIFEST.MF内容:

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.9.1
Created-By: 1.7.0_25-b17 (Oracle Corporation)
Class-Path: lib/enttoolkit.jar lib/mail.jar lib/wm-isclient.jar
X-COMMENT: Main-Class will be added automatically by build
Main-Class: core.Core
@编辑(10:30): 错误为NoClassDefFoundError。compiledSource的值是.class文件的路径,包括类文件本身,而jar与jar文件相同。例如:

"-Djava.class.path=C:/Users/johorvat/AppData/Local/Temp/resource.class" <- The upper NoClassDefFoundError
"-Djava.class.path=C:/Users/johorvat/AppData/Local/Temp/resource.class;C:/Users/johorvat/AppData/Local/Temp/resource.jar" <- Works flawlessly without any errors and produces Java method return values on C++ side.

“-Djava.class.path=C:/Users/johorvat/AppData/Local/Temp/resource.class”否。您只需提供正确构造的JAR文件或.class文件的层次结构。我建议您的jar文件中缺少某些内容,或者出现在错误的名称或目录下


请注意,NoClassDefError与ClassNotFoundException不同。这意味着找到了该文件,但它不包含所需的类,例如错误的大小写或错误的包。

定义“无法调用”和“停止工作”。Core.jar的清单是否有命名其他jar文件的类路径条目?是的,它有。我还添加了清单的内容。FindClass()失败时会出现什么错误?“compiledSource”和“jar”的值是什么?为Findclass添加了一个问题。对不起,我必须更新这个问题,因为如果我把它写在评论中,它将无法阅读。
"-Djava.class.path=C:/Users/johorvat/AppData/Local/Temp/resource.class" <- The upper NoClassDefFoundError
"-Djava.class.path=C:/Users/johorvat/AppData/Local/Temp/resource.class;C:/Users/johorvat/AppData/Local/Temp/resource.jar" <- Works flawlessly without any errors and produces Java method return values on C++ side.