Hello once again,
when we tried to compile some scripts in our real world
application with
the org.codehaus.janino.Compiler (Janino 2.2.0, jdk
1.4.2_06, Win2K)
the compiler signalled errors though the java files
were written correctly
(proved with javac). So we tried to find the minimal
code to
demonstrate this behaviour. Finally we broke the
problem down to one
interface and one class implementing this interface.
We have the files MyOid.java (the interface) and
MyOid32BitImpl.java
(the implementation and the main() method, in which the
errors occur) attached
to this bug report.
If you try to compile the attached files MyOid.java and
MyOid32BitImpl.java
with org.codehaus.janino.Compiler, you get errors like
'Class "MyOid" has
no method named "equals"' or 'Class "MyOid" has no
method named "toString"',
depending on what parts of the main() method in
MyOid32BitImpl.java you
comment in or out. In the case of the missing equals()
method a
java.lang.ArrayIndexOutOfBoundsException is also thrown.
We had a look at the code of Java.java and we think the
problem might be,
that java.lang.Object is not considered a superclass of
an interface
like MyOid and therefore the methods of
java.lang.Object that are inherited
by all objects if not overwritten otherwise, are not
detected.
Tests with
System.out.println("*** type: " + type);
and
System.out.println("*** superclass: " + superclass);
in Java.getIMethods() seem to prove that.
To fix it for us, we splitted the Java.getIMethods()
into two methods
Java.getIMethods() and Java.getIMethods2() to make
sure, that for
every IClass type at least the methods of
java.lang.Object are considered.
Here is our patched version and it seems to work.
/**
* Add all methods with the given
<code>methodName</code> that are declared
* by the <code>type</code>, its superclasses and
all their superinterfaces
* to the result list <code>v</code>.
* @param type
* @param methodName
* @param v
* @throws CompileException
*/
private static void getIMethods(
IClass type,
String methodName,
List v // IMethod
) throws CompileException {
// first getIMethods2
getIMethods2(type, methodName, v);
// now check methods declared by
java.lang.Object first
IClass.IMethod[] ims =
Java.getIClassLoader().OBJECT.getDeclaredIMethods();
for (int i = 0; i < ims.length; ++i) {
IClass.IMethod im = ims[i];
if (im.getName().equals(methodName)) v.add(im);
}
}
private static void getIMethods2(
IClass type,
String methodName,
List v // IMethod
) throws CompileException {
if (type == Java.getIClassLoader().OBJECT) {
return;
}
// Check methods declared by this type.
IClass.IMethod[] ims = type.getDeclaredIMethods();
for (int i = 0; i < ims.length; ++i) {
IClass.IMethod im = ims[i];
if (im.getName().equals(methodName)) v.add(im);
}
// Check superclass.
IClass superclass = type.getSuperclass();
if (superclass != null)
Java.getIMethods2(superclass, methodName, v);
// Check superinterfaces.
IClass[] interfaces = type.getInterfaces();
for (int i = 0; i < interfaces.length; ++i)
Java.getIMethods2(interfaces[i], methodName, v);
}
Because you wrote in your mail responding to our last
bug report,
you'd be curious to know for what application we use
Janino, we'll sent you an
EMail directly, describing why and how we came to use
Janino.
As it seems, that you live in Germany like we do, we
will write this EMail in German.
Thanks in advance
Matthias Eichel & Judith Andres
Logged In: YES
user_id=865893
Hi,
> We had a look at the code of Java.java and we think
> the problem might be, that java.lang.Object is not
> considered a superclass of an interface like MyOid
> and therefore the methods of java.lang.Object that
> are inherited by all objects if not overwritten
> otherwise, are not detected.
Got your point, all understood. The question is: Why should
"Object" be considered the superclass of all interfaces? I
cannot find a clause in the JLS2 that defines this, nor does
the JAVADOC of "Class.getSuperclass()" indicate that. Do you
have any reference apart from the fact that JAVAC compiles this?
Logged In: YES
user_id=865893
Ah, got it:
http://java.sun.com/docs/books/jls/second_edition/html/names.doc.html#34849
>If an interface has no direct superinterfaces, then the
> interface implicitly declares a public abstract member
> method m with signature s, return type r, and throws
> clause t corresponding to each public instance
> method m with signature s, return type r, and throws
> clause t declared in Object, unless a method with the
> same signature, same return type, and a compatible
> throws clause is explicitly declared by the interface.
Yep, will try to fix this.
Logged In: YES
user_id=865893
Fixed it. will be released in the next (>2.2.0) version.