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

Observer method inheritance broken

    Details

    • Type: Bug
    • Status: Resolved (View Workflow)
    • Priority: Minor
    • Resolution: Done
    • Affects Version/s: 1.1.1.Final
    • Fix Version/s: 1.1.4.Final
    • Component/s: Events
    • Labels:
      None

      Description

      /*
      <beans xmlns="http://java.sun.com/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/javaee  http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
       
          <alternatives>
              <class>Foo$Bar</class>
          </alternatives>
       
      </beans>
       */
      @ApplicationScoped
      public class Foo {
       
          public static void main(String[] args) {
              WeldContainer weld = new Weld().initialize();
              weld.event().select(MyEvent.class).fire(new MyEvent());
          }
       
          static class MyEvent {
          }
       
          @Qualifier
          @Target({FIELD, PARAMETER})
          @Retention(RUNTIME)
          public @interface SomeQualifier {
          }
       
          @PostConstruct
          void init() {
              System.out.println("INIT FOO");
          }
       
          void onEvent(@Observes MyEvent e) {
              System.out.println("EVENT FOO");
          }
       
          @Alternative
          @Specializes
          static public class Bar extends Foo {
       
              @Override
              void init() {
                  System.out.println("INIT BAR");
              }
       
              @Override
              void onEvent(@Observes @SomeQualifier MyEvent e) {
                  System.out.println("EVENT BAR");
              }
          }
       
      }
      

      The expected output is:

      INIT BAR

      The actual output is:

      INIT BAR
      EVENT BAR

      Removing the @SomeQualifier annotation on the Bar#onEvent() method results in:

      INIT BAR
      EVENT BAR
      EVENT BAR

      Removing also the @Observes annotation on the Bar#onEvent() method results in:

      INIT BAR
      EVENT BAR

      One or several of these outcomes is wrong. Also, section 4.2 of the spec says that observer methods are only inherited if the subclass doesn't override the method. I'm confused why everyone (e.g. https://issues.jboss.org/browse/CDITCK-186) seems to assume the exact opposite.

        Gliffy Diagrams

          Activity

          Hide
          pmuir Pete Muir added a comment -

          To answer your point about why the confusion - this area of the spec received heavy editing just before the spec was submitted (in an ideal world there would be a period during which the spec is not changed to allow the TCK to catch up, this didn't happen in this case) so quite a few resources were out of date and it took a while to get it correct.

          Show
          pmuir Pete Muir added a comment - To answer your point about why the confusion - this area of the spec received heavy editing just before the spec was submitted (in an ideal world there would be a period during which the spec is not changed to allow the TCK to catch up, this didn't happen in this case) so quite a few resources were out of date and it took a while to get it correct.
          Hide
          pmuir Pete Muir added a comment -

          Agreed. The certainly shouldn't get EVENT BAR printed twice in the second case, and I don't think you should get it in the first case either

          Show
          pmuir Pete Muir added a comment - Agreed. The certainly shouldn't get EVENT BAR printed twice in the second case, and I don't think you should get it in the first case either
          Hide
          alesj Ales Justin added a comment -

          The problem is in @Specializes not being properly applied.

          Foo's onEvent method is the only proper resolver in this case.
          And that's what gets matched – where it probably shouldn't since Foo is specialized, hence should be excluded?
          But since Bar specializes Foo, this observer method is invoked against Bar instance.

          @Pete: how do we treat beans that have specialized sub-beans? Completely exclude them in the BDA on their specialized sub-bean?

          Show
          alesj Ales Justin added a comment - The problem is in @Specializes not being properly applied. Foo's onEvent method is the only proper resolver in this case. And that's what gets matched – where it probably shouldn't since Foo is specialized, hence should be excluded? But since Bar specializes Foo, this observer method is invoked against Bar instance. @Pete: how do we treat beans that have specialized sub-beans? Completely exclude them in the BDA on their specialized sub-bean?
          Hide
          pmuir Pete Muir added a comment -

          No, they should not be enabled, but they should still be there. Just like alternatives.

          Show
          pmuir Pete Muir added a comment - No, they should not be enabled, but they should still be there. Just like alternatives.

            People

            • Assignee:
              alesj Ales Justin
              Reporter:
              christian.bauer Christian Bauer
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development