2 Replies Latest reply on Jun 18, 2018 7:53 AM by Matěj Novotný

    Event firing/matching and parameterized types

    Laird Nelson Expert

      (For background, I've read You think you know everything about CDI events… Think again! | Next Presso , so I'm at least mostly familiar with many edge cases in CDI events.)


      I have an AbstractFoo<? extends T> as a payload that I want to fire.


      T is defined as T extends MetaData.


      For various unimportant reasons I have to fire my payload programmatically, so I do this:


      final Event<Object> cdiEventMachinery = beanManager.getEvent();

      assert cdiEventMachinery != null;

      final TypeLiteral<AbstractFoo<? extends T>> eventTypeLiteral = new TypeLiteral<AbstractFoo<? extends T>>() {

          private static final long serialVersionUID = 1L;


      final Event<AbstractFoo<? extends T>> broadcaster = cdiEventMachinery.select(eventTypeLiteral, someQualifiers);

      assert broadcaster != null;


      Obviously here broadcaster is now set up to fire my payload.  My intention is that these events should be delivered to observers looking for AbstractFoo-or-its-subclasses instances parameterized by any type that extends MetaData.


      Now, when I do broadcaster.fire(payload), I've noticed that observer methods like this one:


      private final void onFoo(@ObservesAsync @MatchingQualifier final Foo<? extends MetaDataSubclass> event) {}


      …do not get called.  (The ? extends MetaDataSubclass seems to be the culprit; if the observed parameter is simply, say, Object then obviously the method is notified.)


      Specifically, assuming that:


      • a MatchingQualifier literal is present in someQualifiers, and
      • MetaDataSubclass is a class that extends MetaData, and
      • Foo is a class that extends AbstractFoo


      …why doesn't that observer method get called?


      To be clear, I'm sure this isn't a bug but is something missing in my understanding.  I'd like to find out what I'm missing.




        • 1. Re: Event firing/matching and parameterized types
          Laird Nelson Expert

          Here's a test case using more simple constructs:


            private final void collectionExtendsNumber(@Observes final Collection<? extends Number> payload) {

              System.out.println("*** collection extends Number");



            private final void collectionExtendsInteger(@Observes final Collection<? extends Integer> payload) {

              System.out.println("*** collection extends Integer");



            private final void collectionInteger(@Observes final Collection<Integer> payload) {

              System.out.println("*** collection Integer");



            private final void collectionNumber(@Observes final Collection<Number> payload) {

              System.out.println("*** collection Number");




            public void testContainerStartup() {

              final SeContainerInitializer initializer = SeContainerInitializer.newInstance();




              try (final SeContainer container = initializer.initialize()) {


                final BeanManager beanManager = container.getBeanManager();


                final TypeLiteral<Collection<? extends Number>> literal = new TypeLiteral<Collection<? extends Number>>() {

                    private static final long serialVersionUID = 1L;


                final Event<Collection<? extends Number>> broadcaster = beanManager.getEvent().select(literal);


                final Collection<? extends Number> payload = Collections.singleton(Integer.valueOf(1));





          In this case, only the first observer method prints anything.


          The main thing that I'm struggling with is that at the point where I would like to fire my payload, all I know is that it is, effectively, Collection<? extends Number>, even though it might "actually" be Set<Integer> (as in the example above).


          So my TypeLiteral has to be TypeLiteral<Collection<? extends Number>>, unless I'm missing something.


          And if it has to be TypeLiteral<Collection<? extends Number>>, then I don't know how to fire the payload in such a way that an observer of, say, Collection<? extends Integer> or Collection<Integer> would be notified.

          • 2. Re: Event firing/matching and parameterized types
            Matěj Novotný Novice

            Hi Laird,


            I've added an answer to your SO crosspost, so in order not to dulicate info, here is the link.

            I am still puzzled by the last case and if I will try to get more information about that.