我有一个非常直接的代码,可以通过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.");
}
}
注意类路径行。如果我删除了jar,我就无法通过jni调用任何函数。当我再次设置它一切正常。我是否需要编译源和bunbled jar(s - with dependency jars)的功能呢?
@Edit: 谢谢你的回复。请允许我在一个地方澄清一些突发问题。因此,Java项目在Netbeans 7.4中具有以下结构:
Core
Source Packages
core
Core.java
model
model.java
Test Packages
Libraries
enttoolkit.jar
mail.jar
wm-isclient.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和包含外部jar文件的lib文件夹。
现在到实际有问题的部分。如果我稍后在env-> gt; Createclass中从类路径中删除.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
@Edit(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.
如果我省略类文件并使用唯一的jar,也会发生同样的情况。只有当我同时拥有它们或获取NoClassDefFoundError时它才有效。对我来说有点奇怪......
答案 0 :(得分:0)
没有。您只需提供正确构造的JAR文件或 .class文件的层次结构。我建议您的jar文件中缺少某些内容,或者出现在错误的名称或目录下。
请注意,NoClassDefError与ClassNotFoundException不同。这意味着找到 文件,但它不包含预期的类,例如错误的情况或错误的包裹。