lucene-pylucene-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Andi Vajda <va...@apache.org>
Subject Re: throwing an exception *through* Java?
Date Mon, 27 Sep 2010 18:37:28 GMT

On Sep 27, 2010, at 11:17, Bill Janssen <janssen@parc.com> wrote:

> Andi Vajda <vajda@apache.org> wrote:
>
>> On Sat, 25 Sep 2010, Bill Janssen wrote:
>>
>>> Andi Vajda <vajda@apache.org> wrote:
>>>
>>>> On Sep 25, 2010, at 13:54, Bill Janssen <janssen@parc.com> wrote:
>>>>
>>>>> I've got a subclass of PythonMultiFieldQueryParser.  I'd like to  
>>>>> be
>>>>> able
>>>>> to throw a custom Python exception with parameters in that code,  
>>>>> and
>>>>> catch it in the Python code that's using it.  To do this, the
>>>>> exception
>>>>> has to somehow travel through Java.  I thought I could perhaps
>>>>> subclass
>>>>> PythonException to do this, but it looks like that's not really an
>>>>> extension class.
>>>>>
>>>>> How to do this?
>>>>
>>>> Have you tried just throwing your exception ? It should be picked  
>>>> up
>>>> at the JVM crossing point and thrown on in some form back to  
>>>> Python,
>>>> no ?
>>>
>>> Yep, it shows up again in Python as a JavaError, but the error  
>>> type and
>>> any arguments associated with it have been stripped out.  I'm  
>>> trying to
>>> use it to communicate a really exceptional condition, and I need  
>>> that
>>> info.
>>
>> The error reporting code is a bit tricky but if you're using shared  
>> mode -
>> the mode where the PythonException java class exists since it's part
>> of the JCC runtime shared library - a Python exception reported in an
>> extension class _should_ cross the VM boundaries back and forth (to
>> Java and then back to the original caller in Python) unadultered  
>> since
>> - unless there is a bug somewhere along the way - the Python error
>> state is not cleared until the stack has unwound to original call in
>> the Python interpreter.
>
> You mean sys.exc_info() here?  Wouldn't that be clobbered by the
> JavaError thrown by the JVM code?  Ah, but the JavaError I'm actually
> seeing shouldn't be thrown at all.
>
>> The error you raise from your Python code is detected by the NULL
>> return value in the C++ extension code (JCC-generated) that calls  
>> your
>> method. That NULL return value is then reported on to Java by  
>> throwing
>> a PythonException Java exception (line 1087 in functions.cpp).
>>
>> This Java exception is then caught by one the call<something> macros
>> in JCCENv.cpp (line 447) which calls reportException() - in other
>> words, after every JNI method call, reportException() is called to
>> check for an exception raised in the JVM.
>>
>> reportException(), JCCEnv.cpp line 407, checks to see if there is an
>> exception thrown in the JVM, checks it against PythonException and if
>> so throws the _EXC_PYTHON C++ exception which is turned into a NULL
>> return value by one of the OBJ_CALL()/INT_CALL() macros in macros.h,
>> line 17, which wrap every C++ call from Python (these macros also
>> release the GIL for the time of the call).
>>
>> In other words, unless there is a bug or you're not using shared  
>> mode,
>> your Python exception state should not be getting lost. Then, I could
>> be missing something here, this code is a bit hairy as it uses three
>> language exception systems together across shared libraries.
>
> Wonderfully twisty, but I follow.
>
>> Note also that there was a bug with this code in throwing C++
>> exception objects across shared libraries that I fixed in the latest
>> JCC by just throwing ints instead of C++ exception objects. If you're
>> not using the latest JCC release, you may be hitting this bug too.
>
> That could be it.  I believe I'm using 2.9.3.  Is the fix in 3.0.2?

2.9.3, 3.0.2, 3.x and trunk all use jcc 2.6 so you should have that  
fix. Are you using shared mode ? (if you're seeing a java  
RuntimeException thrown, the answer is probably not).

Andi..

>
> Bill

Mime
View raw message