Community
Participate
Working Groups
Given the following classes, javac reports a Symbol not found error. Eclipse compiles fine. I am unsure which of both is wrong. === file Closure.java === package closure; public interface Closure<I> { public void execute(I input); } === Closure.java === === ChainedClosure.java === package closure; public class ChainedClosure<I> implements Closure<I> { private final Closure<? super I>[] iClosures; @SuppressWarnings("unchecked") public static <I> Closure<I> getInstance(Closure<? super I> closure1, Closure<? super I> closure2) { if (closure1 == null || closure2 == null) { throw new IllegalArgumentException("Closures must not be null"); } Closure<I>[] closures = new Closure[] { closure1, closure2 }; return new ChainedClosure<I>(closures); } public ChainedClosure(Closure<? super I>[] closures) { super(); iClosures = closures; } public void execute(I input) { for (int i = 0; i < iClosures.length; i++) { iClosures[i].execute(input); } } } === ChainedClosure.java === === ClosureUtils.java === package closure; public class ClosureUtils { public static <I> Closure<I> chainedClosure(Closure<? super I> closure1, Closure<? super I> closure2) { return ChainedClosure.getInstance(closure1, closure2); } } === ClosureUtils.java === hendrik@lichtenstein:~/workspace/test Java> javac -classpath . closure/ClosureUtils.java closure/ClosureUtils.java:6: <I>getInstance(closure.Closure<? super I>,closure.Closure<? super I>) in closure.ChainedClosure cannot be applied to (closure.Closure<capture of ? super I>,closure.Closure<capture of ? super I>) return ChainedClosure.getInstance(closure1, closure2); ^ 1 error
Forgot to add: javac -version javac 1.5.0_07
I just noticed a very strange thing: in the original, more complex source, I got a ‘symbol not found’ error: /home/hendrik/workspace/Jakarta/org/apache/commons/collections/ClosureUtils.java:196: cannot find symbol symbol : method getInstance(org.apache.commons.collections.Closure<capture of ? super I>,org.apache.commons.collections.Closure<capture of ? super I>) location: class org.apache.commons.collections.functors.ChainedClosure return ChainedClosure.getInstance(closure1, closure2); ^ After trimming down all unnecessary methods and classes, the error changed to the ‘cannot be applied to’ error above.
I believe this is a javac bug. Observe that inference performs correclty with javac 1.6 if eliminating type parameters from invocation site, e.g. class ClosureUtils { public static Closure<String> chainedClosure(Closure<? super String> closure1, Closure<? super String> closure2) { return ChainedClosure.getInstance(closure1, closure2); } } Though in essence inferring using type variable I or type String should behave in a similar way (either all right or all wrong). In this case, Eclipse does the right thing. I think it is also related to the known javac bug: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6302954
Thus this is a dup of bug 98379 (different scenario, but same cause: inference based on type parameter arguments). Added GenericTypeTest#test1034 *** This bug has been marked as a duplicate of 98379 ***
>Verified reproduced in JDK 1.6.0_21 >Verified fixed in JDK 1.6.0_22 (and 1.6.0_27) http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6302954
> A more systematic test on each release reveals 1.6.0_22 = broken (bug with same exception says fixed) 1.6.0_23 = broken 1.6.0_24 = broken 1.6.0_25 = OK 1.6.0_26 = OK 1.6.0_27 = OK