1

I want to write an dll in C/C++ and call java methods contained in an jar file. I found many threads on SO with the opposite (using a dll from a jar), but not much for my case. So I'm wondering if this is even possible/reasonable at all. I thought just an matching jvm would be required on the machine that loads the dll - but it seems I have to embed a whole jvm in my dll. That would be overkill in my scenario.

My reason to do this is the following: I have an 3rd party application that is capable of loading dlls with a certain interface and I have also a license algorithm as jar file (which will check if a valid license is installed on this machine - no source code for this jar is existing at my end). So I want to compile an dll that will only work if the license mechanism from the jar file returns success. Do I really have to embed a whole jvm in my dll then? Which problems could occur? Any ideas/suggestions on this topic?

Thanks,

Community
  • 1
  • 1
Constantin
  • 8,721
  • 13
  • 75
  • 126

1 Answers1

2

I want to write an dll in C/C++ and call java methods contained in an jar file

You have to access jvm.dll in the c/c++ program.

JNIEnv* create_vm(JavaVM ** jvm)
{
JNIEnv *env;
JavaVMInitArgs vm_args;
JavaVMOption options[2];

options[0].optionString = "-Djava.class.path=.";
options[1].optionString = "-DXcheck:jni:pedantic";  

vm_args.version = JNI_VERSION_1_6;
vm_args.nOptions = 2;
vm_args.options = options;
vm_args.ignoreUnrecognized = JNI_TRUE; // remove unrecognized options

int ret = JNI_CreateJavaVM(jvm, (void**) &env, &vm_args);
if (ret < 0) printf("\n<<<<< Unable to Launch JVM >>>>>\n");
return env;
 }

Here's the c++ program I've prepared to access main method of HelloWorld Class.

int main(int argc, char* argv[])
{
JNIEnv* env;
JavaVM* jvm;

env = create_vm(&jvm);

if (env == NULL) return 1;

jclass myClass = NULL;
jmethodID main = NULL;

/* Get the Hello World Class */
myClass = env->FindClass("HelloWorld");

/* Call the main method */
if (myClass != NULL)
    main = env->GetStaticMethodID(myClass, "main", "([Ljava/lang/String;)V");
else
    printf("Unable to find the requested class\n");


if (main != NULL)
{
   env->CallStaticVoidMethod( myClass, main, " ");
}else
   printf("main method not found") ;


jvm->DestroyJavaVM();
return 0;
}

Compile

g++ -D_JNI_IMPLEMENTATION_ -I"C:\Program Files\Java\jdk1.6.0_32\include" -I"C:\Program Files\Java\jdk1.6.0_32\include\win32" hello.cpp -L"C:\Program Files\Java\jre6\bin\client" -ljvm -o hello.exe

Further, If you wish to extend this functionality to jar files. use class loaders.

I used MinGW on windows with jdk 1.6. I've tested this code and created a custom exe for my application on windows to package the JRE with my application

Sorter
  • 9,704
  • 6
  • 64
  • 74