You are viewing a plain text version of this content. The canonical link for it is here.
Posted to pylucene-dev@lucene.apache.org by Barry Wark <ba...@physion.us> on 2013/05/07 16:43:46 UTC

Wrapping methods from implemented interfaces

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

Thank you,
Barry

Re: Wrapping methods from implemented interfaces

Posted by Barry Wark <ba...@physion.us>.
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
> >>>
>

Re: Wrapping methods from implemented interfaces

Posted by Andi Vajda <va...@apache.org>.
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
>>> 

Re: Wrapping methods from implemented interfaces

Posted by Andi Vajda <va...@apache.org>.
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
>> 

Re: Wrapping methods from implemented interfaces

Posted by Barry Wark <ba...@physion.us>.
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.

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

Re: Wrapping methods from implemented interfaces

Posted by Andi Vajda <va...@apache.org>.
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.

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

Re: Wrapping methods from implemented interfaces

Posted by Barry Wark <ba...@physion.us>.
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?

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

Re: Wrapping methods from implemented interfaces

Posted by Andi Vajda <va...@apache.org>.
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).

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