[java] JNI Problems

Started by
3 comments, last by tj963 20 years, 8 months ago
Hey, I''m trying to use the JNI Invocation API to write an executable to run a Java program. However, no matter how hard I try, I can''t get it to run. It always returns a negative number from JNI_CreateJavaVM, and the pointers are always returned as null. Does anybody know what the problem might be? I figue it might be something to do with files I''m not putting in the right place or something, but there''s a serious lack of documentation on this, and I copied the source of the API docs.

JavaVM *jvm;       /* denotes a Java VM */
	JNIEnv *env;       /* pointer to native method interface */
    
	JavaVMInitArgs vm_args;
	JavaVMOption options[4];

	options[0].optionString = "-Djava.compiler=NONE";           /* disable JIT */
	options[1].optionString = "-Djava.class.path=c:\\Prog;."; /* user classes */
	options[2].optionString = "-Djava.library.path=c:\\j2sdk1.4.2\\lib";  /* set native library path */
	options[3].optionString = "-verbose:jni";                   /* print JNI-related messages */

	vm_args.version = JNI_VERSION_1_2;
	vm_args.options = options;
	vm_args.nOptions = 4;
	vm_args.ignoreUnrecognized = true;

	//vm_args.classpath = ;

	/* load and initialize a Java VM, return a JNI interface 
	 * pointer in env */
	JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);

	/* invoke the Main.test method using the JNI */
	jclass cls = env->FindClass("Markbook");
	jmethodID mid = env->GetStaticMethodID(cls, "main", "[Ljava/lang/String;");
	env->CallStaticVoidMethod(cls, mid, 100);

	/* We are done. */
	jvm->DestroyJavaVM();

	return 0;
 
Thanks, tj963
tj963
Advertisement
I had a lot of problems trying to get it to work as well.
I found the one thing that got mine working was loading jvm.dll dynamically.

To dynamically load jvm.dll try the following code:

CreateJavaVM_t *CreateJavaVM;	HINSTANCE handle;	/* Load the Java VM DLL */	if ((handle = LoadLibrary("d:\\j2sdk1.4.2\\jre\\bin\\client\\jvm.dll")) == NULL)	{		printf("Error:cannot load JVM");		return NULL;	}	/* Now get the function addresses */	CreateJavaVM = (CreateJavaVM_t *)GetProcAddress(handle, "JNI_CreateJavaVM");	if (CreateJavaVM == NULL)	{		printf("Error: can''t find JNI interfaces\n");		return NULL;	}


After you have the function address you can call CreateJavaVM the same as you did above. Not sure if this will work for you but it was the one thing that got it working for me.

Corry GT.
Thanks, I''ll try try that.

tj963
tj963
It's possible it could be your options. Here's my code that works. My class path string only contains the address of the java code (.jar files) I need to speak to (not the sdk path stuff).

You may also want to make sure you installed the java sdk properly (i.e. .dlls are accessible).

void CAndromedaEngine::CreateVirtualMachine(){	DEBUGS("START CAndromedaEngine: CreateVirtualMachine()\n")	DEBUGS("------------------------------------------------------\n\n")		char classpath[SIZE_CLASS_PATH];	sprintf(classpath, "-Djava.class.path=%s", GetClassPath() );	DEBUGS("Classpath = ")	DEBUGS(classpath)	DEBUGS("\n")	//Load the Java Virtual Machine	JavaVMInitArgs vm_args;	JavaVMOption options[3];	options[0].optionString = classpath;	options[1].optionString = "exit";	options[1].extraInfo = VMExit;	options[2].optionString = "abort";	options[2].extraInfo = VMAbort;	vm_args.version = 0x00010002;	vm_args.options = options;	vm_args.nOptions = 3;	vm_args.ignoreUnrecognized = JNI_FALSE;	jint res = JNI_CreateJavaVM(&m_pJvm, (void**)&m_pEnv, &vm_args);	if(res < 0)	{		DEBUGS("CAndromedaEngine: Error Creating Virtual Machine\n")		CAndromedaException e(ANDROMEDA_VIRTUALMACHINEEXCEPTION, "CAndromedaEngine::CreateVirtualMachine() - Error Creating Virtual Machine");		throw(e);	}	DEBUGS("\nEND CAndromedaEngine: CreateVirtualMachine\n")	DEBUGS("------------------------------------------------------\n\n")}   


The debug output from this code is
START CAndromedaEngine: CreateVirtualMachine()------------------------------------------------------Classpath = -Djava.class.path=D:\AndromedaEngine\SourceCode\AndromedaEngineJava\AndromedaGameEngine\AndromedaGameEngine.jar;D:\AndromedaEngine\SourceCode\AndromedaEngineJava\AndromedaEngine\AndromedaEngine.jarEND CAndromedaEngine: CreateVirtualMachine------------------------------------------------------ 





[edited by - shaft on August 19, 2003 12:32:57 AM]
He''s a bad motha - Shut yo mouth.
I think I found your problem. I just discovered after formatting my hard drive that the above code that I said works, didn''t work. So after much stress and research I think I found the problem (at least it''s back and working for me).

Version 1.2(and above) requires your system path to not only contain "/bin" but also "jre/bin/classic". The classic directory contains the jvm.dll. If you tried to move the jvm.dll to another directory, the create method will fail. A FAQ on java.sun.com states that it uses the path where it finds "jvm.dll" as a reference to find other needed dll files. So if you move jvm.dll, it will fail because it can''t find the other dlls it needs.

Hope this helps.
He''s a bad motha - Shut yo mouth.

This topic is closed to new replies.

Advertisement