Развертывание JRE через JNI: jvm.dll не предназначен для работы в Windows или [......]

Поэтому я создаю приложение Win32, которое упаковывает Java Runtime Environment (JRE) в качестве ресурса. Приложение извлекает ресурс на диск и распаковывает его. Теперь я хотел бы использовать этот JRE для запуска Java-программы с использованием API вызова. Как только я переключился на программу, указывающую на извлеченный JRE файл jvm.dll вместо установленного JRE (что я и скопировал), я получил эту ошибку:

\ jre1.8.0_31 \ bin \ server \ jvm.dll либо не предназначен для работы в Windows, либо содержит ошибку. Попробуйте установить программу еще раз, используя оригинальный установочный носитель, или обратитесь к системному администратору или поставщику программного обеспечения за поддержкой. Состояние ошибки 0x000012f

Сообщение об ошибке jvm.dll

То, что я надеюсь сделать с этим вопросом, это документировать эту ошибку, а также то, что ее вызвало. И, если возможно, найдите решение, чтобы я мог сослаться на извлеченную 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?

1 ответ

Решение

Что именно вызывает сообщение об ошибке? Эта ошибка не является уникальной для моего приложения, поэтому какая документация существует для этой ошибки?

Сообщение об ошибке верно. Что-то не так с моей выборочной установкой. Видимо файлы потеряли данные при извлечении из исполняемого файла. После буквального копирования в установленную на данный момент JRE все работает!

Почему скопированная JRE (точная копия установленной) не работает, как я ожидал?

Потому что это не "точная" копия.

Как я могу исправить ситуацию, чтобы я мог использовать эту распакованную JRE?

Это больше не проблема, потому что это была ошибка с моей стороны. Извлечение не было сделано правильно.

PS: Наслаждайтесь кодом JNI, надеюсь, он поможет кому-нибудь позже сделать это!

Просто установите 32-битную версию JDK и запустите Android Studio.
Если Android Studio не обнаруживает 32-битный JDK, измените вашу переменную среды

Другие вопросы по тегам