Hi Jesper,

(Please subscribe to pylucene-dev so that I don't have to moderate you in every time).

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.

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..


Jesper

-----Original Message-----
From: Andi Vajda [mailto:va...@apache.org]
Sent: den 29 november 2017 21:52
To: pylucene-dev@lucene.apache.org
Cc: Jesper Mattsson <jesper.matts...@modelon.com>
Subject: Re: JCCEnv::ExceptionOccurred() returns NULL


On Nov 29, 2017, at 15:42, William Schilp <william.sch...@ansys.com> wrote:

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..


On Nov 28, 2017 12:42, "Andi Vajda" <va...@apache.org> wrote:


On Nov 28, 2017, at 11:27, William Schilp <william.sch...@ansys.com>
wrote:

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
C++ 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?

Because throwing object exceptions across DLL boundaries is fraught.
Using int is recommended.

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..




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.

Reply via email to