Reputation: 164
In C++ (JNI), I get an already running JVM using the following JNI function:
JNI_GetCreatedJavaVMs(&jvm,1,&vmnb);
Then I attach the current thread using the following code:
jvm->AttachCurrentThread((void**)&env, NULL);
Question: How can I set classpath in that case? Thanks.
Note: Creating a new JVM and passing the classpath in vm_args to the new JVM is not an option for me.
Upvotes: 6
Views: 4581
Reputation: 164
As it is possible to append the classpath
inside Java, so I found an alternative way to set classpath inside C++ through Java. As I'm already running JVM, I use the append classpath method (void addPath(String path)
, that is posted in this answer), inside the Java program that is already running in the JVM. I access the addPath
java method from C++ using JNI calls to append the classpath. The classpath passed to addPath
method from C++ should not include "-Djava.class.path"
and it should be just complete path to the .jar file, i.e. "C:\\folder\\abc.jar"
. So sequence is: 1) get already running JVM, attach current thread to the JVM, get JNI environment pointer and then call addPath
java function (of another running thread) from C++ using JNI. I can now access the classes of new classpath (.jar file) successfully from C++.
Upvotes: 5
Reputation: 96
I ran into this issue, and I did not have the option to call back into the JVM, so I implemented the whole add_path
busniess on the JNI side.
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;
}
Upvotes: 2