-
Bug
-
Resolution: Done
-
Major
-
3.1.1.Final
-
None
-
None
A bean archive contains a bean class that is (as a post-compilation step) instrumented by ByteBuddy bytecode manipulation framework. As a consequence, certain hidden methods are added to the .class file; when examined with javap tool, these method generally look like:
final java.util.Queue someMethod$__orig$accessor$h7Z5pZSX(java.util.List, java.util.Set); descriptor: (Ljava/util/List;Ljava/util/Set;)Ljava/util/Queue; flags: ACC_FINAL, ACC_SYNTHETIC Code: stack=3, locals=3, args_size=3 0: aload_0 1: aload_1 2: aload_2 3: invokespecial #538 6: areturn
The methods are synthetic, final and package-private. This combination of attributes causes exception
org.jboss.weld.exceptions.UnproxyableResolutionException:
WELD-001480: Bean type
class com.acme.SomeClass is not proxyable because it contains a final method final java.util.Queue com.acme.SomeClass.someMethod$__orig$accessor$h7Z5pZSX(java.util.List,java.util.Set)
I have determined that this is due to a check in org.jboss.weld.util.reflection.Reflections#getNonPrivateNonStaticFinalMethod() where only final, private and static method attributes are tested, disregarding synthetic attribute. However, according to a discussion at StackOverflow, dependency injection frameworks ought to ignore synthetic members.
I have locally modified Weld Core, class org.jboss.weld.util.reflection.Reflections, method getNonPrivateNonStaticMethod() as follows:
public static Method getNonPrivateNonStaticFinalMethod(Class<?> type) { for (Class<?> clazz = type; clazz != null && clazz != Object.class; clazz = clazz.getSuperclass()) { for (Method method : AccessController.doPrivileged(new GetDeclaredMethodsAction(clazz))) { if (isFinal(method) && !isPrivate(method) && !isStatic(method) && !method.isSynthetic()) { return method; } } } return null; }
This solution was then tested and appears to work correctly.