简体   繁体   English

JNI C ++为什么也需要.class和.jar?

[英]JNI C++ Why do I need .class and .jar also?

I have a very straight-forward code to call JAVA Functions through JNI from C++, however it only works if I provide the compiled .class files and the bundled .jar file(s) also. 我有一个非常简单的代码,可以通过C ++通过JNI调用JAVA函数,但是,只有在我提供编译后的.class文件和捆绑的.jar文件的情况下,它才有效。 If I remove either of them my application stops working. 如果删除其中任何一个,我的应用程序将停止工作。 Example code: 示例代码:

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.");
    }
}

Notice the classpath line. 注意类路径行。 If I remove the jar I can't call any functions at all through jni. 如果删除jar,则无法通过jni调用任何函数。 When I set it again it all works fine. 当我再次设置它时,一切正常。 Is it intended functionality that I need the compiled sources and the bunbled jar(s - with dependency jars) too? 我是否还需要编译后的源代码和混乱的jar(带有依赖项jars)的预期功能?

@Edit: Thank you for your responses. @Edit:谢谢您的答复。 Allow me to clarify some of the popped up questions in one place. 请允许我在一处阐明一些弹出的问题。 So, the Java Project has the following structure within Netbeans 7.4: 因此,Java项目在Netbeans 7.4中具有以下结构:

Core
 Source Packages
  core
   Core.java
  model
   model.java
 Test Packages
 Libraries
  enttoolkit.jar
  mail.jar
  wm-isclient.jar

As you can see I have three dependencies as external jar files. 如您所见,我有三个依赖项作为外部jar文件。 Whether I like it or not sadly, the java app uses these. 不管我喜不喜欢,Java应用程序都使用这些。 After compilation the following structure appears in the dist folder of the project: 编译后,以下结构将出现在项目的dist文件夹中:

lib
 enttoolkit.jar
 mail.jar
 wm-isclient.jar
Core.jar
 core
  core.class
 META-INF
  MANIFEST.MF
 model
  model.class

I have the Core.jar with the compiled classes inside and a lib folder with the external jar files in it. 我有Core.jar,里面有已编译的类,还有一个带有外部jar文件的lib文件夹。

Now to the actual problematic part. 现在到实际有问题的部分。 If I remove either the .class or .jar file from the classpath in CreateVM function later on env->Findclass fails. 如果稍后在env-> Findclass上从CreateVM函数的类路径中删除.class或.jar文件,则会失败。 It just won't find the any classes, where if I provide both the class files and the jar files it succeeds and I can call any method from the class, static or not. 它只是找不到任何类,如果我同时提供了类文件和jar文件,那么它将成功,并且我可以从类中调用任何方法,无论是否为静态。

MANIFEST.MF contents: 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): The error is NoClassDefFoundError. @Edit(10:30):错误为NoClassDefFoundError。 The value of compiledSource is the path to the .class file including the class file itself while the jar is the same with the jar file. 编译源的值是.class文件(包括类文件本身)的路径,而jar与jar文件相同。 for example: 例如:

"-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.

The same happens if I leave out the class file and use the only the jar. 如果我忽略了类文件并仅使用jar,则会发生相同的情况。 It only works if I have both of them, or get the NoClassDefFoundError. 仅当我同时拥有它们或获取NoClassDefFoundError时,它才有效。 Kind of strange for me... 对我来说有点奇怪

No. You only have to provide a correctly constructed JAR file or a hierarchy of .class files. 不需要。您只需要提供正确构建的JAR文件 .class文件的层次结构即可。 I suggest something is missing from your jar file, or present under the wrong name or directory. 我建议您的jar文件中缺少某些内容,或者使用了错误的名称或目录。

And note that NoClassDefError isn't the same as ClassNotFoundException. 请注意,NoClassDefError与ClassNotFoundException不同。 It means the file was found but it didn't contain the class expected, eg wrong case or wrong package. 这意味着找到文件但其中不包含预期的类,例如,大小写错误或程序包错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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