Calling throwNew 2 times cause hotspot to crash

I've been running into a problem in my program where it would crash if we

happened to call throwNew 2 times in a row (from different invocations of

a native method). I have been able to reproduce this in a very simple test case.

basically I have code which does the following in Java:

for (int i = 0; i < 2; i++){

try{

jniException.loadLib(args[0]);

}

catch(Exception e){

e.printStackTrace();

}

}

In my native code I do the following:

(*env)->ExceptionClear(env);

throwJavaException(env,"Throw test error");

The throwJavaException function is as follows:

static jboolean throwJavaException(JNIEnv* env,const char* err)

{

static jclass clz = NULL;

jboolean ret = JNI_TRUE;

// see if we have gotten the class yet

if (clz == NULL)

{

// nope, clear any existing exceptions

(*env)->ExceptionClear(env);

// Find the exception class

clz = (*env)->FindClass(env,"java/lang/Exception");

// again clear any exceptions created by the above

(*env)->ExceptionClear(env);

if (clz == NULL)

{

// We did not get the class, fail

ret = JNI_FALSE;

}

}

if (ret == JNI_TRUE)

{

// Everything is OK, throw the exception

if ((*env)->ThrowNew(env, clz, err) != 0)

{

// eek - failed. now what?!!

ret = JNI_FALSE;

}

}

return ret;

}

When I run this code I get the following output:

C:\Documents and Settings\jmars\workspace-jnitest\jni_exp>java jniException nosuchlib

java.lang.Exception: Throw test error

at jniException.loadLib(Native Method)

at jniException.main(jniException.java:28)

#

# An unexpected error has been detected by HotSpot Virtual Machine:

#

# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x6d6baad0, pid=10056, tid=492

#

# Java VM: Java HotSpot(TM) Client VM (1.5.0_10-b03 mixed mode, sharing)

# Problematic frame:

# V [jvm.dll+0x8aad0]

#

# An error report file with more information is saved as hs_err_pid10056.log

#

# If you would like to submit a bug report, please visit:

#http://java.sun.com/webapps/bugreport/crash.jsp

#

C:\Documents and Settings\jmars\workspace-jnitest\jni_exp>notepad hs_err_pid10056.log

As you can see the first exception is caught and printed, but the second call causes the VM to crash.

Any ideas what I might be doing wrong?

I have this simple example and I can send it to you to look at if you want.

Thanks

[3790 byte] By [jim.marshalla] at [2007-11-26 17:58:33]
# 1
Hi Jim,I have run into the same problem today. It seems to it helps if you just remove static from this line: static jclass clz = NULL;. So everytime you will use FindClass emthod for finding class.Hopefully it helpedHappy coding
OndrashXa at 2007-7-9 5:11:52 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 2

Hi Jim,

the previous poster was right that removin the "static" from jclass clz will work, but if you know the reason, you will find another solution.

The jclass returned from FindClass is a reference to a java.lang.Class object. It is a so called local rerefence which means, that it gets freed when the JNI call returns. So after calling your throwJavaException for the first time you end up with a value in clz which is an invalid local reference.

One solution is of course to acquire the clz each time. Another solution would be to create a global reference and to store that in clz:

jclass clz = (jclass)(*env)->NewGlobalRef(env, (*env)->FindClass(env, "java/lang/Exception")));

This clz value is then valid during multiple JNI invocations. To clean up, you should however delete this global reference when the Java class owning the JNI code gets unloaded, i.e. in a finalizer.

Hope this helps and makes things clearer.

Martin

martin@worka at 2007-7-9 5:11:52 > top of Java-index,Java HotSpot Virtual Machine,Specifications...