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..
Index: jcc/cpp.py
===================================================================
--- jcc/cpp.py  (revision 1148268)
+++ jcc/cpp.py  (working copy)
@@ -113,9 +113,12 @@
 
 def absname(names):
 
-    return "::%s" %('::'.join(names))
+    if names:
+        return "::%s" %('::'.join(names))
 
+    return ''
 
+
 def typename(cls, current, const):
 
     if cls.isArray():
@@ -747,27 +750,6 @@
                 methods[sig] = method
         elif Modifier.isProtected(modifiers):
             protectedMethods.append(method)
-    for interface in interfaces:
-        for method in interface.getMethods():
-            sig = "%s:%s" %(method.getName(), signature(method, True))
-            if sig not in methods:
-                if generics:
-                    param = method.getGenericReturnType()
-                else:
-                    param = method.getReturnType()
-                if not known(param, typeset, declares, packages, excludes,
-                             generics):
-                    continue
-                if generics:
-                    params = method.getGenericParameterTypes()
-                else:
-                    params = method.getParameterTypes()
-                for param in params:
-                    if not known(param, typeset, declares, packages, excludes,
-                                 generics):
-                        break
-                else:
-                    methods[sig] = method
 
     def _compare(m0, m1):
         value = cmp(m0.getName(), m1.getName())

Reply via email to