lucene-pylucene-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jesper Mattsson <jesper.matts...@modelon.com>
Subject RE: JCCEnv::ExceptionOccurred() returns NULL
Date Mon, 04 Dec 2017 09:59:11 GMT
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:vajda@apache.org]
Sent: den 29 november 2017 21:52
To: pylucene-dev@lucene.apache.org
Cc: Jesper Mattsson <jesper.mattsson@modelon.com>
Subject: Re: JCCEnv::ExceptionOccurred() returns NULL


> On Nov 29, 2017, at 15:42, William Schilp <william.schilp@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" <vajda@apache.org> wrote:
>>
>>
>>> On Nov 28, 2017, at 11:27, William Schilp <william.schilp@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.
Mime
View raw message