Sample code for using C to call Java VM

I found dozens of guys are looking for the source code to write a exe calling Java VM but few reply messages contain a complete demo. In fact, it also makes me nerve-racking for a couple of days. Now I get a demo program and post it to all, which is small but clear enough to show the idea. To some JNI gurus, it may be trivial, but to the newbie like me, it may be helpful. Of course, you may have to modify some string to run this program on your system.

//How to compile

//cl whatever.c -link jvm.lib

///////////////////////////////////////

#include <stdio.h>

#include <jni.h>

#include <windows.h>

typedef jint (JNICALL CreateJavaVM_t)(JavaVM **pvm, void **env, void *args);

JavaVM* jvm;

JNIEnv* create_vm() {

JNIEnv* env;

JavaVMInitArgs args;

JavaVMOption options[1];

int retval = 0;

CreateJavaVM_t *CreateJavaVM;

HINSTANCE handle;

/* Load the Java VM DLL */

if ((handle = LoadLibrary("c:\\j2sdk1.4.0\\jre\\bin\\client\\jvm.dll")) == NULL)

{

printf("Error:cannot loading 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;

}

args.version = JNI_VERSION_1_2;

args.nOptions = 1;

options[0].optionString = "-Djava.class.path=d:\\myprojects\\java\\classes";

args.options = options;

args.ignoreUnrecognized = JNI_FALSE;

retval = CreateJavaVM(&jvm, (void **)&env, &args);

if(retval != 0)

{

printf("Error: cannot create JVM");

return NULL;

}

return env;

}

void invoke_class(JNIEnv* env) {

jclass myClass;

jmethodID mainMethod;

jobjectArray applicationArgs;

jstring applicationArg0;

if(env == NULL) return;

myClass = (*env)->FindClass(env, "Project1/Application1");

if(myClass == NULL)

{

printf("Error: cannot find class\n ");

return;

}

mainMethod = (*env)->GetStaticMethodID(env, myClass, "main", "([Ljava/lang/String;)V");

if(mainMethod == NULL)

{

printf("Error: cannot find method\n ");

return;

}

applicationArgs = (*env)->NewObjectArray(env, 1, (*env)->FindClass(env, "java/lang/String"), NULL);

applicationArg0 = (*env)->NewStringUTF(env, "From-C-program");

(*env)->SetObjectArrayElement(env, applicationArgs, 0, applicationArg0);

(*env)->CallStaticVoidMethod(env, helloWorldClass, mainMethod, applicationArgs);

(*jvm)->DestroyJavaVM(jvm);

}

int main(int argc, char **argv) {

JNIEnv* env = create_vm();

invoke_class( env );

}

[2875 byte] By [r_liana] at [2007-9-27 7:28:36]
# 1

Not bad. But really, if you guys do the search and take times to read most of the reply, you should be able to find an answer you want. If you cannot, go and get the Java Native Interface book on this site and read that book before posting questions asking how to make an executable for Windows using JNI (the book have a complete source code.)

This is the link: http://java.sun.com/docs/books/jni/index.html

IChenga at 2007-7-8 11:18:45 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 2
I really took time to check most of the replay, and then figured out the sample code. What I do is just to make things easy and timesaving for some guys. I did not mean to complain anyone.Anyway, thank you for your advise.
r_liana at 2007-7-8 11:18:45 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 3
... and you don't need to buy a very expensive book ;-)
frisco_stevea at 2007-7-8 11:18:45 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 4

Thank you r lian. You did a good job! Your codes help me a lot in creating JVM. Before this, I have tried many sample codes, but all failed. However, I have two suggestions:

1) When you use jvm.dll in the program, you do not need -link jvm.lib anymore in the cl command. Only jvm.dll is enough.

2) In your codes, "helloWorldClass" should be "myClass" instead.

Otherwise, your codes are working great for j2sdk1.4.1_02.

Summer

summer888a at 2007-7-8 11:18:45 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 5

Hi,

i have try the sample, but i have a error.

please help me.

ans i don't understand all this code

--Configuration: javaappli - Win32 Debug--

Compiling...

invoke.c

c:\documents and settings\delllatitude\bureau\javaappli\invoke.c(73) : error C2065: 'helloWorldClass' : undeclared identifier

c:\documents and settings\delllatitude\bureau\javaappli\invoke.c(73) : warning C4047: 'function' : 'struct _jobject *' differs in levels of indirection from 'int '

c:\documents and settings\delllatitude\bureau\javaappli\invoke.c(73) : warning C4024: 'function through pointer' : different types for formal and actual parameter 2

Error executing cl.exe.

invoke.obj - 1 error(s), 2 warning(s)

kornfra at 2007-7-8 11:18:45 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 6

Hi ,

It's true.

Really I tried nearly one month to succeed creating the JVM.

But now, we set the jvm.dll in the Environment pointer.

But since you have given some handle, etc. like things, I think I can load the dll from code instead of asking setting that in Environment pointer.

Please explain if I use a Win32 program without windows.h

Because i.e. our requirement

Thanks in Advance

LathaDhamoa at 2007-7-8 11:18:45 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 7
worked first pop; well done!
sambellda at 2007-7-8 11:18:45 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 8

Hi,

I am trying to run this from past 2 days. But I am failing to do so. I did the following. Can you please tell me where am I going wrong

1. I wrote the C program

#include <jni.h>

#ifdef _WIN32

#define PATH_SEPARATOR ';'

#else

#define PATH_SEPARATOR ':'

#endif

int main() {

JavaVMOption options[1];

JNIEnv *env;

JavaVM *jvm;

JavaVMInitArgs vm_args;

long status;

jclass cls;

jmethodID mid;

jint square;

jboolean not;

options[0].optionString = "-Djava.class.path=.";

memset(&vm_args, 0, sizeof(vm_args));

vm_args.version = JNI_VERSION_1_2;

vm_args.nOptions = 1;

vm_args.options = options;

status = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);

}

2. I tried compiling the above. But I get

Error: Unresolved external 'JNI_CreateJavaVM' referenced from C:\JNITEST\JNIEXAMPLE.OBJ

i. I am using BCC compiler

ii. bcc32.cfg file contains

-I"C:\BCC55\Include"

-I"C:\Program Files\Java\jdk1.5.0_02\include\win32"

-I"C:\Program Files\Java\jdk1.5.0_02\include"

-L"C:\BCC55\Lib"

-L"c:\Program Files\Java\jdk1.5.0_02\lib"

iii. Command Line Argument being given for compiling is

C:\JniTest>bcc32 -IC:\Program/Files\Java\jdk1.5.0_02\include JniExample.c -Lc:\Program/Files\Java\jdk1.5.0_02\lib\jvm.lib

-IC:\Program/Files\Java\jdk1.5.0_02\include: Contains Jni.h

iv. Env Variable path has the following

C:\Program Files\Java\jdk1.5.0_02\bin\;

C:\bcc55\Bin\;

C:\Program Files\Java\jdk1.5.0_02\jre\bin\client\;

C:\Program Files\Java\jdk1.5.0_02\jre\bin

WHERE AM I GOING WRONG ...

Shashank.Tilwallia at 2007-7-8 11:18:45 > top of Java-index,Java HotSpot Virtual Machine,Specifications...