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 Andi Vajda <va...@apache.org> on 2011/08/01 17:55:09 UTC
Re: JCC CompileError -- incorrect generic parameter detection
Hi Lukasz,
On Sun, 31 Jul 2011, ?ukasz Jancewicz wrote:
> On Fri, Jul 29, 2011 at 17:09, Andi Vajda <va...@apache.org> wrote:
>> For example, is there a piece of gentyref code that I could 'borrow' (with
>> attribution of course) and include that in the JCC sources to fix this
>> particular problem ?
>
> If you look at this file:
>
> http://code.google.com/p/gentyref/source/browse/src/main/java/com/googlecode/gentyref/GenericTypeReflector.java
>
> you'll see that it's completely independent from the rest of gentyref
> library, so I guess that, technically, you could just copy & paste it
> to JCC.
Not really, no. It depends on the whole thing but that's no big deal. The
licensing is also compatible since it's Apache 2.0 licensed (like you said
originally but I missed that, sorry). So it's probably ok to use/include it.
> I don't know much about Apache licensing, so I can't tell you
> if it's legal/appropriate to do so. But the technical possibility
> obviously exists. The advantage of including the library as a whole is
> that any future Java changes (Java 7, etc.) and bugs can be
> potentially taken care of by developers of gentyref.
>
>> This code could be written in Java (and wrapped by JCC for itself)
>
> That's what I did in my patch. I included gentyref.jar in the
> classpath and generated JCC wrappers for it.
So I did a custom build of JCC with that gentyref class wrapped and it does
fix the problem you encountered but it then no longer compiles Lucene :-(
I get this detailed error message from gentyref:
jcc.cpp.JavaError: com.googlecode.gentyref.UnresolvedTypeVariableException:
An exact type is requested, but the type contains a type variable that
cannot be resolved.
Variable: A from public org.apache.lucene.util.Attribute
org.apache.lucene.util.AttributeSource.addAttribute(java.lang.Class)
Hint: This is usually caused by trying to get an exact type when a
generic method who's type parameters are not given is involved.
Hacking it a bit, I catch the error and use the original reflection code
when gentyref fails to see how far I get and I get a bit further but I hit
more problems with too-specific types being resolved (like array of bool
into [B). I could probably fix this too but I'm not yet convinced that
gentyref is actually needed to solve the original problem. It feels like
gentyref, cool as it is, is actually doing too much.
Clearly, I see the bug you reported but I'm not sure where it is yet. Is it
in the java.lang.reflect code or is it in jcc itself ? For example, the same
problem happens if you just define DirectoryEntry as:
public interface DirectoryEntry extends Entry, Iterable {
}
But not when I define it thus:
import java.util.Iterator;
public interface DirectoryEntry extends Entry, Iterable {
Iterator iterator();
}
Or thus:
import java.util.Iterator;
public interface DirectoryEntry extends Entry, Iterable<Entry> {
Iterator<Entry> iterator();
}
It looks like the absence of an iterator() method definition triggers this.
Maybe all I need to do is make the iterator method code generation a bit
smarter, like not generate it if it's inherited from above anyway ?
Or see if it's inherited and its return type is overriden by the extends ?
I'm not quite sure yet what to do about this bug...
Andi..
Re: JCC CompileError -- incorrect generic parameter detection
Posted by Andi Vajda <va...@apache.org>.
Hi Lukasz,
Thank you for the patch. Comments inline.
On Fri, 5 Aug 2011, ?ukasz Jancewicz wrote:
> By the way, I discovered some other issues while using JCC in my project:
>
> 1) In __init__.py of generated code, you set a CLASSPATH variable, but
> then you don't use it anywhere. When I added gentyref.jar to the
> classpath, I was getting ClassDefNotFound errors. Somehow, your
> "classes" dir is found anyway without it. My solution: import
> CLASSPATH from jcc and use env._addClassPath(CLASSPATH) after
> initialising Java VM. I'm not certain that this is the perfect
> solution, but it worked for me.
The CLASSPATH from the generated __init__.py file is used line 400 in
jcc.cpp and on.
The CLASSPATH from jcc's __init__.py itself was unused indeed since wasn't
set to the _jcc module and thus not found by jcc.cpp. This may have gone
unnoticed because jcc itself doesn't normally use any java classes that are
not in the JRE.
The classes in jcc's 'classes' directory are used by the libjcc runtime lib
when running jcc-generated modules built with shared mode. I added
_jcc.CLASSPATH = CLASSPATH to jcc's __init__.py file and classpath is now
initialized to _jcc.CLASSPATH before parsing command line args instead of
starting empty.
> 2) I needed to use one class from Tika that was not public. I know
> that I could just modify Tika to make the class public, but I think
> sometimes you don't have access to library source code and want to use
> it anyway. I made a small modification so that if you explicitly enter
> the class name (not the jar containing it) as one of JCC arguments, it
> is exposed even if it's not public.
Thank you for the feature, I integrated that patch.
> 3) you're mixing tabs and spaces in several places in Python code.
Oops, that's not good. Thank you for pointing it out. Fixed.
> I've attached a patch file with these changes. If you feel that any of
> them might improve JCC, please add them.
>
> Thanks again for your help!
You're welcome !
Andi..
Re: JCC CompileError -- incorrect generic parameter detection
Posted by Łukasz Jancewicz <dz...@gmail.com>.
Hi Andi,
On Thu, Aug 4, 2011 at 18:37, Andi Vajda <va...@apache.org> wrote:
> I took another look at this and it seems that the problem could stem from
> another issue: jcc is generating wrappers for methods declared on interfaces
> that are declared as implemented by a class regardless of whether the method
> is, in fact, implemented by the class.
You're right! I applied your patch to JCC trunk and it worked without
problems. Thank you! So, gentyref is unnecessary after all.
By the way, I discovered some other issues while using JCC in my project:
1) In __init__.py of generated code, you set a CLASSPATH variable, but
then you don't use it anywhere. When I added gentyref.jar to the
classpath, I was getting ClassDefNotFound errors. Somehow, your
"classes" dir is found anyway without it. My solution: import
CLASSPATH from jcc and use env._addClassPath(CLASSPATH) after
initialising Java VM. I'm not certain that this is the perfect
solution, but it worked for me.
2) I needed to use one class from Tika that was not public. I know
that I could just modify Tika to make the class public, but I think
sometimes you don't have access to library source code and want to use
it anyway. I made a small modification so that if you explicitly enter
the class name (not the jar containing it) as one of JCC arguments, it
is exposed even if it's not public.
3) you're mixing tabs and spaces in several places in Python code.
I've attached a patch file with these changes. If you feel that any of
them might improve JCC, please add them.
Thanks again for your help!
--
Łukasz Jancewicz
Re: JCC CompileError -- incorrect generic parameter detection
Posted by Andi Vajda <va...@apache.org>.
Hi Lukasz,
On Mon, 1 Aug 2011, Andi Vajda wrote:
> So I did a custom build of JCC with that gentyref class wrapped and it does
> fix the problem you encountered but it then no longer compiles Lucene :-(
>
> I get this detailed error message from gentyref:
>
> jcc.cpp.JavaError: com.googlecode.gentyref.UnresolvedTypeVariableException:
> An exact type is requested, but the type contains a type variable that
> cannot be resolved.
> Variable: A from public org.apache.lucene.util.Attribute
> org.apache.lucene.util.AttributeSource.addAttribute(java.lang.Class)
> Hint: This is usually caused by trying to get an exact type when a
> generic method who's type parameters are not given is involved.
>
> Hacking it a bit, I catch the error and use the original reflection code when
> gentyref fails to see how far I get and I get a bit further but I hit more
> problems with too-specific types being resolved (like array of bool into [B).
> I could probably fix this too but I'm not yet convinced that gentyref is
> actually needed to solve the original problem. It feels like gentyref, cool
> as it is, is actually doing too much.
>
> Clearly, I see the bug you reported but I'm not sure where it is yet. Is it
> in the java.lang.reflect code or is it in jcc itself ? For example, the same
> problem happens if you just define DirectoryEntry as:
>
> public interface DirectoryEntry extends Entry, Iterable {
> }
>
> But not when I define it thus:
>
> import java.util.Iterator;
> public interface DirectoryEntry extends Entry, Iterable {
> Iterator iterator();
> }
>
> Or thus:
>
> import java.util.Iterator;
> public interface DirectoryEntry extends Entry, Iterable<Entry> {
> Iterator<Entry> iterator();
> }
>
> It looks like the absence of an iterator() method definition triggers this.
> Maybe all I need to do is make the iterator method code generation a bit
> smarter, like not generate it if it's inherited from above anyway ?
> Or see if it's inherited and its return type is overriden by the extends ?
>
> I'm not quite sure yet what to do about this bug...
I took another look at this and it seems that the problem could stem from
another issue: jcc is generating wrappers for methods declared on interfaces
that are declared as implemented by a class regardless of whether the method
is, in fact, implemented by the class.
I don't remember why I wrote it this way originally but it seems to me that
generating wrappers only for methods with an implementation on a class
should be sufficient - and taken care by the 'for method in
cls.getDeclaredMethods() loop above - since the others would be inherited
anyway. I removed that half page of code and rebuilt PyLucene. All looks
good.
Could you please try wrapping Tika again with this patch applied to jcc and
let me know if the result works (and solves the problem you solved with
gentyref) ?
Thanks !
Andi..