简体   繁体   中英

JNI_CreateJavaVM function method does not work and cannot be debugged

JNI_CreateJavaVM function method does not work and cannot be debugged.

  • The development environment is win10 x64, jdk version is 1.8

  • Visual studio 2017 Community Edition Writing a C++ project


I am learning about JNI. I am trying to run The Invocation API . The following URL is an example of the official website documentation.
Click here !

I built the project and added a project dependency that contains jvm.lib. And I put jvm.dll in the project directory. I successfully run this program.

Main.test() is a method of print hello world . But the program exits when executing JNI_CreateJavaVM, the console shows that the return value is 1.

I can't get into debugging, I don't know what happened.

#include <jni.h>


int main() {
    printf("begin..........\n");
    JavaVM *jvm;       /* denotes a Java VM */
    JNIEnv *env;       /* pointer to native method interface */
    JavaVMInitArgs vm_args; /* JDK/JRE 6 VM initialization arguments */
    JavaVMOption* options = new JavaVMOption[1];
    char optionString[] = "-Djava.class.path =D:/Program Files/Java/jdk1.8.0_191/lib/";
    options[0].optionString = optionString;
    vm_args.version = JNI_VERSION_1_8;
    vm_args.nOptions = 1;
    vm_args.options = options;
    vm_args.ignoreUnrecognized = false;
    /* load and initialize a Java VM, return a JNI interface
     * pointer in env */

    int res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
    printf("result=%d", res);
    delete options;
    /* invoke the Main.test method using the JNI */
    jclass cls = env->FindClass("Main");
    jmethodID mid = env->GetStaticMethodID(cls, "test", "(I)V");
    env->CallStaticVoidMethod(cls, mid, 100);
    /* We are done. */
    jvm->DestroyJavaVM();
    return 0;
}

I expect this jvm can be called, but it is forced to exit when the program is executed to `int res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); Where am I wrong? Why is it not working?

Exit screenshot enter image description here

jvm.dll location enter image description here

jvm.lib linker additional library directories enter image description here

jvm.lib linker additional Dependencies enter image description here

Classpath

There is a space between key and equal sign. The space must be removed.

char optionString[] = "-Djava.class.path =D:/Program Files/Java/jdk1.8.0_191/lib/";

Classpath value

The java.class.path value must point to the base directory where your compiled .class files are located.

It looks like you're not using a package name, then it's the directory where Main.class is located, so probably it should look something like this:

char optionString[] = "-Djava.class.path=c:/Users/name/MyJavaPrograms/classes";

Access violation

SEGV (or exception 0xC0000005) is also generated intentionally on JVM startup to verify certain CPU/OS features.

see this fine answer: https://stackoverflow.com/a/36258856

In Visual Studio, when the exception dialog is shown, simply turn off that it breaks there. This will prevent you from seeing it again the next time you start the program again.

Java

Just for the sake of completeness: the Java method should look like this:

public class Main {

public static void test(int num) {
    System.out.println("Java: test called with '" + num + "'");
}

...

Visual Studio Configuration

The jvm.dll needs to be found. In Visual Studio under Configuration Properties/Debugging/Environment add PATH=%PATH%;<path-to-jdk>\\bin\\server

For later deployment you could think about putting the whole JRE into a subfolder of your application and reference it with a relative path.

Demo

Finally a brief demo (added a \\n here printf("result=%d\\n", res); to have a separate line):

演示

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM