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