简体   繁体   English

在UWP C ++应用程序内部生成JVM时崩溃

[英]Crash when spawning a JVM inside of a UWP C++ Application

First of: I don't know if this problem is rather related to UWP and it's strange security settings or rather me mis-using JNI's Invocation 首先:我不知道这个问题是否与UWP有关,并且它是奇怪的安全设置,还是我误用了JNI的调用

Anyhow, I use this code to spawn a jvm inside a c++ static library (With /ZW , so compiling for UWP, but disabling it doesn't change a thing). 无论如何,我使用此代码在c ++静态库内生成了一个jvm(使用/ZW ,因此可以编译UWP,但是禁用它不会改变任何事情)。

The following code is based upon Oracle's Notes and openjdk's code (exeinvoke.c, launcher.c, ...): 以下代码基于Oracle的便笺和openjdk的代码(exeinvoke.c,launcher.c等):

void JVM4UWP::loadVM(string vmOptions[], int numOptions, int jni_version) {
    /* Copy the VM Options */
    options = new JavaVMOption[numOptions];
    for (uint8_t i = 0; i < numOptions; i++) {
        options[i].optionString = new char[vmOptions[i].length() + 1]; // \0 takes the additional byte
        strncpy_s(options[i].optionString, vmOptions[i].length() + 1, vmOptions[i].c_str(), vmOptions[i].length() + 1);
    }

    //options[0].optionString = "-Djava.class.path=/usr/lib/java";
    vm_args = new JavaVMInitArgs();
    vm_args->version = jni_version;
    vm_args->nOptions = numOptions;
    vm_args->options = options;
    vm_args->ignoreUnrecognized = false;

    /* load and initialize a Java VM, return a JNI interface
    * pointer in env */
    JNI_CreateJavaVM(&jvm, (void**)&env, vm_args);
    delete options;

    /* invoke the Main.test method using the JNI */
    jclass cls = env->FindClass("Main");
    jmethodID mid = env->GetStaticMethodID(cls, "main", "(I)V");
    env->CallStaticVoidMethod(cls, mid, 100);

    /* We are done. */
    jvm->DestroyJavaVM();
}

Now the problem with this is: I added #include <jni.h> , I added lib/jvm.lib as static library (taken from oracle's jdk), however it seems that something is still incomplete. 现在的问题是:我添加了#include <jni.h> ,我添加了lib/jvm.lib作为静态库(取自oracle的jdk),但是似乎仍然不完整。

When I run the application, I get an error upon loadup ( App::App of the sample UWP application isn't even run). 当我运行该应用程序时,加载时出现错误(示例UWP应用程序的App::App甚至没有运行)。

The console returns: 控制台返回:

Das Programm "[1892] TestJVM.exe" wurde mit Code -1073741515 (0xc0000135) 'Es wurde keine abhängige DLL gefunden' beendet. Das程序“ [1892] TestJVM.exe”的代码为-1073741515(0xc0000135)'Es wurde keineabhängigeDLL gefunden'已保存。

Loosely translated it's: Could find no dependant dll . 松散地翻译是: Could find no dependant dll

Now this reminds me of this MSDN Article. 现在,这使我想起了 MSDN文章。 I have to admit that I don't fully understand it's contents. 我不得不承认我不完全了解它的内容。 Especially since jvm.lib cannot have any Manifests. 特别是因为jvm.lib不能有任何清单。 I tried to add jvm.dll , java.dll and jli.dll to the folder of the .exe but for some reason it still doesn't work. 我试图将jvm.dlljava.dlljli.dll添加到.exe的文件夹中,但是由于某些原因,它仍然无法正常工作。

Since the above code should work without dlls, I think it might be related to UWP, maybe even to my code: 由于上述代码应在没有dll的情况下工作,因此我认为它可能与UWP有关,甚至可能与我的代码有关:

My Setup currently is like this: I have the JVM4UWP static library which in-turn is linked statistically against jvm.lib . 我的安装程序当前是这样的:我有JVM4UWP静态库,该库又与jvm.lib统计jvm.lib This Library is then included into the Demo UWP Project, which I am trying to execute. 然后将该库包含到我正在尝试执行的Demo UWP项目中。

Note that only subset of usual Windows APIs is available for uwp applications and I doubt that jvm is compatible with these restrictions. 注意,只有普通Windows API的子集可用于uwp应用程序,我怀疑jvm是否与这些限制兼容。 "lib/jvm.lib" might actually be an export library, not static library. “ lib / jvm.lib”实际上可能是导出库,而不是静态库。

Also you probably might want to get familiar with Using a Win32 DLL in a Universal Windows Platform App . 您可能还想熟悉在通用Windows平台应用程序中使用Win32 DLL

It looks like JVM library is missing. 看来缺少JVM库。

Take a look here for a sample where JVM is executed from C code: 在这里查看从C代码执行JVM的示例:

http://jnicookbook.owsiak.org/recipe-no-027/ http://jnicookbook.owsiak.org/recipe-no-027/

This sample is little bit more complex (it uses POSIX threads) but still, basics are the same. 该示例稍微复杂一点(它使用POSIX线程),但是基本知识是相同的。

Make sure that all libraries are on PATH so they can be loaded by either C++ or JVM. 确保所有库都在PATH上,以便可以通过C ++或JVM加载它们。

Have fun with JNI! 与JNI玩得开心!

Okay, so I made progress: This Question , compiling for Win32 and the fact that you have to embed dll's so they are available, showed me that the jvm.dll was missing, even though I added it to the program's path. 好的,所以我取得了进展: 这个问题 (为Win32编译)以及必须嵌入 dll以便可以使用的事实,向我表明jvm.dll丢失了,即使我将其添加到了程序的路径中。 Using gflags as pointed out above shows you which dlls it's trying to load and where it tried to locate them. 使用上面指出的gflags可以向您显示它正在尝试加载哪些dll,以及在何处找到它们。

Actually, you don't have to embed dll's for debugging purposes, but the dlls have to reside inside of the AppX Folder, instead of the Root folder (even though there is also an exe file there). 实际上,您不必为了调试目的而嵌入dll,但是dll必须驻留在AppX文件夹内,而不是Root文件夹内(即使那里也有一个exe文件)。

So since it's not mentioned elsewhere: When linking against jvm.lib, you still need the jvm.dll since this lib only seems to handle dynamic loading/wrapping/etc 因此,由于未在其他地方提及: 在链接到jvm.lib时,您仍然需要jvm.dll,因为此lib似乎只能处理动态加载/包装/ etc

Note that only subset of usual Windows APIs is available for uwp applications and I doubt that jvm is compatible with these restrictions. 注意,只有普通Windows API的子集可用于uwp应用程序,我怀疑jvm是否与这些限制兼容。

Yes and no, I had a look at openJDKs Sourcecode and the Majority of it is only File Handling and such, so I guess the part which could require reworking is the Memory and Threading related things. 是的,不是,我看过openJDK的源代码,它的多数只是文件处理等,所以我猜可能需要重新处理的部分是与内存和线程相关的事情。

Anyhow I was expecting such errors rather as Access Violations since some OS imports are simply 0x0 (aka not found), so I could now what I have to change to make it UWP compatible. 无论如何,由于某些OS导入仅为0x0 (即未找到),因此我一直期待此类错误,而不是访问冲突,因此我现在可以进行更改以使其与UWP兼容。 I might also give recompiling the openJDK with /ZW a try, but it's a challenging task. 我也可以尝试使用/ ZW重新编译openJDK,但这是一项艰巨的任务。

Using a Win32 DLL in a Universal Windows Platform App also tells that at least the static librarys seem to work as is, maybe one needs wrappers for the illegal API to link into the project. Using a Win32 DLL in a Universal Windows Platform App还表明,至少静态库似乎可以正常工作,也许可能需要包装器才能将非法API链接到项目中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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