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