Discussion:
JCCEnv::ExceptionOccurred() returns NULL
William Schilp
2017-11-28 14:27:10 UTC
Permalink
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?
Andi Vajda
2017-11-28 17:42:03 UTC
Permalink
Post by William Schilp
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
// 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
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
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.
1. Why does JCCEnv::reportException() throw an int instead of the
jthrowable?
Because throwing object exceptions across DLL boundaries is fraught. Using int is recommended.
Post by William Schilp
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?
If I remember correctly, the exception support requires JCC to be built in shared mode.
Did you build it this way ?

Andi..
William Schilp
2017-11-28 19:09:36 UTC
Permalink
i sort of agree with you. throwing an object through a DLL boundary may be
problematic due to memory allocation/deallocation. but in this case, it's
throwing a pointer (_jthrowable*), which is pretty much the same as
throwing an int...
Post by William Schilp
Post by William Schilp
i'm using JCC in a rather large project where a C++ interface drives a
java
Post by William Schilp
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
Post by William Schilp
C++ interface as well as the JCC interface. with vs2012 i was getting
random problems when trying to extract information from an exception
thrown
Post by William Schilp
by the java application as ExceptionOccurred() would randomly return
NULL..
Post by William Schilp
with vs2015, ExceptionOccurred() always returns NULL. the basic flow was
// 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
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
Post by William Schilp
throw jthrowable;
and then catch the jthrowable in my interface. this appears to work as
the
Post by William Schilp
jthrowable is now non-NULL and i'm able to extract the actual contents of
the exception.
1. Why does JCCEnv::reportException() throw an int instead of the
jthrowable?
Because throwing object exceptions across DLL boundaries is fraught. Using
int is recommended.
Post by William Schilp
2. do you have any idea why the return of JCCEnv::ExceptionOccurred()
would
Post by William Schilp
return non-NULL in reportException() and then in a later catch block
return
Post by William Schilp
NULL?
If I remember correctly, the exception support requires JCC to be built in shared mode.
Did you build it this way ?
Andi..
Andi Vajda
2017-11-28 21:48:06 UTC
Permalink
Post by William Schilp
i sort of agree with you. throwing an object through a DLL boundary may be
problematic due to memory allocation/deallocation. but in this case, it's
throwing a pointer (_jthrowable*), which is pretty much the same as
throwing an int...
Until you free the pointer or something...
But you didn’t answer my question ?

Andi..
Post by William Schilp
Post by William Schilp
Post by William Schilp
i'm using JCC in a rather large project where a C++ interface drives a
java
Post by William Schilp
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
Post by William Schilp
C++ interface as well as the JCC interface. with vs2012 i was getting
random problems when trying to extract information from an exception
thrown
Post by William Schilp
by the java application as ExceptionOccurred() would randomly return
NULL..
Post by William Schilp
with vs2015, ExceptionOccurred() always returns NULL. the basic flow was
// 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
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
Post by William Schilp
throw jthrowable;
and then catch the jthrowable in my interface. this appears to work as
the
Post by William Schilp
jthrowable is now non-NULL and i'm able to extract the actual contents of
the exception.
1. Why does JCCEnv::reportException() throw an int instead of the
jthrowable?
Because throwing object exceptions across DLL boundaries is fraught. Using
int is recommended.
Post by William Schilp
2. do you have any idea why the return of JCCEnv::ExceptionOccurred()
would
Post by William Schilp
return non-NULL in reportException() and then in a later catch block
return
Post by William Schilp
NULL?
If I remember correctly, the exception support requires JCC to be built in shared mode.
Did you build it this way ?
Andi..
William Schilp
2017-11-28 23:24:12 UTC
Permalink
true, but at least in my case, leaking a pointer per exception is not that
big a deal.
i have to contact a team i work with that actually generates the JCC
interface, and they're located in Norway...
Post by Andi Vajda
Post by William Schilp
i sort of agree with you. throwing an object through a DLL boundary may
be
Post by William Schilp
problematic due to memory allocation/deallocation. but in this case, it's
throwing a pointer (_jthrowable*), which is pretty much the same as
throwing an int...
Until you free the pointer or something...
But you didn’t answer my question ?
Andi..
Post by William Schilp
Post by William Schilp
Post by William Schilp
i'm using JCC in a rather large project where a C++ interface drives a
java
Post by William Schilp
application through the JCC interface. the java application makes
considerable use of exceptions (as it should) and the C++ interface
needs
Post by William Schilp
Post by William Schilp
Post by William Schilp
to catch the various exceptions and perform various actions based on
the
Post by William Schilp
Post by William Schilp
Post by William Schilp
exception thrown. unfortunately i have to use visual studio to compile
the
Post by William Schilp
C++ interface as well as the JCC interface. with vs2012 i was getting
random problems when trying to extract information from an exception
thrown
Post by William Schilp
by the java application as ExceptionOccurred() would randomly return
NULL..
Post by William Schilp
with vs2015, ExceptionOccurred() always returns NULL. the basic flow
was
Post by William Schilp
Post by William Schilp
Post by William Schilp
// 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
Post by William Schilp
Post by William Schilp
Post by William Schilp
vs2012, this was annoying but only happened on windows 10 machines.
we've
Post by William Schilp
Post by William Schilp
Post by William Schilp
moved to vs2015, and now ExceptionOccurred() always returns NULL. in
void JCCEnv::reportException() const
{
JNIEnv *vm_env = get_vm_env();
jthrowable throwable = vm_env->ExceptionOccurred(); <---- throwable
is
Post by William Schilp
Post by William Schilp
Post by William Schilp
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
Post by William Schilp
Post by William Schilp
Post by William Schilp
whatever reason, between the break in reportException() at
ExceptionOccurred() and my catch block, whatever is supposed to store
the
Post by William Schilp
Post by William Schilp
Post by William Schilp
jthrowable pointer gets set to NULL.
so i made a change to the throw _EXC_JAVA to throw a copy of the
jthrowable
Post by William Schilp
throw jthrowable;
and then catch the jthrowable in my interface. this appears to work as
the
Post by William Schilp
jthrowable is now non-NULL and i'm able to extract the actual contents
of
Post by William Schilp
Post by William Schilp
Post by William Schilp
the exception.
1. Why does JCCEnv::reportException() throw an int instead of the
jthrowable?
Because throwing object exceptions across DLL boundaries is fraught.
Using
Post by William Schilp
Post by William Schilp
int is recommended.
Post by William Schilp
2. do you have any idea why the return of JCCEnv::ExceptionOccurred()
would
Post by William Schilp
return non-NULL in reportException() and then in a later catch block
return
Post by William Schilp
NULL?
If I remember correctly, the exception support requires JCC to be built
in
Post by William Schilp
Post by William Schilp
shared mode.
Did you build it this way ?
Andi..
William Schilp
2017-11-29 18:42:43 UTC
Permalink
I've added our JCC expert Jesper to this.
Regarding shared mode, we're not quite sure what you mean here, do you mean
dynamically linked runtime libraries(mscrt##.dll)? We use the /MD flag to
visual studio.
Post by William Schilp
Post by William Schilp
i'm using JCC in a rather large project where a C++ interface drives a
java
Post by William Schilp
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
Post by William Schilp
C++ interface as well as the JCC interface. with vs2012 i was getting
random problems when trying to extract information from an exception
thrown
Post by William Schilp
by the java application as ExceptionOccurred() would randomly return
NULL..
Post by William Schilp
with vs2015, ExceptionOccurred() always returns NULL. the basic flow was
// 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
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
Post by William Schilp
throw jthrowable;
and then catch the jthrowable in my interface. this appears to work as
the
Post by William Schilp
jthrowable is now non-NULL and i'm able to extract the actual contents of
the exception.
1. Why does JCCEnv::reportException() throw an int instead of the
jthrowable?
Because throwing object exceptions across DLL boundaries is fraught. Using
int is recommended.
Post by William Schilp
2. do you have any idea why the return of JCCEnv::ExceptionOccurred()
would
Post by William Schilp
return non-NULL in reportException() and then in a later catch block
return
Post by William Schilp
NULL?
If I remember correctly, the exception support requires JCC to be built in shared mode.
Did you build it this way ?
Andi..
Andi Vajda
2017-11-29 20:52:29 UTC
Permalink
Post by William Schilp
I've added our JCC expert Jesper to this.
Regarding shared mode, we're not quite sure what you mean here, do you mean
dynamically linked runtime libraries(mscrt##.dll)? We use the /MD flag to
visual studio.
I mean: build JCC with shared mode enabled (see setup.py) and then build your wrappers with
—shared on JCC command line.

This makes it possible to use multiple jcc-built libraries in the same VM by sharing the jcc runtime among them which is then in its own DLL.

That build mode is required for the exception passing support to work.

Andi..
Post by William Schilp
Post by William Schilp
Post by William Schilp
i'm using JCC in a rather large project where a C++ interface drives a
java
Post by William Schilp
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
Post by William Schilp
C++ interface as well as the JCC interface. with vs2012 i was getting
random problems when trying to extract information from an exception
thrown
Post by William Schilp
by the java application as ExceptionOccurred() would randomly return
NULL..
Post by William Schilp
with vs2015, ExceptionOccurred() always returns NULL. the basic flow was
// 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
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
Post by William Schilp
throw jthrowable;
and then catch the jthrowable in my interface. this appears to work as
the
Post by William Schilp
jthrowable is now non-NULL and i'm able to extract the actual contents of
the exception.
1. Why does JCCEnv::reportException() throw an int instead of the
jthrowable?
Because throwing object exceptions across DLL boundaries is fraught. Using
int is recommended.
Post by William Schilp
2. do you have any idea why the return of JCCEnv::ExceptionOccurred()
would
Post by William Schilp
return non-NULL in reportException() and then in a later catch block
return
Post by William Schilp
NULL?
If I remember correctly, the exception support requires JCC to be built in shared mode.
Did you build it this way ?
Andi..
Jesper Mattsson
2017-12-04 09:59:11 UTC
Permalink
Dear Andi,

Please note that we are not using Python at all when using the wrappers - we use the generated C++ classes directly in a C++ program. The documentation says that you need --shared to be able to load several JCC wrapper libraries at the same time, and to be able to call Python from Java - do you also need it to throw exceptions from Java to C++?

Does --shared affect the generated code? We do not use the --build or --install flags, since we do not need a Python extension. Looking at python.py, it looks like it (for the C++ wrappers) should be enough to build a DLL from jcc.cpp & JCCEnv.cpp, exclude them from the .lib and then link against the DLL as well. Is that correct?

Jesper

-----Original Message-----
From: Andi Vajda [mailto:***@apache.org]
Sent: den 29 november 2017 21:52
To: pylucene-***@lucene.apache.org
Cc: Jesper Mattsson <***@modelon.com>
Subject: Re: JCCEnv::ExceptionOccurred() returns NULL
Post by William Schilp
I've added our JCC expert Jesper to this.
Regarding shared mode, we're not quite sure what you mean here, do you
mean dynamically linked runtime libraries(mscrt##.dll)? We use the /MD
flag to visual studio.
I mean: build JCC with shared mode enabled (see setup.py) and then build your wrappers with —shared on JCC command line.

This makes it possible to use multiple jcc-built libraries in the same VM by sharing the jcc runtime among them which is then in its own DLL.

That build mode is required for the exception passing support to work.

Andi..
Post by William Schilp
Post by William Schilp
Post by William Schilp
i'm using JCC in a rather large project where a C++ interface drives a
java
Post by William Schilp
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
Post by William Schilp
C++ interface as well as the JCC interface. with vs2012 i was
C++ getting
random problems when trying to extract information from an exception
thrown
Post by William Schilp
by the java application as ExceptionOccurred() would randomly return
NULL..
Post by William Schilp
with vs2015, ExceptionOccurred() always returns NULL. the basic flow was
// 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
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
Post by William Schilp
throw jthrowable;
and then catch the jthrowable in my interface. this appears to work as
the
Post by William Schilp
jthrowable is now non-NULL and i'm able to extract the actual
contents of the exception.
1. Why does JCCEnv::reportException() throw an int instead of the
jthrowable?
Because throwing object exceptions across DLL boundaries is fraught.
Using int is recommended.
Post by William Schilp
2. do you have any idea why the return of
JCCEnv::ExceptionOccurred()
would
Post by William Schilp
return non-NULL in reportException() and then in a later catch block
return
Post by William Schilp
NULL?
If I remember correctly, the exception support requires JCC to be built in shared mode.
Did you build it this way ?
Andi..
This email and any attachments are intended solely for the use of the individual or entity to whom it is addressed and may be confidential and/or privileged. If you are not one of the named recipients or have received this email in error, (i) you should not read, disclose, or copy it, (ii) please notify sender of your receipt by reply email and delete this email and all attachments, (iii) Modelon does not accept or assume any liability or responsibility for any use of or reliance on this
Andi Vajda
2017-12-04 13:44:35 UTC
Permalink
Hi Jesper,

(Please subscribe to pylucene-dev so that I don't have to moderate you in
every time).
Post by Jesper Mattsson
Please note that we are not using Python at all when using the wrappers -
we use the generated C++ classes directly in a C++ program. The
documentation says that you need --shared to be able to load several JCC
wrapper libraries at the same time, and to be able to call Python from
Java - do you also need it to throw exceptions from Java to C++?
You do need --shared to load multiple JCC built libraries into the same Java
VM, regardless of whether you're using python or not.

Looking at the sources, I see at line 544 in JCCEnv.cpp, in the
reportException() method that to report a _python_ exception from a Java
error, a PythonException _java_ class is necessary. That class is only
available when using --shared mode.

You are not using python, thus the --shared question is moot as applied to
the exception issue. To answer your original question, I do not know why
exception reporting is behaving like you're seeing - only a debugging
session with JCC built with DEBUG mode enabled and a real debugger is going
to help tell. I do not have access to Windows at all so I can't help with
debugging this myself.
Post by Jesper Mattsson
Does --shared affect the generated code? We do not use the --build or
--install flags, since we do not need a Python extension. Looking at
python.py, it looks like it (for the C++ wrappers) should be enough to
build a DLL from jcc.cpp & JCCEnv.cpp, exclude them from the .lib and then
link against the DLL as well. Is that correct?
See my response above. Using --shared changes how things are linked and
initialized at runtime, not the generated code itself.

Andi..
Post by Jesper Mattsson
Jesper
-----Original Message-----
Sent: den 29 november 2017 21:52
Subject: Re: JCCEnv::ExceptionOccurred() returns NULL
Post by William Schilp
I've added our JCC expert Jesper to this.
Regarding shared mode, we're not quite sure what you mean here, do you
mean dynamically linked runtime libraries(mscrt##.dll)? We use the /MD
flag to visual studio.
I mean: build JCC with shared mode enabled (see setup.py) and then build your wrappers with ?shared on JCC command line.
This makes it possible to use multiple jcc-built libraries in the same VM by sharing the jcc runtime among them which is then in its own DLL.
That build mode is required for the exception passing support to work.
Andi..
Post by William Schilp
Post by William Schilp
Post by William Schilp
i'm using JCC in a rather large project where a C++ interface drives a
java
Post by William Schilp
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
Post by William Schilp
C++ interface as well as the JCC interface. with vs2012 i was
C++ getting
random problems when trying to extract information from an exception
thrown
Post by William Schilp
by the java application as ExceptionOccurred() would randomly return
NULL..
Post by William Schilp
with vs2015, ExceptionOccurred() always returns NULL. the basic flow was
// 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
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
Post by William Schilp
throw jthrowable;
and then catch the jthrowable in my interface. this appears to work as
the
Post by William Schilp
jthrowable is now non-NULL and i'm able to extract the actual
contents of the exception.
1. Why does JCCEnv::reportException() throw an int instead of the
jthrowable?
Because throwing object exceptions across DLL boundaries is fraught.
Using int is recommended.
Post by William Schilp
2. do you have any idea why the return of
JCCEnv::ExceptionOccurred()
would
Post by William Schilp
return non-NULL in reportException() and then in a later catch block
return
Post by William Schilp
NULL?
If I remember correctly, the exception support requires JCC to be built in shared mode.
Did you build it this way ?
Andi..
This email and any attachments are intended solely for the use of the individual or entity to whom it is addressed and may be confidential and/or privileged. If you are not one of the named recipients or have received this email in error, (i) you should not read, disclose, or copy it, (ii) please notify sender of your receipt by reply email and delete this email and all attachments, (iii) Modelon does not accept or assume any liability or responsibility for any use of or reliance on this email.
Loading...