Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

creating a JVM from within a JNI method

Is it possible to create a JVM from within a JNI method using the JNI API?

I've tried to do this using the JNI function "JNI_CreateJavaVM()", but it's not working (the function keeps returning a value less than zero).

Here is the basic code I'm using (C++):

JNIEnv *env;
JavaVM *jvm;
jint res;

#ifdef JNI_VERSION_1_2
JavaVMInitArgs vm_args;
JavaVMOption options[2];
options[0].optionString =
    "-Djava.class.path=" USER_CLASSPATH;
options[1].optionString = "-verbose:jni";
vm_args.version = JNI_VERSION_1_2;
vm_args.options = options;
vm_args.nOptions = 2;
vm_args.ignoreUnrecognized = JNI_TRUE;
/* Create the Java VM */
res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);

#else

JDK1_1InitArgs vm_args;
char classpath[1024];
vm_args.version = 0x00010001;
JNI_GetDefaultJavaVMInitArgs(&vm_args);
/* Append USER_CLASSPATH to the default system class path */
sprintf(classpath, "%s%c%s",
        vm_args.classpath, PATH_SEPARATOR, USER_CLASSPATH);
vm_args.classpath = classpath;
/* Create the Java VM */
res = JNI_CreateJavaVM(&jvm, &env, &vm_args);

#endif /* JNI_VERSION_1_2 */

Where USER_CLASSPATH contains the path to the classes I want to load. After the above code executes, res < 0, indicating that JNI_CreateJavaVM() failed. The code above is part of a native method written in C++ called from Java. Any ideas on how to get this to work?

Thanks.

like image 678
DR. Avatar asked Feb 14 '10 02:02

DR.


People also ask

How does Java JNI work?

The JNI framework lets a native method use Java objects in the same way that Java code uses these objects. A native method can create Java objects and then inspect and use these objects to perform its tasks. A native method can also inspect and use objects created by Java application code.

What is native code in JVM?

The Java Native Interface (JNI) establishes a well-defined and platform-independent interface between the two. Native code can be used together with Java in two distinct ways: as "native methods" in a running JVM and as the code that creates a JVM using the "Invocation API".

What is JNI Bridge?

Introduction to Java Native Interface: Establishing a bridge between Java and C/C++ JNI (Java Native Interface) is a foreign function interface that allows code running on JVM to call (or be called by) native applications. Using JNI, one can call methods written in C/C++ or even access assembly language.


2 Answers

No, you can't. It's a documented restriction that you can only have one JVM at a time. The API is designed for the possibility of extension, but the extension has never happened.

If you are in a JNI method, then there is already one JVM, and one JVM per process is all you get.

like image 71
bmargulies Avatar answered Sep 28 '22 09:09

bmargulies


I see what you mean: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4479303

The bug report says it's not possible to run multiple JVMs in the same address space. I have to say I'm a little surprised that JNI_CreateJavaVM() doesn't fork off a new JVM in a different address space.

Since JNI_CreateJavaVM() doesn't fork a new process itself, is it possible to manually fork off another JVM process from within a JNI method and subsequently use IPC to manage it? If so, what's the best way to do this? A literal fork()/exec() doesn't seem like a good idea because it would copy the entire (probably very large) address space of the JVM only to throw it away immediately afterward.

like image 42
DR. Avatar answered Sep 28 '22 07:09

DR.