wood burning stoves*
The moose likes Java in General and the fly likes JNI : Creating a JVM Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "JNI : Creating a JVM" Watch "JNI : Creating a JVM" New topic
Author

JNI : Creating a JVM

Keyur Shah
Greenhorn

Joined: May 31, 2000
Posts: 15
I am trying to invoke a simple java application from native side. While creating a JVM I am getting following error. I shall be higly obliged if I get any suggestions / comments - Thank you.
I am using VC++ 5.0 IDE to compile my natice 'C' program. I receive an error at following line :
/* Create the Java VM */
res = JNI_CreateJavaVM(&jvm, &env, &vm_args);
And the error is :
Error C2664: 'JNI_CreateJavaVM' : cannot convert parameter 2 from 'struct JNIEnv_ ** ' to 'void ** '
Sahir Shah
Ranch Hand

Joined: Nov 05, 2000
Posts: 158

Try modifying
JNIEnv *env;
to
JNIEnv env;
Let me know if it works.
Cheers.
Sahir


....
Sahir Shah
Ranch Hand

Joined: Nov 05, 2000
Posts: 158

Oops . Sorry I didnt see that ** . It must be something else then. You will have to go through that header file with a fine toothcomb to find the problem. Is it really worth the effort ?
Cheers
Sahir
Keyur Shah
Greenhorn

Joined: May 31, 2000
Posts: 15
Thanks Sahir !
Well, I need to cast it by (void **) and it gets compiled. But I am getting runtime error!
Thanks once again!
- Keyur
Sahir Shah
Ranch Hand

Joined: Nov 05, 2000
Posts: 158

Hi this is a demo of calling a java class from C written by Davanum Srinivas
<pre>
#include <jni.h>
#include <windows.h>
#define PATH_SEPARATOR ';' /* platform dependent */
#define USER_CLASSPATH "." /* directory where Sample.class is present */
typedef jint (*P_JNI_GetDefaultJavaVMInitArgs)(void *args);
typedef jint (*P_JNI_CreateJavaVM)(JavaVM **pvm, JNIEnv ** penv, void *args);
void __cdecl main(int argc, char **argv) {
char classpath[1024]; /* Class Path */
JNIEnv *env = NULL; /* Environment */
JavaVM *jvm = NULL; /* Virtual Machine */
JDK1_1InitArgs vm_args; /* Initializing arguments */
jint res = -1;
jclass cls;
jmethodID mid;
jstring jstr;
jobjectArray args;
HANDLE hLib = NULL;
/* Pointer to required functions */
P_JNI_GetDefaultJavaVMInitArgs pfnGetDefaultJavaVMInitArgs = NULL;
P_JNI_CreateJavaVM pfnCreateJavaVM = NULL;

/* Load the library */
printf("Loading Library .... msjava \n");
hLib = LoadLibrary("msjava");
if(hLib == NULL) {
printf("Unable to Load Library.... exiting....");
exit(-1);
}
pfnGetDefaultJavaVMInitArgs = (P_JNI_GetDefaultJavaVMInitArgs) GetProcAddress(hLib, "JNI_GetDefaultJavaVMInitArgs");
vm_args.version = 0x00010001;
/* Get the default arguments */
if(pfnGetDefaultJavaVMInitArgs != NULL)
(*pfnGetDefaultJavaVMInitArgs)(&vm_args);
if(vm_args.classpath != NULL)
sprintf(classpath, "%s%c%s", vm_args.classpath, PATH_SEPARATOR, USER_CLASSPATH);
else
sprintf(classpath, "%s", USER_CLASSPATH);

vm_args.classpath = classpath;
/* Store the function pointer for creating the VM */
pfnCreateJavaVM = (P_JNI_CreateJavaVM) GetProcAddress(hLib, "JNI_CreateJavaVM");
/* Create the Java VM */
if(pfnCreateJavaVM != NULL)
res = (*pfnCreateJavaVM)(&jvm,&env,&vm_args);
if (res < 0) {<br /> fprintf(stderr, "Can't create Java VM\n");<br /> exit(1);<br /> }<br /> cls = (*env)->FindClass(env, "Test");
if (cls == 0) {
fprintf(stderr, "Can't find %s.class Test");
exit(1);
}

mid = (*env)->GetStaticMethodID(env, cls, "main", "([Ljava/lang/String V");
if (mid == 0) {
fprintf(stderr, "Can't find main function in %s.class Test");
exit(1);
}
jstr = (*env)->NewStringUTF(env, "Hello World!!!");
if (jstr == 0) {
fprintf(stderr, "Out of memory\n");
exit(1);
}
args = (*env)->NewObjectArray(env, 1, (*env)->FindClass(env, "java/lang/String"), jstr);
if (args == 0) {
fprintf(stderr, "Out of memory\n");
exit(1);
}
(*env)->CallStaticVoidMethod(env, cls, mid, args);
(*jvm)->DestroyJavaVM(jvm);
}
</pre>

I tried it out in VCPP. It compiles and runs fine.
Cheers
Sahir
[This message has been edited by Sahir Shah (edited December 25, 2000).]
Sanjib Talukdar
Greenhorn

Joined: Dec 18, 2000
Posts: 6
Keyur,
/* Create the Java VM */
res = JNI_CreateJavaVM(&jvm, &env, &vm_args);
In the above method call, you need to pass a void ** as the second parameter.
After the method returns successfully, you will have to cast the void ** argument variable to jenv ** variable.
That should work.
Sanjib.
Keyur Shah
Greenhorn

Joined: May 31, 2000
Posts: 15
Thank you very much Sahir and to you Sanjib.
Sahir, the program you've given is for JDK1.1.5 and I doubt if it works with JDK1.2 or not. JNI_GetDefaultJavaVMInitArgs is not needed with JDK1.2. I am sorry I was out of town and got your message late. I will try it today and would let you know.
Thanks once again - I am hihgly obliged.
- Keyur
tioroy
Greenhorn

Joined: May 22, 2001
Posts: 1
use
res = JNI_CreateJavaVM(&jvm, (void **) &env,&vm_args);
but, looking in the previous lines, changes:
vm_args.version = 0x00010001;
to
vm_args.version = JNI_VERSION_1_2;

To me, JNI_CreateJavaVM returned -3 (JNI_EVERSION). Changes the line, the VM is initialized correctly.
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: JNI : Creating a JVM