On May 7, 2013, at 21:31, Andi Vajda <va...@apache.org> wrote:

> 
> On May 7, 2013, at 19:40, Barry Wark <ba...@physion.us> wrote:
> 
>> On Tue, May 7, 2013 at 1:15 PM, Andi Vajda <va...@apache.org> wrote:
>> 
>>> 
>>> On May 7, 2013, at 9:03, Barry Wark <ba...@physion.us> wrote:
>>> 
>>>> Andi, thank you for the great info!
>>>> 
>>>> 
>>>> On Tue, May 7, 2013 at 11:58 AM, Andi Vajda <va...@apache.org> wrote:
>>>> 
>>>>> 
>>>>> On Tue, 7 May 2013, Barry Wark wrote:
>>>>> 
>>>>> I recently discovered JCC (awesome project!) and am attempting to use it
>>>>>> to
>>>>>> wrap a Java API for Python users. It's been working great, with two
>>>>>> exceptions. I'd be grateful for any advice on the following:
>>>>>> 
>>>>>> 1) Public methods from implemented interfaces are not wrapped
>>>>>> 
>>>>>> We have where (public) methods of interfaces are not wrapped. Here's a
>>> toy
>>>>>> example:
>>>>>> 
>>>>>> package us.physion.mixin;
>>>>>> public interface MixinA {
>>>>>> void mixinMethodA(String);
>>>>>> }
>>>>>> 
>>>>>> public interface MixinB {
>>>>>> void mixinMethodB(String);
>>>>>> }
>>>>>> 
>>>>>> 
>>>>>> package us.physion.domain;
>>>>>> public interface Entity extends us.physion.mixin.MixinA,
>>>>>> us.physion.mixin.MixinB
>>>>>> {
>>>>>> void entityMethod();
>>>>>> }
>>>>>> 
>>>>>> public interface MyClass extends Entity
>>>>>> 
>>>>>> package us.physion.domain.impl;
>>>>>> public class EnityBase implements us.physion.domain.Entity {
>>>>>> }
>>>>>> 
>>>>>> public class MyClass extends EntityBase implements
>>>>>> us.physion.domain.MyClass {
>>>>>> }
>>>>>> 
>>>>>> MyClass is wrapped correctly, and exposes entityMethod. However, the
>>>>>> mixinMethodA and mixinMethodB aren't exposed. We get an AttributeError
>>>>>> when
>>>>>> calling mixinMethodA on a MyClass instance:
>>>>>> 
>>>>>> In [10]: myInstance = MyClass()
>>>>>> In [11]: myInstance.mixinMethodA()
>>>>>> ------------------------------**------------------------------**
>>>>>> ---------------
>>>>>> AttributeError                            Traceback (most recent call
>>>>>> last)
>>>>>> <ipython-input-10-**51f1cf2e8c2d> in <module>()
>>>>>> ----> 1 myInstance.mixinMethodA('foo')
>>>>>> 
>>>>>> AttributeError: 'MyClass' object has no attribute 'mixinMethodA'
>>>>>> 
>>>>>> The issue may or may not be related to the second issue of name
>>>>>> collisions.
>>>>> 
>>>>> You can access these mixin methods by casting to the owning interface:
>>>>> 
>>>>> MixinA.cast_(myInstance).**mixinMethodA('foo')
>>>>> 
>>>>> The cast_() here function rewraps your Java object with a wrapper for
>>> the
>>>>> MixinA interface (also checking that the Java instance can be cast to
>>> it).
>>>> 
>>>> 
>>>> Yup, that works! Is there any way to get the "uber" wrapper so that, at
>>> the
>>>> interactive prompt, a user can call any of the methods in MyClass, MixinA
>>>> and MixinB?
>>> 
>>> I think I didn't implement that because I didn't know how conflicting
>>> method names would be resolved. Synchronizing multiple inheritance logic
>>> between Java, C++ and Python looked a little daunting.
>> 
>> Hmm, from the Java side, isn't there only one method implementation with a
>> given name? Java's single inheritance + interfaces (i.e. pure abstract
>> classes) allows only one implementation; unlike C#, there would be no way
>> to distinguish between different interfaces' implementations in a single
>> class. So would multiple inheritance really be an issue? It would make a
>> *huge* difference to us to be able to provide a single wrapper that exposes
>> all of the classes' methods, whether declared directly or by an implemented
>> interface.
> 
> Well, the logic in cpp.py to pick what is going to be wrapped is fairly 
> simple.
> Follow the logic in the headers() function and see if you can improve it.
> Patches are welcome !

To avoid generated C++ code bloat, an issue already, I want to rely on 
inheritance as much as possible. Between the Python layer and Java there is a 
C++ wrapper layer talking to the JNI layer. If you can coax the multiple 
inheritance behaviors of the three languages involved to emulate the Java 
semantics then I think you can make this work.

Andi..

> 
> Andi..
> 
>> 
>> Thanks!
>> 
>> Barry
>> 
>> 
>>> 
>>> Andi..
>>> 
>>>> 
>>>> Thanks,
>>>> Barry
>>>> 
>>>> 
>>>>> 
>>>>> 
>>>>> Note that we have an interface us.physion.domain.MyClass, and the
>>>>>> implementation us.physion.domain.impl.**MyClass. JCC 2.15 sees these
>>> as a
>>>>>> name conflict, so we have
>>>>>> 
>>>>>> --rename us.physion.domain.impl.**MyClass=us_physion_domain_**
>>>>>> impl_MyClass
>>>>>> 
>>>>>> in our wrapper invocation.
>>>>>> 
>>>>>> Can anyone guide me in the right direction?
>>>>>> 
>>>>>> 2) Name collisions across packages
>>>>>> 
>>>>>> The same example above shows a name collision
>>>>>> between us.physion.domain.impl.MyClass and us.physion.domain.MyClass.
>>>>>> We're
>>>>>> using
>>>>>> 
>>>>>> --rename us.physion.domain.impl.**MyClass=us_physion_domain_**
>>>>>> impl_MyClass
>>>>>> 
>>>>>> in our wrapper invocation, but --rename is not well documented on the
>>> JCC
>>>>>> web site, so i'm not positive we're using it correctly. I saw a post
>>> from
>>>>>> Aug 29 to this list that says JCC 2.16 models the entire package
>>>>>> structure,
>>>>>> avoiding these name collisions, but when running JCC from SVN trunk
>>> this
>>>>>> doesn't appear to be the case (we still get the name collision without
>>> the
>>>>>> --rename).
>>>>>> 
>>>>>> Are we using --rename correctly?
>>>>> 
>>>>> Looks correct to me but you should use JCC 2.16 instead and use its
>>>>> --use_full_names command line flag instead so that the full package
>>>>> hierarchy is reproduced as Python modules. JCC 2.16 is available from
>>> trunk
>>>>> and its release is imminent (PyLucene 4.3.0 rc1 is up for release vote).
>>>>> 
>>>>> When using --use_full_names, you must first import your main Python
>>>>> extension - which causes the java packages to be installed - then the
>>> java
>>>>> hierarchy packages. For PyLucene, the main extension is called 'lucene',
>>>>> for example:
>>>>> 
>>>>>>>> from lucene import initVM
>>>>>>>> from org.apache.lucene.document import Document
>>>>>>>> etc....
>>>>> 
>>>>>>>> initVM()
>>>>>>>> d = Document()
>>>>> 
>>>>> Andi..
>>>>> 
>>>>> 
>>>>>> Thank you,
>>>>>> Barry
>>> 

Reply via email to