JNI调用FindClass获取package的时候失败. 不带包名则调用成功为什么?

发布于 2022-09-07 16:36:22 字数 2675 浏览 13 评论 0

c++进程启动jvm虚拟机 然后获取java相关类方法(使用FindClass), 如果只有一个类名是成功的,但是如果有包的话就会调用失败,相关代码如下:

//MyTest.java
package com;
import  java.lang.management.ManagementFactory;

public class MyTest {
    //private static int magic_counter = 777;

    public static boolean start(String path) {
        System.out.print("MyTest start: " + path);
        return true;
    }
}
// main.cpp
#include <iostream>
#include <jni.h>
#include <memory.h>

int main()
{
    char opt1[] = "-Djava.compiler=NONE";
    char opt2[] = "-Djava.class.path=./MyTest.jar";
    //char opt2[] = "-Djava.class.path=.";
    char opt3[] = "-verbose:NONE";

    JavaVMOption options[3];
    options[0].optionString = opt1; options[0].extraInfo = NULL;
    options[1].optionString = opt2; options[1].extraInfo = NULL;
    options[2].optionString = opt3; options[2].extraInfo = NULL;

    JavaVMInitArgs jargv;
    jargv.version = JNI_VERSION_1_6;
    jargv.nOptions = 3;
    jargv.options = options;
    jargv.ignoreUnrecognized = JNI_TRUE;

    JavaVM* jvm = NULL;
    JNIEnv* jenv = NULL;
    jint res = JNI_CreateJavaVM( &jvm, (void**)&jenv, &jargv  );
    if ( 0 != res  )
        return 1;

    jclass jc = jenv->FindClass("/com/MyTest");
    //jclass jc = jenv->FindClass("MyTest");
    //jclass jc = jenv->FindClass("java/lang/String");
    if ( NULL == jc  ) {
        if( jenv->ExceptionOccurred()  )
            jenv->ExceptionDescribe();
        else {
            std::cout << "jc null" << std::endl;
        }
        return 1;
    }

    jmethodID jmid = jenv->GetStaticMethodID( jc, "start", "(Ljava/lang/String;)Z");
    if ( NULL == jmid) {
        std::cout << "jmid null" << std::endl;
        return 1;
    }
    else {
        std::cout << "jmid ok" << std::endl;
    }

    jstring jniStr = jenv->NewStringUTF("jni to java");
    jboolean res1 = jenv->CallBooleanMethod( jc, jmid, jniStr);
    if(res1) {
        std::cout << "CallBooleanMethod ok" << std::endl;
    }

    std::cout << "\n";
    std::cout << "Hello, World!" << std::endl;
        return 0;
}

相关命令如下:

javac MyTest.java
jar cvf MyTest.jar MyTest.class
g++ main.cpp -I
~/jdk/include/ -I~/jdk/include/linux -L~s/jdk/jre/lib/amd64/server -ljvm

这是运行a.out会出现报错提示:类没有找到:
Exception in thread "main" java.lang.NoClassDefFoundError: /com/MyTest
Caused by: java.lang.ClassNotFoundException: .com.MyTest

如果java中把包名com去掉,c++中直接找类MyTest,那么FindClass就是成功的.

环境: ubuntu 16.04 jdk 1.8

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

眼角的笑意。 2022-09-14 16:36:22

已解决.
java对于带报名的类的查找是需要路径的,看修改就知道了.
mkdir com
mv MyTest.jar com/
tar cvf MyTest.jar com

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文