如何在C ++(JNI)中设置正在运行的JVM的类路径?

时间:2017-07-21 08:15:30

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

在C ++(JNI)中,我使用以下JNI函数获取已经运行的JVM:

JNI_GetCreatedJavaVMs(&jvm,1,&vmnb);

然后我使用以下代码附加当前线程:

jvm->AttachCurrentThread((void**)&env, NULL);

问题:在这种情况下如何设置classpath?感谢。

注意:创建 new JVM并将vm_args中的类路径传递给新JVM 是我的选项。

2 个答案:

答案 0 :(得分:1)

以下是解决方案: 因为可以在Java中附加classpath,所以我找到了一种通过Java在C ++中设置classpath的替代方法。因为我已经运行了JVM,所以我在已经在JVM中运行的Java程序中使用了追加类路径方法(void addPath(String path),它发布在this answer中)。我使用JNI调用从C ++访问addPath java方法以附加类路径。从C ++传递给addPath方法的类路径不应包含"-Djava.class.path",它应该只是.jar文件的完整路径,即"C:\\folder\\abc.jar"。所以序列是:1)已经运行JVM,将当前线程附加到JVM,获取JNI环境指针,然后使用JNI从C ++调用addPath java函数(另一个正在运行的线程)。我现在可以从C ++成功访问新类路径(.jar文件)的类。

答案 1 :(得分:0)

我遇到了这个问题,并且我没有选择回叫JVM的选择,所以我在JNI端实现了整个add_path业务。

void add_path(JNIEnv* env, const std::string& path)
{
    const std::string urlPath = "file:/" + path;
    jclass classLoaderCls = env->FindClass("java/lang/ClassLoader");
    jmethodID getSystemClassLoaderMethod = env->GetStaticMethodID(classLoaderCls, "getSystemClassLoader", "()Ljava/lang/ClassLoader;");
    jobject classLoaderInstance = env->CallStaticObjectMethod(classLoaderCls, getSystemClassLoaderMethod);
    jclass urlClassLoaderCls = env->FindClass("java/net/URLClassLoader");
    jmethodID addUrlMethod = env->GetMethodID(urlClassLoaderCls, "addURL", "(Ljava/net/URL;)V");
    jclass urlCls = env->FindClass("java/net/URL");
    jmethodID urlConstructor = env->GetMethodID(urlCls, "<init>", "(Ljava/lang/String;)V");
    jobject urlInstance = env->NewObject(urlCls, urlConstructor, env->NewStringUTF(urlPath.c_str()));
    env->CallVoidMethod(classLoaderInstance, addUrlMethod, urlInstance);
    std::cout << "Added " << urlPath << " to the classpath." << std::endl;
}