Wie fängt man Java-Ausnahmen mit einem C++-Launcher ab?Java

Java-Forum
Anonymous
 Wie fängt man Java-Ausnahmen mit einem C++-Launcher ab?

Post by Anonymous »

Ich schreibe eine Clientanwendung mit Java Swing. Ich bin ziemlich verwirrt darüber, wie ein Launcher JVM-Absturzinformationen erfassen kann, wenn die JVM abstürzt.
Die Datei hs_err_pid[PID].log wird nicht generiert. Ich glaube, mein C++-Launcher wird normal beendet.
Projektstruktur
Image

Einfacher C++-Launchercode

Code: Select all

#include 
#include 
#include 
#include 

typedef jint(JNICALL* PfnCreateJavaVM)(JavaVM**, void**, void*);

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {

// 1. get run path
wchar_t exePath[MAX_PATH];
GetModuleFileNameW(NULL, exePath, MAX_PATH);
std::wstring strPath(exePath);
size_t lastSlash = strPath.find_last_of(L"\\/");
std::wstring appDir = strPath.substr(0, lastSlash);

// myapp (target,Project Directory)
//
//      -> runtime (jdk env)
//      -> myapp.jar (core jar program)
//      -> main.cpp(launcher exe)

// path append
std::wstring jvmDllPath = appDir + L"\\runtime\\bin\\server\\jvm.dll";
std::wstring jarPath = appDir + L"\\myapp.jar";

// 2. load jvm  dLL
HMODULE hJvmDll = LoadLibraryW(jvmDllPath.c_str());
if (!hJvmDll) {
MessageBoxW(NULL, (L"not found jvm dll: " + jvmDllPath).c_str(), L"error", MB_OK | MB_ICONERROR);
return 1;
}

PfnCreateJavaVM createVM = (PfnCreateJavaVM)GetProcAddress(hJvmDll, "JNI_CreateJavaVM");

// 3. handler classpath utf-8
int size_needed = WideCharToMultiByte(CP_UTF8, 0, jarPath.c_str(), -1, NULL, 0, NULL, NULL);
std::string utf8JarPath(size_needed, 0);
WideCharToMultiByte(CP_UTF8, 0, jarPath.c_str(), -1, &utf8JarPath[0], size_needed, NULL, NULL);
std::string cpOption = "-Djava.class.path=" + utf8JarPath;

// 4. jvm params
JavaVMInitArgs vmArgs;
std::vector options;

options.push_back({ (char*)cpOption.c_str(), NULL });
options.push_back({ (char*)"--enable-native-access=ALL-UNNAMED", NULL });
options.push_back({ (char*)"-Dsun.java2d.uiScale=1", NULL });

vmArgs.version = JNI_VERSION_24;
vmArgs.nOptions = (jint)options.size();
vmArgs.options = options.data();
vmArgs.ignoreUnrecognized = JNI_FALSE;

// 5. start jvm and run
JavaVM* jvm;
JNIEnv* env;
if (createVM(&jvm, (void**)&env, &vmArgs) >= 0) {
jclass mainClass = env->FindClass("com/example/code/Application");
if (mainClass) {
jmethodID mainMethod = env->GetStaticMethodID(mainClass, "main", "([Ljava/lang/String;)V");
if (mainMethod) {
// call main method
jobjectArray args = env->NewObjectArray(0, env->FindClass("java/lang/String"), NULL);
env->CallStaticVoidMethod(mainClass, mainMethod, args);
//I can’t capture the exception because I believe the JVM has already crashed and exited.
if (env->ExceptionOccurred()) {
env->ExceptionDescribe();
env->ExceptionClear();
MessageBoxW(NULL, L"JVM crashed!", L"error", MB_OK | MB_ICONERROR);
}
}
}
else {
MessageBoxW(NULL, L"not find main !!!", L"error", MB_OK | MB_ICONERROR);
}
jvm->DestroyJavaVM();
}

FreeLibrary(hJvmDll);
return 0;
}
Ich habe hier gerade eine Ausnahme simuliert:
Image

Ausnahmebehandlungscode

Code: Select all

 if (env->ExceptionOccurred()) {
env->ExceptionDescribe();
env->ExceptionClear();
MessageBoxW(NULL, L"JVM crashed!", L"error", MB_OK | MB_ICONERROR);
}
Ich kann die Ausnahmeinformationen immer noch nicht erfassen. Ich glaube, dass die JVM abgestürzt ist und beendet wurde und die Ausnahme asynchron in einem separaten Thread ausgelöst wurde.
Wie kann ich JVM-Absturz-Exit-Informationen mit einem C++-Launcher erfassen?

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post