1 Reply Latest reply on Nov 14, 2016 3:31 AM by Martin Kouba

    Adding an annotation to a method via an extension: surprises

    Laird Nelson Apprentice

      For posterity I thought I would record this here.


      I am futzing around with an extension that programmatically turns JSR-330 Providers into producer methods.  I am not entirely sure where I'm going with this yet—just kind of exploring, and it's feeling like a dead end—but it has been a great way to get into the nitty gritty details of the CDI SPI.


      Anyway, so I wrote an observer method that does this:


      public <T extends Provider<?>> void replaceGuiceProviderWithProducerMethod(@Observes final ProcessAnnotatedType<T> event) {

        if (event != null) {

          final Stream<AnnotatedMethodConfigurator<? super T>> methodStream = event.configureAnnotatedType().filterMethods(m -> {

              return m.getJavaMember().getName().equals("get");


          System.out.println("*** get() method count: " + methodStream.count()); // prints 2!

          methodStream.forEach(m -> {

              m.add(PRODUCES_LITERAL); // an annotation literal implementing the Produces annotation; this fires twice





      One of the more interesting things I found was that if you have a Provider implementation (public class Foo implements Provider<Bar>), that has exactly one declared method in it (public Bar get() { return bar; }), its declared method count is…two.  Whaaa…?


      If you examine the methods in the stream, you'll see that one is declared, effectively:


      public Object get();


      …and the other is declared, effectively:


      public Bar get();


      This was surprising to me.  Then I read more deeply about bridge methods and it made sense.


      My question, I guess, is: as you can see above, I'm adding @Produces onto the get() method (in the abstract).  But do I add it onto both of these AnnotatedMethods, or just the one that returns Bar?  I don't want there to be a producer method that manufactures java.lang.Object!