Java 在Windows7中调用JNIDLL时Tomcat崩溃

Java 在Windows7中调用JNIDLL时Tomcat崩溃,java,dll,windows-7,java-native-interface,openssl,Java,Dll,Windows 7,Java Native Interface,Openssl,我有一个Java web应用程序,它使用tomcat 7,调用JNI dll,使用Openssl EVP解密一些数据 当在WindowsXP上运行时,一切正常,但当我尝试在Windows7上运行时,它崩溃了 tomcat stdout.log: 2013-07-07 14:23:33 Commons Daemon procrun stdout initialized # # A fatal error has been detected by the Java Runtime Environme

我有一个Java web应用程序,它使用tomcat 7,调用JNI dll,使用Openssl EVP解密一些数据

当在WindowsXP上运行时,一切正常,但当我尝试在Windows7上运行时,它崩溃了

tomcat stdout.log:

2013-07-07 14:23:33 Commons Daemon procrun stdout initialized
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x77b42b79, pid=3576, tid=1528
#
# JRE version: 6.0_18-b07
# Java VM: Java HotSpot(TM) Client VM (16.0-b13 mixed mode, sharing windows-x86 )
# Problematic frame:
# C  [ntdll.dll+0x52b79]
#
# An error report file with more information is saved as:
# C:\Windows\system32\hs_err_pid3576.log
#
# If you would like to submit a bug report, please visit:
#   http://java.sun.com/webapps/bugreport/crash.jsp
#
applicationContext.xml]
[2013-07-07 14:23:52,025] INFO  [org.springframework.beans.factory.xml.XmlBeanDefinitionReader] - Loading XML bean definitions from ServletContext resource [/WEB-INF/conf/spring/applicationContext-dataSource.xml]
[2013-07-07 14:23:52,119] INFO  [org.springframework.beans.factory.xml.XmlBeanDefinitionReader] - Loading XML bean definitions from ServletContext resource [/WEB-INF/conf/spring/applicationContext-manageable.xml]
[2013-07-07 14:23:52,228] INFO  [org.springframework.beans.factory.xml.XmlBeanDefinitionReader] - Loading XML bean definitions from ServletContext resource [/WEB-INF/conf/spring/applicationContext-security.xml]
[2013-07-07 14:23:52,930] INFO  [org.springframework.security.core.SpringSecurityCoreVersion] - You are running with Spring Security Core 3.0.5.RELEASE
[2013-07-07 14:23:52,930] INFO  [org.springframework.security.config.SecurityNamespaceHandler] - Spring Security 'config' module version is 3.0.5.RELEASE
[2013-07-07 14:23:53,148] INFO  [org.springframework.security.config.http.HttpSecurityBeanDefinitionParser] - ncyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null, order = 1800, <org.springframework.security.web.access.intercept.FilterSecurityInterceptor#0>, order = 1900]
jni dll名称为:myDLL.dll 函数是:myApp.d()

以下是生成dll的c程序中的myApp.d()函数:

JNIEXPORT jbyteArray JNICALL Java_myApp_d(JNIEnv *env, jobject obj, jbyteArray b)
    {
        EVP_CIPHER_CTX en, de;

        // get length of bytes
        int srcLen=(*env)->GetArrayLength(env, b);

        //convert jbyteArray to byte []
        jbyte data[srcLen];
        (*env)->GetByteArrayRegion(env, b, 0, srcLen, data);
        (*env)->ReleaseByteArrayElements(env, b, data , 0);

        unsigned int salt[] = {12345, 54321};
        unsigned char key_data[16]={ 'A','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p'};

    int key_data_len = 16;


    if (aes_init(key_data, key_data_len, (unsigned char *)&salt, &en, &de))
    {
        printf("Couldn't initialize AES cipher\n");
        return -1;
    }

    unsigned char* indata=(unsigned char*)data;
    char *plaintext;
    int olen, len;
    int j;


    char tampon[16];

    for(j=0; j<16; j++)
    {
        tampon[j]=indata[j];
    }

    int desLen;

    sscanf(tampon,"%d",&desLen);

    unsigned char indataB[srcLen-16];

    for(j=0; j<srcLen-16; j++)
    {
        indataB[j]=indata[16+j];
    }

    olen = len = srcLen-16+1;


    plaintext = (char *)aes_decrypt(&de, indataB, &len);

    jbyteArray bArray = (*env)->NewByteArray(env, desLen);
    jboolean isCopy = JNI_TRUE;
    jbyte* decrypteddata = (jbyte *)(*env)->GetByteArrayElements(env, bArray, &isCopy);
    memcpy(decrypteddata, plaintext, desLen);
    (*env)->ReleaseByteArrayElements(env, bArray, decrypteddata, 0);



    free(plaintext);
    free(decrypteddata);

    EVP_CIPHER_CTX_cleanup(&en);
    EVP_CIPHER_CTX_cleanup(&de);

    return bArray;

    (*env)->DeleteLocalRef(env, bArray );
}
我怀疑这一部分允许将数据从char*复制到jbytearray:

    jbyte* decrypteddata = (jbyte *)(*env)->GetByteArrayElements(env, bArray, &isCopy);
memcpy(decrypteddata, plaintext, desLen);
(*env)->ReleaseByteArrayElements(env, bArray, decrypteddata, 0);
我试图用GetPrimitiveArrayCritical替换GetByTearArrayElements,用ReleasePrimitiveArrayCritical替换GetByTearElements,但没有成功。

[已解决]

正如我在问题中所想,问题是由调用这两个JNI函数引起的:

    (*env)->GetByteArrayRegion(env, b, 0, srcLen, data);
    (*env)->ReleaseByteArrayElements(env, b, data , 0);
我将其替换为:

jbyte* d = (*env)->GetByteArrayElements(env, b, &isCopyS);

int i;

for(i = 0; i < srcLen; i++)
{
    data[i] = d[i];
}

(*env)->ReleaseByteArrayElements(env, b, d, JNI_ABORT);
jbyte*d=(*env)->GetByteArrayElements(env、b和isCopyS);
int i;
对于(i=0;i按技术要求发布(env、b、d、JNI_中止);
现在它可以在WindowsXP和Windows7中使用

    (*env)->GetByteArrayRegion(env, b, 0, srcLen, data);
    (*env)->ReleaseByteArrayElements(env, b, data , 0);
jbyte* d = (*env)->GetByteArrayElements(env, b, &isCopyS);

int i;

for(i = 0; i < srcLen; i++)
{
    data[i] = d[i];
}

(*env)->ReleaseByteArrayElements(env, b, d, JNI_ABORT);