Community
Participate
Working Groups
The compiler produces an invalid class file for a top-level class that implements an interface that is parameterized by an inner class of that top-level class when the interface declares a method whose return type is an array of the interface's generic type parameter and the outer class is woven with an aspect. Attempting to load the invalid class at runtime results in the JVM throwing a ClassFormatError: Duplicate method name&signature in class file. Example: //// // pkg1/MyInterface.java package pkg1; public interface MyInterface<F> { public F[] getValues(); } //// //// // pkg1/MyClass.java package pkg1; public class MyClass implements MyInterface<MyClass.MyInnerEnum> { public enum MyInnerEnum { } public MyInnerEnum[] getValues() { return MyInnerEnum.values(); } public static void main(String[] args) { } } //// //// // pkg2/MyAspect.aj package pkg2; import pkg1.MyClass; public aspect MyAspect pertypewithin(MyClass) { } //// Attempting to execute the main method throws this error: Exception in thread "main" java.lang.ClassFormatError: Duplicate method name&signature in class file pkg1/MyClass at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(Unknown Source) at java.security.SecureClassLoader.defineClass(Unknown Source) at java.net.URLClassLoader.defineClass(Unknown Source) at java.net.URLClassLoader.access$000(Unknown Source) at java.net.URLClassLoader$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClassInternal(Unknown Source) Deleting the aspect makes the error go away. Also, changing the declared return type of MyInterface.getValues() to Object[] rather than F[] makes the error go away.
Created attachment 72810 [details] example demonstrating bug This is a maven project demonstrating the bug. Unzip and run 'mvn package'. Then simply execute 'java -jar target/bug-0.jar'.
AspectJ1.5.2 incorrectly created a 3rd getValues() method in the woven class, identical to the bridge method generated by the compiler. The weaver bridge method gen code is only activated if a type is targeted by an aspect (hence this only occurring when the aspect is included). With AspectJ1.5.3 this third getValues() method no longer appears, so this was fixed a while ago.