Native to Java crash on JNI
<p>I have a windows service running C++ that calls Java via JNI.</p>

<p>When stopping the service using windows service manager the service crashes.</p>

<p>C++ registers to JNI the following:</p>

<pre><code> 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 = &amp;options[0];
    vm_args.ignoreUnrecognized = 0;
    jint res = JNI_CreateJavaVM(&amp;g_jvm, (void **)&amp;g_env, &amp;vm_args);
    if (res != 0)
    {
        jint result = JNI_GetCreatedJavaVMs(&amp;g_jvm, 1, NULL);
        if(result != JNI_OK)
            break;
        result = g_jvm-&gt;GetEnv((void**)&amp;g_env, JNI_VERSION_1_8);
    }
    if (! g_masterClassDef.cls)
        g_masterClassDef.cls = (jclass)g_env-&gt;NewGlobalRef(g_env-&gt;FindClass("com/hospira/sapphire/adapter/SapphireAdapter"));
    if (! g_masterClassDef.cls)
        break;
    g_masterClassDef.mtd_constructor = g_env-&gt;GetMethodID(g_masterClassDef.cls, "&lt;init&gt;", "()V");
    g_masterClassDef.mtd_setReference = g_env-&gt;GetMethodID(g_masterClassDef.cls, "setReferenceId", "(J)V");
    g_masterClassDef.mtd_getReference = g_env-&gt;GetMethodID(g_masterClassDef.cls, "referenceId", "()J");
    g_masterClassDef.mtd_connect = g_env-&gt;GetMethodID(g_masterClassDef.cls, "connect", "(Ljava/lang/String;I)V");
    g_masterClassDef.mtd_disconnect = g_env-&gt;GetMethodID(g_masterClassDef.cls, "disconnect", "()V");
    g_masterClassDef.mtd_cleanup = g_env-&gt;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-&gt;GetMethodID(g_masterClassDef.cls, "sendRegistrationSignal", "([B)Z");
    g_masterClassDef.mtd_sendClinicalStatus = g_env-&gt;GetMethodID(g_masterClassDef.cls, "sendClinicalStatusSignal", "([B)Z"); 
    g_masterClassDef.mtd_sendLogDownload = g_env-&gt;GetMethodID(g_masterClassDef.cls, "sendLogDownloadSig", "([B)Z"); 
    g_masterClassDef.mtd_sendDeployUpdateInquiry = g_env-&gt;GetMethodID(g_masterClassDef.cls, "sendDeployUpdateInquiry", "([B)Z");
    g_masterClassDef.mtd_sendTimeSync = g_env-&gt;GetMethodID(g_masterClassDef.cls, "sendTimeSync", "([B)Z");
    g_masterClassDef.mtd_setIdleTimes = g_env-&gt;GetStaticMethodID(g_masterClassDef.cls, "setIdleTimes", "(II)V");
   }

    return flow;
}
</code></pre>

<p>I know that the registration is successful as I see 
g_masterClassDef.mtd_cleanup is 0 - no in  DebugView.</p>

<p>The C++ code calls the following:</p>

<pre><code>CCommunicationToMedNet::~CCommunicationToMedNet(void)
{
          sapphire_adapter_uninitialize();
          d_LoggerWrite(CMediatorLogging::e_Severity_Info, _T("Uninitialized sapphire adaptor"));
}
</code></pre>

<p>The interface class SapphireAdapter sapphire_adapter_uninitialize() is</p>

<pre><code>   SAPPHIRE_DLL_API void sapphire_adapter_uninitialize()
   {
        g_env-&gt;CallStaticVoidMethod(g_masterClassDef.cls,  g_masterClassDef.mtd_cleanup);
        g_env-&gt;DeleteGlobalRef(g_masterClassDef.cls);
        g_jvm-&gt;DestroyJavaVM();
        g_jvm = NULL;
        g_env = NULL;
        g_pPumpCallbacks = NULL;
  }
</code></pre>

<p>3) The Java code does not matter as the Java method is never reached.</p>

<pre><code>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]
</code></pre>

<p>4) Looking further in the error report I found:</p>

<pre><code>Internal exceptions (10 events):
Event: 0.149 Thread 0x00000000005bf000 Exception &lt;a &gt;'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 &lt;a 'java/lang/ArrayIndexOutOfBoundsException': 160&gt; (0x00000000d72431a8) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u74\6087\hotspot\src\share\vm\interpreter\interpreterRuntime.cpp, line 366]
</code></pre>

<p>5)Looking at the stack trace – it seems that the code never reaches the JVM method
any ideas on how to resolve the issue? </p>