Archived

This topic is now archived and is closed to further replies.

[java] JNI Problems

This topic is 5228 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
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.

Share this post


Link to post
Share on other sites
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.jar

END CAndromedaEngine: CreateVirtualMachine
------------------------------------------------------





[edited by - shaft on August 19, 2003 12:32:57 AM]

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites