Community
Participate
Working Groups
Compiling and running the following code: public class GenericType<V extends Integer> { public GenericType(V value) {} public void foo() {} public void bar() {} protected V getValue() { return null; } public static void main(String[] args) { new GenericType<Integer>(null).foo(); } } aspect SomeAspect { before(GenericType t): call(* GenericType.foo()) && target(t) { // Direct call to non-generic method works t.bar(); // Indirect call to non-generic method works t.callNormalMethod(); // Direct call to generic method works t.getValue(); // Indirect call to generic method produces a NoSuchMethodError t.callGenericMethod(); } private void GenericType.callNormalMethod() { bar(); } private void GenericType.callGenericMethod() { getValue(); } } produces the following error: Exception in thread "main" java.lang.NoSuchMethodError: GenericType.ajc$protecte dDispatch$GenericType$getValue()Ljava/lang/Integer; at SomeAspect.ajc$interMethod$SomeAspect$GenericType$callGenericMethod(G enericType.java:34) at GenericType.ajc$interMethodDispatch2$SomeAspect$callGenericMethod(Gen ericType.java:1) at SomeAspect.ajc$interMethodDispatch1$SomeAspect$GenericType$callGeneri cMethod(GenericType.java) at SomeAspect.ajc$before$SomeAspect$1$f6d0c54(GenericType.java:26) at GenericType.main(GenericType.java:14) in versions 1.5.0, 1.5.1a and the current development version. The bug also occurs if V is declared as <V extends java.util.EventListener>, but does not occur is V is declared as <V extends Object> (I haven't tried anything else).
thanks for the clear bug report and test program. the erasure of the method invoked by the ITD is being lost during (de)serialization. Leaving us with a 'V extends Object' return value which is incorrect.
this related case is also a problem: (typevar as parameter rather than return type) public class GenericType2<V extends Integer> { public GenericType2(V value) {} public void foo() {} protected void getValue(V aV) { } public static void main(String[] args) { new GenericType2<Integer>(null).foo(); } } aspect SomeAspect { before(GenericType2 t): call(* GenericType2.foo()) && target(t) { t.callGenericMethod(); } private void GenericType2.callGenericMethod() { getValue(new Integer(45)); } }
these two testcases are committed - commented out in Ajc152Tests
investigate for 1.5.4, but might fall back to 1.6.0 if it is a bit tricky to get solved!
I have fixed the first case of this: private void GenericType.callGenericMethod() { getValue(); } will now work. Yet more code that wasn't generics aware needed changing. Case 2 i am not fixing. If you write this Java code: public class GenericType2<V extends Integer> { public void getValue(V v) {} public void foo() { getValue(new Integer(45)); } } Then it doesn't compile with javac: "The method getValue(V) in the type GenericType2<V> is not applicable for the arguments (Integer)" (which I perhaps found a little surprising giving that the parameter meets the specified bound). AspectJ gives the same error if the getValue() call is moved out into the ITD