【发布时间】:2013-12-02 12:11:03
【问题描述】:
我正在尝试为应用程序创建插件。插件需要用 C++ 编写。我想在 Windows 和 Mac 上使用插件,所以用 Java 编写插件会很棒。
我的问题,还有一个使用 Java 的插件。由于他们使用的是同一个主应用程序,因此已经有一个正在运行的 JavaVM。
JavaVM *jvm = NULL;
jsize jvm_count = 0;
jint res=0;
res = JNI_GetCreatedJavaVMs (&jvm, 1, &jvm_count);
我的问题: 如何更改/修改现有 JavaVM 的类路径?或者我怎样才能创建一个新的/第二个 JavaVM?
我尝试通过 JNI 加载我的 jar 文件:
/* URL CLASS */
jclass URLcls;
URLcls = env->FindClass("java/net/URL");
/* URL CLASS CONSTRUCTOR*/
jmethodID URLclsMid;
URLclsMid = env->GetMethodID(URLcls, "<init>","(Ljava/lang/String;)V");
/* URL OBJECT */
jobject URLobj;
jstr = env->NewStringUTF("file:/path/to/test/file/test.jar");
URLobj = env->NewObject(URLcls, URLclsMid, jstr);
/* URL Array */
jobjectArray URLArray;
URLArray = env->NewObjectArray(1, URLcls, URLobj);
/*Thread Class*/
jclass ThreadCLS;
ThreadCLS = env->FindClass("java/lang/Thread");
/*Static Method currentThread*/
jmethodID ThreadCLS_currentThread;
ThreadCLS_currentThread = env->GetStaticMethodID(ThreadCLS, "currentThread","()Ljava/lang/Thread;");
/*get current Thread Object*/
jobject currentThread;
currentThread = env->CallStaticObjectMethod(ThreadCLS, ThreadCLS_currentThread);
/* getContextClassLoader method */
jmethodID currentThread_getContextClassLoader;
currentThread_getContextClassLoader = env->GetMethodID(ThreadCLS, "getContextClassLoader","()Ljava/lang/ClassLoader;");
/* ClassLoader Class */
jclass ClassLoaderCLS;
ClassLoaderCLS = env->FindClass("java/lang/ClassLoader");
/* get ClassLoader Object */
jobject classLoader = env->CallObjectMethod(currentThread, currentThread_getContextClassLoader);
/* URLClassLoader Class */
jclass URLClassLoaderCLS;
URLClassLoaderCLS = env->FindClass("java/net/URLClassLoader");
/* Static Method newInstance */
jmethodID URLClassLoaderCLS_newInstance;
URLClassLoaderCLS_newInstance = env->GetStaticMethodID(URLClassLoaderCLS, "newInstance","([Ljava/net/URL;Ljava/lang/ClassLoader;)Ljava/net/URLClassLoader;");
/* get new URLClassLoader Instance */
jobject myURLClassLoaderInstance;
myURLClassLoaderInstance = env->CallStaticObjectMethod(URLClassLoaderCLS, URLClassLoaderCLS_newInstance, URLArray, classLoader);
/* get setContextClassLoader Method */
jmethodID currentThread_setContextClassLoader;
currentThread_setContextClassLoader = env->GetMethodID(ThreadCLS, "setContextClassLoader","(Ljava/lang/ClassLoader;)V");
/* trying to set the ClassLoader from the current Thread */
env->CallVoidMethod(currentThread, currentThread_setContextClassLoader, myURLClassLoaderInstance);
/* get loadClass Method */
jmethodID loadClass;
loadClass = env->GetMethodID(URLClassLoaderCLS, "loadClass","(Ljava/lang/String;)Ljava/lang/Class;");
/* get a Class from my test.jar*/
jstring methodString = env->NewStringUTF("de.domain.sayHello");
jclass myClass = (jclass)env->CallObjectMethod(myURLClassLoaderInstance, loadClass, methodString);
/*working till here*/
jmethodID myClassMethod;
myClassMethod = env->GetMethodID(myClass, "doIt","()Ljava/lang/String;");
if (myClassMethod == NULL) {
// Method of Class "de.domain.sayHello" not found
}
如何更改类路径?还是加载我的 jar 文件?
谢谢 丽莎
【问题讨论】:
-
我不相信您可以以可靠的方式修改正在运行的虚拟机的类路径。您可以尝试实现自定义类加载器,也可以尝试使用调用 API 启动新 VM,请参阅:JNI_CreateJavaVM()。更多信息:docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/… 和 inonit.com/cygwin/jni/invocationApi/c.html
-
@Alex Barker 感谢您的评论。据我所知,当主应用程序的其他线程之一中已经有一个正在运行的 VM 时,不可能创建一个新的 VM。
标签: java c++ plugins java-native-interface