Alright. We'll take a look. Thanks, Andi!
On Wed, May 8, 2013 at 12:39 AM, Andi Vajda <va...@apache.org> wrote: > > 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 > >>> >