6 Replies Latest reply on May 28, 2019 2:43 PM by Laird Nelson

    Portable extension: can it tell whether an alternative is selected?

    Laird Nelson Expert

      I hope I'm not overlooking something.

       

      Suppose I am validating injection points in enabled beans in a portable extension.

       

      Suppose one injection point is in a bean that I somehow "know" is disabled or will be disabled in favor of a selected alternative.

       

      I would like to detect this case so that I do not waste time and effort validating an injection point inside a bean that will not in fact be used in an application.

       

      In other words, I'd like to validate the injection points in the selected alternative, not in the "default" non-alternative bean that is being "shadowed" by the alternative.

       

      How can I do this?

       

      The specification seemed to imply (but I might be reading it wrong) that only enabled beans would be processed by processBean (http://docs.jboss.org/cdi/spec/2.0/cdi-spec.html#bean_discovery_steps).  I took this to mean that simply observing the processBean event would be enough, i.e. that the "shadowed" bean would not be reported.  I was wrong; both beans are reported.  As a result, I end up validating all injection points.  Rats.

       

      I know that from a BeanAttributes (which Bean extends) I can call its isAlternative() method, but that doesn't tell me whether it's selected or not.

       

      I'm dimly aware that this might be complicated, as the specification also talks about a bean being "selected for a given injection point" or words to that effect.  That makes a certain amount of sense since a Bean may obviously have many bean types.

       

      I can't just look for @Priority on @Alternative-annotated beans because they might be selected in the beans.xml.  Also there are stereotypes to consider.

       

      I was hoping for some sort of isSelected() method somewhere.

       

      Best,

      Laird

        • 1. Re: Portable extension: can it tell whether an alternative is selected?
          Matěj Novotný Novice

          Hi

           

          ljnelson  wrote:

          The specification seemed to imply (but I might be reading it wrong) that only enabled beans would be processed by processBean (http://docs.jboss.org/cdi/spec/2.0/cdi-spec.html#bean_discovery_steps).  I took this to mean that simply observing the processBean event would be enough, i.e. that the "shadowed" bean would not be reported.  I was wrong; both beans are reported.  As a result, I end up validating all injection points.  Rats.

           

          With alternatives, both (or all) beans are effectively enabled hence you do end up validating all. What you describe is what you should get while using specialization instead- with that you shouldn't be getting those ruled out beans.

           

          ljnelson  wrote:

          I know that from a BeanAttributes (which Bean extends) I can call its isAlternative() method, but that doesn't tell me whether it's selected or not.

           

          I'm dimly aware that this might be complicated, as the specification also talks about a bean being "selected for a given injection point" or words to that effect.  That makes a certain amount of sense since a Bean may obviously have many bean types.

           

          I can't just look for @Priority on @Alternative-annotated beans because they might be selected in the beans.xml.  Also there are stereotypes to consider.

           

          I was hoping for some sort of isSelected() method somewhere.

           

          Sadly, the concept of bean being selected isn't that easy. Take beans.xml for instance - with that you can enable bean for one archive but keep it disabled for another. Now, extensions are application wide; meaning they get notification from whole app, not just the bean archive they are in. What should isSelected() method give you then? So no silver bullet, at least not one I could think of now.

          If it is priority you are after, then you could probably check if Prioritized was implemented. But that is clumsy at best as it requires you to check custom impls of Bean interface, then you can have beans backed by class, so checking the class too. Then producer method/fields which can never have that and finally, you can have beans from configurator where only WeldBean can tell you if anything was set. And even after you do all that, alternatives in beans.xml will ruin your day I am afraid :-/

          • 2. Re: Portable extension: can it tell whether an alternative is selected?
            Laird Nelson Expert

            Thanks; this was very helpful.

             

            For context, I'm looking at the Microprofile Config specification, which, in regards to @ConfigProperty-annotated injection points, says only in the javadocs for ConfigProperty, "If no configured value exists for this property, a DeplymentException [sic] will be thrown during startup."  Admittedly it is not much of a specification at all, but it is all that we're going to get.

             

            Their TCK has a test for this, but it doesn't consider alternatives (or specialization).

             

            I have a user of a Microprofile Config implementation who does not want his "shadowed" bean to be validated: the shadowed bean will apparently have invalid configuration property names, so will cause validation failures simply by existing.  This is exactly the case I brought up here.

             

            It sounds like the only way to accomplish this would be for him to use specialization, because there is no way to tell at validation time when and where the "shadowed" bean will be used.  To your point, it might be enabled in one archive and disabled in another, etc.

             

            The two beans in question are, I think, managed beans, i.e. they are not producer methods nor are they made by producer methods.  If I am reading the specification right (I am no expert at all in this area), a managed bean B specializes A if and only if B extends A and is annotated with @Specializes.  Let's say that for whatever reason this user doesn't want to have B extend A (I'm guessing but this may very well be a real constraint).  It sounds like there is no way to both honor the Microprofile Config specification in this case and not have the "shadowed" bean validated and have B not inherit from A, correct?

             

            Thanks for your time,

            Laird

            • 3. Re: Portable extension: can it tell whether an alternative is selected?
              Laird Nelson Expert

              A follow-up:

               

              Suppose I have bean A.  It is not annotated with anything (other than a bean-defining annotation).  Bean B extends it and is annotated with @SpecializesAccording to the specification, B now specializes A.  All beans.xml files are effectively empty.

               

              Should a ProcessBean event be fired for A?  I assume not.

               

              Best,

              Laird

              • 4. Re: Portable extension: can it tell whether an alternative is selected?
                Laird Nelson Expert

                Ah, I am probably wrong for at least two reasons:

                • The specification for ProcessBean does not in fact mention enablement.  Somehow I thought it did.
                • B might specialize A, but A might still have injection points that need to be satisfied during B's invocation of super().

                 

                Best,

                laird

                • 5. Re: Portable extension: can it tell whether an alternative is selected?
                  Matěj Novotný Novice

                  ljnelson  wrote:

                   

                  Ah, I am probably wrong for at least two reasons:

                  • The specification for ProcessBean does not in fact mention enablement.  Somehow I thought it did.
                  • B might specialize A, but A might still have injection points that need to be satisfied during B's invocation of super().

                  Yes, the IP can be used by specializing bean hence still need to be satisfied.

                  As for ProcessBean event, I am not sure if it is fired, but in this case, it won't make a difference for you.

                   

                  I suppose easiest way is to just declare some dummy value for that config if you don't need it anyway?

                  • 6. Re: Portable extension: can it tell whether an alternative is selected?
                    Laird Nelson Expert

                    manovotn  wrote:

                    I suppose easiest way is to just declare some dummy value for that config if you don't need it anyway?

                    Yes, I agree and have advised the original poster similarly.  The real problem here is with the MicroProfile Config specification, which seems simply not to have taken alternatives or specialization into account properly.

                     

                    Thanks for your time!

                     

                    Best,

                    Laird