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

时间:2014-02-08 19:07:51

标签: java c++ java-native-interface

我有一个非常直接的代码,可以通过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时它才有效。对我来说有点奇怪......

1 个答案:

答案 0 :(得分:0)

没有。您只需提供正确构造的JAR文件 .class文件的层次结构。我建议您的jar文件中缺少某些内容,或者出现在错误的名称或目录下。

请注意,NoClassDefError与ClassNotFoundException不同。这意味着找到 文件,但它不包含预期的类,例如错误的情况或错误的包裹。