William Schilp
2017-11-28 14:27:10 UTC
i'm using JCC in a rather large project where a C++ interface drives a java
application through the JCC interface. the java application makes
considerable use of exceptions (as it should) and the C++ interface needs
to catch the various exceptions and perform various actions based on the
exception thrown. unfortunately i have to use visual studio to compile the
C++ interface as well as the JCC interface. with vs2012 i was getting
random problems when trying to extract information from an exception thrown
by the java application as ExceptionOccurred() would randomly return NULL..
with vs2015, ExceptionOccurred() always returns NULL. the basic flow was
this:
// setup the JNI interface, which returns a pointer to the JNIenv
JNIEnv* jniEnv = setupJNIenv();
_jthrowable* jException = NULL;
try
{
<call something via JCC which fails throwing an exception in the java
code>;
}
catch(_EXC_JAVA jErr);
{
_jthrowable* jException = jniEnv->ExceptionOccurred(); <--- in vs2012
this randomly returns NULL for exceptions that are caught
}
if(jException != NULL)
{
<do something for exception>
as noted, ExceptionOccurred() would randomly return NULL when built with
vs2012, this was annoying but only happened on windows 10 machines. we've
moved to vs2015, and now ExceptionOccurred() always returns NULL. in
debugging this issue i put a break in JCCEnv::reportException():
void JCCEnv::reportException() const
{
JNIEnv *vm_env = get_vm_env();
jthrowable throwable = vm_env->ExceptionOccurred(); <---- throwable is
not NULL here...
if (throwable)
{
if (!env->handlers)
vm_env->ExceptionDescribe();
// python code removed
}
throw _EXC_JAVA;
}
when i break at vm_env->ExceptionOccurred() it returns a non-NULL
throwable. then when i break in my catch block: catch(_EXC_JAVA)...
and look at the return value for ExceptionOccurred() it returns NULL. for
whatever reason, between the break in reportException() at
ExceptionOccurred() and my catch block, whatever is supposed to store the
jthrowable pointer gets set to NULL.
so i made a change to the throw _EXC_JAVA to throw a copy of the jthrowable
as such:
throw jthrowable;
and then catch the jthrowable in my interface. this appears to work as the
jthrowable is now non-NULL and i'm able to extract the actual contents of
the exception.
my questions:
1. Why does JCCEnv::reportException() throw an int instead of the
jthrowable?
2. do you have any idea why the return of JCCEnv::ExceptionOccurred() would
return non-NULL in reportException() and then in a later catch block return
NULL?
application through the JCC interface. the java application makes
considerable use of exceptions (as it should) and the C++ interface needs
to catch the various exceptions and perform various actions based on the
exception thrown. unfortunately i have to use visual studio to compile the
C++ interface as well as the JCC interface. with vs2012 i was getting
random problems when trying to extract information from an exception thrown
by the java application as ExceptionOccurred() would randomly return NULL..
with vs2015, ExceptionOccurred() always returns NULL. the basic flow was
this:
// setup the JNI interface, which returns a pointer to the JNIenv
JNIEnv* jniEnv = setupJNIenv();
_jthrowable* jException = NULL;
try
{
<call something via JCC which fails throwing an exception in the java
code>;
}
catch(_EXC_JAVA jErr);
{
_jthrowable* jException = jniEnv->ExceptionOccurred(); <--- in vs2012
this randomly returns NULL for exceptions that are caught
}
if(jException != NULL)
{
<do something for exception>
as noted, ExceptionOccurred() would randomly return NULL when built with
vs2012, this was annoying but only happened on windows 10 machines. we've
moved to vs2015, and now ExceptionOccurred() always returns NULL. in
debugging this issue i put a break in JCCEnv::reportException():
void JCCEnv::reportException() const
{
JNIEnv *vm_env = get_vm_env();
jthrowable throwable = vm_env->ExceptionOccurred(); <---- throwable is
not NULL here...
if (throwable)
{
if (!env->handlers)
vm_env->ExceptionDescribe();
// python code removed
}
throw _EXC_JAVA;
}
when i break at vm_env->ExceptionOccurred() it returns a non-NULL
throwable. then when i break in my catch block: catch(_EXC_JAVA)...
and look at the return value for ExceptionOccurred() it returns NULL. for
whatever reason, between the break in reportException() at
ExceptionOccurred() and my catch block, whatever is supposed to store the
jthrowable pointer gets set to NULL.
so i made a change to the throw _EXC_JAVA to throw a copy of the jthrowable
as such:
throw jthrowable;
and then catch the jthrowable in my interface. this appears to work as the
jthrowable is now non-NULL and i'm able to extract the actual contents of
the exception.
my questions:
1. Why does JCCEnv::reportException() throw an int instead of the
jthrowable?
2. do you have any idea why the return of JCCEnv::ExceptionOccurred() would
return non-NULL in reportException() and then in a later catch block return
NULL?