12 Replies Latest reply on Dec 12, 2016 3:45 AM by mkouba

    Decorator problems with programmatically added Bean

    ljnelson

      I have an extension that adds a Bean (which reports Foo, an interface, among its types) during AfterBeanDiscovery.

       

      I have a decorator, an abstract class implementing Foo, annotated with @Decorator and @Priority(javax.interceptor.Interceptor.Priority.APPLICATION), with a constructor annotated with @Inject, with a parameter in that constructor annotated with @Delegate.  In other words, I'm Doing It Right™.  I have no beans.xml.

       

      I am working with Weld 3.0.0 Alpha 17, so CDI 2.0 EDR2.

       

      I add the decorator class to the SeContainerInitializer using its addDecorators(Class<?>...) method.  (I did not add my Foo implementation to the bean classes, because the Bean representing Foo (and FooImpl) is added by my extension.)

       

      The decorator is not picked up.  I get the following error at initialize() time:

       

      org.jboss.weld.exceptions.DeploymentException: WELD-001419: Enabled decorator class com.foobar.FooDecorator is not the bean class of at least one decorator bean (detected decorator beans:

        - org.jboss.weld.environment.se.threading.RunnableDecorator)

        at org.jboss.weld.bootstrap.Validator.validateEnabledDecoratorClasses(Validator.java:667)

        at org.jboss.weld.bootstrap.Validator.validateDeployment(Validator.java:470)

        at org.jboss.weld.bootstrap.WeldStartup.validateBeans(WeldStartup.java:461)

        at org.jboss.weld.bootstrap.WeldBootstrap.validateBeans(WeldBootstrap.java:90)

        at org.jboss.weld.environment.se.Weld.initialize(Weld.java:790)

       

      Although I find the wording of this error message confusing, I suspect this has to do with the fact that AfterBeanDiscovery::addBean adds my Foo, but the decorator class can't be associated with that bean for some reason.

       

      So: how can I get my decorator to work here?  Must I programmatically add a javax.inject.spi.Decorator representing it as well?

        • 1. Re: Decorator problems with programmatically added Bean
          tremes

          Hi Laird,

          I guess you also need to add your FooDecorator to the set of bean classes - seContainerInitializer.addBeanClasses(FooDecorator.class). Hope this helps.

           

          Tom

          1 of 1 people found this helpful
          • 2. Re: Decorator problems with programmatically added Bean
            mkouba

            Note that decorators are not applied to custom implementations of Bean added through AfterBeanDiscovery methods. See also CDI-8.

            • 3. Re: Decorator problems with programmatically added Bean
              ljnelson

              tremes, this resolved the error (it seems so obvious now!) and I see from looking at the cdi-dev list that there is a proposal to rename addDecorators to enableDecorators, which I support.  However, to Martin's point, though my decorator is now happily installed, it doesn't actually decorate my custom Bean implementation.  I note that CDI-8 is resolved and indicates that CDI-580 tracks the work to be done—and CDI-580 is marked Done.  Does that mean that if I go up to 3.0.0-SNAPSHOT my decorator should just work?

               

              (I am fully aware of the fact that I am using alpha software—and grateful for the ability to do so.)

              • 4. Re: Decorator problems with programmatically added Bean
                ljnelson

                mkouba: thanks.  CDI-8's work is done in CDI-580, which is marked Done.  Does that mean I can just use 3.0.0-SNAPSHOT and my decorator should work, or is there more work to do?

                • 5. Re: Decorator problems with programmatically added Bean
                  ljnelson

                  Thinking more on this issue.

                   

                  CDI-8 and the solution proposed in CDI-580 (whatever is implied by its last comment) implies that the author of a decorator must know whether the particular bean she's intending to decorate is added programmatically or not in any given CDI environment, which is information she may very well not have.  Is there work being done to allow a discovered decorator to apply to a custom bean?  Or does the specification, which says that decorators must apply to "managed" beans—maybe trying to exclude custom ones?—prohibit this?

                  • 6. Re: Decorator problems with programmatically added Bean
                    manovotn

                    Hi Laird

                     

                    CDI-580 allows to "enable" interceptors in two different ways:

                    1) as a result of producer -> which you described earlier

                    2) in a custom bean's create method using a BeanManager method -> this is probably what you are after

                     

                    The way to do it can be seen here, in the javadoc of the interface. Note that this is not yet going to work in Weld, there is work in progress though

                     

                    EDIT: Ignore the above, Martin it correct, its for interceptors only. Lack of caffeine made me momentarily think it's for decorators as well, sorry.

                    • 7. Re: Decorator problems with programmatically added Bean
                      mkouba

                      Well, CDI-580 only deals with interceptors. The summary should be updated. Support for decorators might be added in CDI 2.1.

                      • 8. Re: Decorator problems with programmatically added Bean
                        mkouba
                        CDI-8 and the solution proposed in CDI-580 (whatever is implied by its last comment) implies that the author of a decorator must know whether the particular bean she's intending to decorate is added programmatically or not...

                        Why do you think so?

                        • 9. Re: Decorator problems with programmatically added Bean
                          ljnelson

                          Martin Kouba wrote:

                           

                          CDI-8 and the solution proposed in CDI-580 (whatever is implied by its last comment) implies that the author of a decorator must know whether the particular bean she's intending to decorate is added programmatically or not...

                          Why do you think so?

                          I'm sure I'm just missing something.  Suppose you write a framework with an embedded CDI container.  And suppose you have programmatically added some bean that implements an interface I have access to.  Ah, I say, I like your framework!  Here, let me provide a decorator for beans of that interface!  So I put my decorator in my bean archive…and it doesn't work.  Is this thought experiment invalid?

                          • 10. Re: Decorator problems with programmatically added Bean
                            mkouba

                            Laird Nelson  napsal(a):

                             

                            Martin Kouba wrote:

                             

                            CDI-8 and the solution proposed in CDI-580 (whatever is implied by its last comment) implies that the author of a decorator must know whether the particular bean she's intending to decorate is added programmatically or not...

                            Why do you think so?

                            I'm sure I'm just missing something. Suppose you write a framework with an embedded CDI container. And suppose you have programmatically added some bean that implements an interface I have access to. Ah, I say, I like your framework! Here, let me provide a decorator for beans of that interface! So I put my decorator in my bean archive…and it doesn't work. Is this thought experiment invalid?

                            Well, it's not entirely invalid but unfortunately it's not supported ATM. And there are quite a few technical problems to solve I think.

                            • 11. Re: Decorator problems with programmatically added Bean
                              ljnelson

                              OK, so to confirm: programmatically added Beans cannot be decorated in any way.  Is that correct?

                               

                              I am not upset, just trying to make sure I understand what the environment is and what my options are.

                              • 12. Re: Decorator problems with programmatically added Bean
                                mkouba

                                Yes, currently the container does not provide any means to apply decorators to a custom bean instance. In theory, you could implement the decorators on your own, but I wouldn't recommend this approach .