ExceptionClear does not work as expected

Hi,

I am wanting to conditionally handle an exception occurring in a general

callback from native code to a java method. My approach is to

query env->ExceptionOccurred() and then if found, call env->ExceptionClear()

to temporarily deactivate the exception, but save a global reference to

the exception. If my handling code does not handle it, then ultimately

I want to call env->Throw() on the global reference to the originally obtained

excetion from ExceptionOccurred().

The problem is that ExceptionClear() seems to destroy the exception object,

and though env->Throw() does not complain, the java application appears to

have thrown a java.lang.Object!!! Apparantly ExceptionClear() destroys the

original exception.

How for example, am I going to be able to wrap the exception in another

exception and throw that if ExceptionClear() destroys the original? Is this

a bug in the JVM? Should I report it to Sun? Or is there an alternative

to ExceptionClear() that allows me to keep the original exception and wrap it.

Andy

[1137 byte] By [p7ea] at [2007-10-3 0:40:52]
# 1
The problem must be in your code somewhere.I did a simple test and it worked perfectly.You will have to be more specific (show your relevant code between code tags for instance) if you want more help.Regards
jfbrierea at 2007-7-14 17:35:05 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 2

You're right! I tried dumming down my code to match what I think you did

and then it worked for me. In essence, what I was originally doing is:

1. calling ExceptionOccurred() to get "t"

2. calling ExceptionClear()

3. calling gt = NewGlobalRef(t)

4. DeleteLocalRef(t)

5. creating a new C++ struct wrapper for gt with a destructor

that DeleteLocalRef(gt-member)

6. throwing that struct as a C++ exception

7. catching that C++ struct as a reference

8. in the catch code, calling env->Throw(mystruct.gt)

9. return 0 from the native function

allowing the destructor for the C++ call to fire at will and call

DeleteGlobalRef(gt-member)

that last DeleteGlobalRef in the destructor of the C++ wrapper was the

problem. Something weird about my C++ compiler, because when I remove

it from the destructor and do it explicitly as step 10, everything is ok.

Thanks again,

Andy

p7ea at 2007-7-14 17:35:05 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 3

Don't blame the compiler too much. I am in the same boat, and I also protect the exception with a global ref, then clear the exception, yet I can get the JVM to crash during GC in the VMThread with 1.5_09, and it looks like it's fixed in 1.6. So, first look at the hs* file generated to see where you crash, before you blame the compiler.

sanokistokaa at 2007-7-14 17:35:05 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 4

Just at a guess I'd wonder if you need a proper copy constructor for your struct. You need to make sure that the destructor that deletes the global ref isn't being executed multiple times because there are intermediate copies of the struct are being created by the compiler. Your constructor and destructor should really be symmetric. Test your code using -Xcheck:jni and it should complain if you are deleting the global ref multiple times.

tom

neverevera at 2007-7-14 17:35:05 > top of Java-index,Java HotSpot Virtual Machine,Specifications...