Uploaded image for project: 'Weld'
  1. Weld
  2. WELD-2586

CDI deployment fails when there are synthetic final methods in a class

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Done
    • Icon: Major Major
    • 3.1.2.Final
    • 3.1.1.Final
    • None
    • None
    • Hide

      1. Create a bean class
      2. Perform non-trivial, non-runtime bytecode instrumentation using ByteBuddy
      3. Try to deploy a bean archive containing the instrumented bean class

      Show
      1. Create a bean class 2. Perform non-trivial, non-runtime bytecode instrumentation using ByteBuddy 3. Try to deploy a bean archive containing the instrumented bean class

      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.

              manovotn Matěj Novotný
              bol_bobcik Boleslav Bobcik (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Created:
                Updated:
                Resolved: