JNI调用API - NoClassDefFoundError (C/Java)

5
我试图使用JNI,因为我有一个在C中的应用程序需要访问单个Java库函数(没有C等效库)。 我编写了一个非常简单的测试程序来从C加载Java VM并调用静态函数并获取返回值。
不幸的是,我无法正确加载类。虽然它可能会归结于这一点,但我认为我的ClassPath是正确的:当我在相同的目录中使用相同的ClassPath使用java命令时,该类会完美地加载和执行。
环境:
Ubuntu 8.04服务器
Java JRE&SDK 1.6
gcc
我的当前工作目录始终是/home/me/project
这是当我运行java命令时得到的结果(java -Djava.class.path=/home/me/project/ -verbose my.ClassABC):
[Loaded ...] (many loads)
[Loaded my.ClassABC from file:/home/me/project/]
Hello test
[Loaded java.lang.Shutdown from shared objects file]
[Loaded java.lang.Shutdown$Lock from shared objects file]

当我运行我的C程序(./myClassABC)时,我得到了以下结果:

[Loaded ...]
[Loaded my.ClassABC from file:/home/me/project/]
Exception in thread "main" java.lang.NoClassDefFoundError: my.ClassABC
Failed to get class

这是我的GCC命令行:
gcc -o myClassABC myClassABC.c -I/usr/lib/jvm/java-6-sun-1.6.0.16/include/ -I/usr/lib/jvm/java-6-sun-1.6.0.16/include/linux -L/usr/lib/jvm/java-6-sun-1.6.0.16/jre/lib/i386/server/ -ljvm
我的C代码(myClassABC.c):
int main(int argc,char **argv)
{
    JNIEnv *env;
    JavaVM *jvm;
    jint res;
    jclass cls;
    jmethodID mid;
    jstring jstr;
    jclass stringClass;
    jobjectArray args;

    JavaVMInitArgs vm_args;
    JavaVMOption options[2];
    options[0].optionString =
        "-Djava.class.path=."; // or "-Djava.class.path=/home/me/project/";
    options[1].optionString =
        "-verbose";
    vm_args.version = JNI_VERSION_1_6;
    vm_args.options = options;
    vm_args.nOptions = 2;
    vm_args.ignoreUnrecognized = JNI_FALSE;
    /* Create the Java VM */
    res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);

    if (res < 0) {
        fprintf(stderr, "Can't create Java VM\n");
        exit(1);
    }
    if ((*env)->ExceptionOccurred(env)) {
        (*env)->ExceptionDescribe(env);
    }

    cls = (*env)->FindClass(env,"my.ClassABC");
    if (cls == NULL) {
        if ((*env)->ExceptionOccurred(env)) {
            (*env)->ExceptionDescribe(env);
        }
        printf("Failed to get class\n");
        exit(1);
    }

    [call methods, etc.]
}

以下是我的Java代码,仅供娱乐(编译后生成/home/me/project/my/ClassABC.class):

package my;

class ClassABC {
    public static void main(String[] args) {
        System.out.println(ClassABC.getPassword("test"));
        return;
    }

    static String getPassword(String filename)
    {
        return "Hello "+filename;
    }
}

感谢您,
布莱恩
1个回答

10

只需替换此处

cls = (*env)->FindClass(env,"my.ClassABC");

使用

cls = (*env)->FindClass(env,"my/ClassABC");

然后你应该没问题了。

否则尝试添加

...
JavaVMOption options[3];
...
options[2].optionString = "-verbose:jni";
...

哦,太感谢了!回头看看规格和其他东西,我现在意识到我忽略了那个。 - HalfBrian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接