通过JNI部署JRE:jvm.dll不能在Windows上运行或[......]

时间:2015-02-28 06:35:51

标签: java c++ jvm java-native-interface

所以我正在创建一个将Java Runtime Environment(JRE)打包为资源的Win32应用程序。应用程序将资源提取到磁盘并解压缩。现在,我想使用此JRE以使用调用API运行Java程序。一旦我改为程序指向提取的JRE的jvm.dll而不是安装的JRE(这是我复制的),我收到了这个错误:

  

< jre-path> \ jre1.8.0_31 \ bin \ server \ jvm.dll要么不是设计为在Windows上运行,要么包含错误。尝试使用原始安装介质再次安装程序,或与系统管理员或软件供应商联系以获取支持。错误状态0x000012f

jvm.dll error message

我希望对此问题采取的措施是记录此错误以及导致错误的原因。如果可能的话,找到一个解决方案,以便我可以引用提取的JRE。

让我详细说明一下我的环境。首先,我正在运行Windows 10 Tech Preview。我的操作系统,我的程序和我从安装中复制的JRE都是64位的。此外,当我的程序指向已安装的JRE时,它运行正常,问题仅在于复制的JRE。

还有一些代码可以参考我正在做的事情:

typedef jint (JNICALL *CreateJVMFunc)(JavaVM **pvm, void **penv, void *args);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    //For brevity I am omitting the extraction/unzipping.
    //I am using libzip to do the unzipping which uses zlib
    //for dealing with the compression/decrompression.
    //Likewise, I am also omitting the error checking for brevity.

    //Assume at this point the JRE folder exists in the same location
    //as this program's executable file.  I am accessing the jvm.dll
    //using a relative file path.

    //Load the Java virtual machine inside of the packaged JRE.
    //This is where that error occurs.
    //LoadLibrary is necessary because I must connect to the DLL after
    //it has been unpacked.
    HMODULE jvmDll = LoadLibrary(_T("jre1.8.0_31\\bin\\server\\jvm.dll"));
    CreateJVMFunc CreateJVM = (CreateJVMFunc)GetProcAddress(jvmDll, "JNI_CreateJavaVM");

    //Start the Java virtual machine.
    JavaVM *jvm;
    JNIEnv *env;
    JavaVMInitArgs vmArgs;
    JavaVMOption *options = new JavaVMOption[1];
    options[0].optionString = "-Djava.class.path=C:/Users/Nicholas/Documents/Programming Projects/Java Projects/JVM Launcher Test/JVM Launcher Test.jar"
    vmArgs.version = JNI_VERSION_1_8;
    vmArgs.nOptions = 1;
    vmArgs.options = options;
    vmArgs.ignoreUnrecognized = false;

    int retVal = CreateJVM(&jvm, (void**)&env, &vmArgs);
    delete[] options;

    //Instantiate the program.
    jclass mainClass = env->FindClass("jvmlauncher/test/Application");
    jmethodID mainMethod = env->GetStaticMethodID(mainClass, "main", "([Ljava/lang/String;)V");
    env->CallStaticVoidMethod(mainClass, mainMethod, NULL);

    //Cleanup.
    jvm->DestroyJavaVM();
    FreeLibrary(jvmDll);
    return 0;
}

所以我想有几个问题我想找到答案。

  • 究竟是什么触发了错误消息?此错误并非我的应用程序所独有,因此该错误存在哪些文档?

  • 为什么复制的JRE(已安装的JRE的精确副本)无法正常工作?

  • 如何纠正这种情况,以便我可以使用这个解压缩的JRE?

2 个答案:

答案 0 :(得分:0)

  

究竟是什么触发了错误消息?此错误并非我的应用程序所独有,因此该错误存在哪些文档?

错误消息是正确的。我的自定义安装出了问题。显然,文件在从可执行文件中提取时丢失了数据。 在当前安装的JRE中进行字面复制后,一切正常!

  

为什么复制的JRE(已安装的JRE的精确副本)无法正常工作?

因为它不是"确切的"副本。

  

如何纠正这种情况,以便我可以使用这个解压缩的JRE?

这不再是一个问题,因为这是我的错。提取没有正确完成。

PS:享受JNI代码,希望以后可以帮助别人这样做!

答案 1 :(得分:0)

只需安装32位JDK版本并运行Android Studio。
如果Android Studio自身未检测到32位JDK,则更改环境变量