2016-08-22 8 views
2

JNI経由でJavaを呼び出すC++を実行するWindowsサービスがあります。JNIのJavaクラッシュネイティブ

Windowsサービスマネージャを使用してサービスを停止すると、サービスがクラッシュします。次のJNIために登録する++

C:

SAPPHIRE_DLL_API int sapphire_adapter_initialize(CSACallbacks* callbacks) 
{ 
JavaVMInitArgs vm_args; 
JavaVMOption options[4]; 
int flow = 0; 

g_pPumpCallbacks = callbacks; 
for (flow = 0; flow == 0; flow++) 
{ 
    //options[0].optionString = "-Djava.class.path=SapphireAdapter.jar;hdpservices.jar;..\\virgo-tomcat-server-3.6.1.RELEASE\\pickup\\com.hospira.hdpservices_1.0.0.jar;slf4j-api.jar;slf4j-log4j12.jar;log4j.jar"; 
    options[0].optionString = "-Djava.class.path=SapphireAdapter.jar;hdpservices.jar;slf4j-api.jar;slf4j-log4j12.jar;log4j.jar"; 
    options[1].optionString = "-verbose:jni"; /* print JNI-related messages */ 
    //options[2].optionString = "-Xdebug"; 
    //options[3].optionString = "-Xrunjdwp:transport=dt_socket,address=8998,server=y,suspend=y"; /* Enable Remote Debugging */ 
    vm_args.version = JNI_VERSION_1_8; 
    vm_args.nOptions = 2; // set to 2 for verbose output from jni or 4 for remote debugging. 
    vm_args.options = &options[0]; 
    vm_args.ignoreUnrecognized = 0; 
    jint res = JNI_CreateJavaVM(&g_jvm, (void **)&g_env, &vm_args); 
    if (res != 0) 
    { 
     jint result = JNI_GetCreatedJavaVMs(&g_jvm, 1, NULL); 
     if(result != JNI_OK) 
      break; 
     result = g_jvm->GetEnv((void**)&g_env, JNI_VERSION_1_8); 
    } 
    if (! g_masterClassDef.cls) 
     g_masterClassDef.cls = (jclass)g_env->NewGlobalRef(g_env->FindClass("com/hospira/sapphire/adapter/SapphireAdapter")); 
    if (! g_masterClassDef.cls) 
     break; 
    g_masterClassDef.mtd_constructor = g_env->GetMethodID(g_masterClassDef.cls, "<init>", "()V"); 
    g_masterClassDef.mtd_setReference = g_env->GetMethodID(g_masterClassDef.cls, "setReferenceId", "(J)V"); 
    g_masterClassDef.mtd_getReference = g_env->GetMethodID(g_masterClassDef.cls, "referenceId", "()J"); 
    g_masterClassDef.mtd_connect = g_env->GetMethodID(g_masterClassDef.cls, "connect", "(Ljava/lang/String;I)V"); 
    g_masterClassDef.mtd_disconnect = g_env->GetMethodID(g_masterClassDef.cls, "disconnect", "()V"); 
    g_masterClassDef.mtd_cleanup = g_env->GetStaticMethodID(g_masterClassDef.cls, "cleanup", "()V"); 
    OutputDebugString(_T("g_masterClassDef.mtd_cleanup is 0 ? ")); 
    (g_masterClassDef.mtd_cleanup == 0) ? OutputDebugString(_T(" YES")) : OutputDebugString(_T(" no")) ; 

    g_masterClassDef.mtd_sendRegistration = g_env->GetMethodID(g_masterClassDef.cls, "sendRegistrationSignal", "([B)Z"); 
    g_masterClassDef.mtd_sendClinicalStatus = g_env->GetMethodID(g_masterClassDef.cls, "sendClinicalStatusSignal", "([B)Z"); 
    g_masterClassDef.mtd_sendLogDownload = g_env->GetMethodID(g_masterClassDef.cls, "sendLogDownloadSig", "([B)Z"); 
    g_masterClassDef.mtd_sendDeployUpdateInquiry = g_env->GetMethodID(g_masterClassDef.cls, "sendDeployUpdateInquiry", "([B)Z"); 
    g_masterClassDef.mtd_sendTimeSync = g_env->GetMethodID(g_masterClassDef.cls, "sendTimeSync", "([B)Z"); 
    g_masterClassDef.mtd_setIdleTimes = g_env->GetStaticMethodID(g_masterClassDef.cls, "setIdleTimes", "(II)V"); 
    } 

    return flow; 
} 

私は g_masterClassDef.mtd_cleanupが0である参照としての登録が成功したことを知っている - がないのDebugViewで。

C++のコードは次のように呼び出します。

CCommunicationToMedNet::~CCommunicationToMedNet(void) 
{ 
      sapphire_adapter_uninitialize(); 
      d_LoggerWrite(CMediatorLogging::e_Severity_Info, _T("Uninitialized sapphire adaptor")); 
} 

インタフェースクラスSapphireAdapterのsapphire_adapter_uninitializeは()Javaメソッドは到達しませんよう、Javaコードは関係ありません)

SAPPHIRE_DLL_API void sapphire_adapter_uninitialize() 
    { 
     g_env->CallStaticVoidMethod(g_masterClassDef.cls, g_masterClassDef.mtd_cleanup); 
     g_env->DeleteGlobalRef(g_masterClassDef.cls); 
     g_jvm->DestroyJavaVM(); 
     g_jvm = NULL; 
     g_env = NULL; 
     g_pPumpCallbacks = NULL; 
    } 

3です。私が見つけたエラーレポートにさらに探し

Stack: [0x0000000000210000,0x0000000000310000], sp=0x000000000030f260,  free space=1020k 

Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) 
V [jvm.dll+0x31165] 
V [jvm.dll+0x274b86] 
V [jvm.dll+0x212ad2] 
V [jvm.dll+0x32cf42] 
V [jvm.dll+0x212e63] 
V [jvm.dll+0x147a68] 
V [jvm.dll+0x14d608] 
C [SapphireAdapter.dll+0x12bc] 
C [SapphireAdapter.dll+0x169e] 
C [MedNetMediatorService.exe+0xe2746] 
C [MedNetMediatorService.exe+0xe3929] 
C [MedNetMediatorService.exe+0xe9c52] 
C [MSVCR110.dll+0x22fe1] 
C [MedNetMediatorService.exe+0x170616] 
C [kernel32.dll+0x159bd] 
C [ntdll.dll+0x2a2e1] 

4):

Internal exceptions (10 events): 
Event: 0.149 Thread 0x00000000005bf000 Exception <a >'java/lang/ArrayIndexOutOfBoundsException': 22 (0x00000000d7240d58) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u74\6087\hotspot\src\share\vm\interpreter\interpreterRuntime.cpp, line 366] 
Event: 0.150 Thread 0x00000000005bf000 Exception <a 'java/lang/ArrayIndexOutOfBoundsException': 160> (0x00000000d72431a8) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u74\6087\hotspot\src\share\vm\interpreter\interpreterRuntime.cpp, line 366] 

5)は、スタックトレースを見て - コードがJVM方法 解決する方法上の任意のアイデアに到達したことがないようです問題?

答えて

2

mtd_cleanupは静的メソッドであり、したがってCallStaticVoidMethodで呼び出す必要があります。

+0

はい - CallStaticVoidMethodに変更されましたが、クラッシュが発生します。元のコードを更新しました。何か案が? –

+0

@ YaronBerlinsky完全な画像を見ることなく推測するのは難しいです。検証可能な最小限のサンプルを作成し、コンパイルして実行できるようにしてください。 – apangin

関連する問題