9 Replies Latest reply on Jan 18, 2009 1:31 AM by pmuir

    Understanding Binding Types

    peteroyle.howardmoon.hitcity.com.au

      Hi,


      Does the current ALPHA1 and/or TRUNK versions of the RI support the use of binding annotations? I can't see any code that checks what they are within ManagerImpl.getInstanceByType(...) (apart from sanity checking the types themselves).


      To double check I created the following simple web beans:



      @Named
      public class Door { }





      @Synchronous
      @Named
      public class SynchronousDoor extends Door { }



      I then added this method to the existing test class org.jboss.webbeans.test.InstantiationByTypeTest.java:


         @Test() @SpecAssertion(section="5.9")
         public void testBindingTypes() throws Exception
         {
             DependentContext.INSTANCE.setActive(true);
             try {
                 Bean<SynchronousDoor> synchDoorBean = SimpleBean.of(SynchronousDoor.class, manager);
                 manager.addBean(synchDoorBean);
                 Bean<Door> doorBean = SimpleBean.of(Door.class, manager);
                 manager.addBean(doorBean);
      
                 /* a */ manager.getInstanceByType(Door.class, new CurrentBinding());
                 /* b */ manager.getInstanceByType(Door.class);
                 // c    manager.getInstanceByType(SynchronousDoor.class);
                 // d    manager.getInstanceByType(SynchronousDoor.class, new CurrentBinding());
                 // e    manager.getInstanceByType(SynchronousDoor.class, new CurrentBinding(), new AnnotationLiteral<Synchronous>(){});
                 // f    manager.getInstanceByType(Door.class, new CurrentBinding(), new AnnotationLiteral<Synchronous>(){});
             } finally {
                  DependentContext.INSTANCE.setActive(false);
             }
         }




      Only lines a and b pass. The commented out lines c to f all fail with an UnsatisfiedDependencyException - something like:


      javax.webbeans.UnsatisfiedDependencyException: Annotated class Class @Named @Synchronous org.jboss.webbeans.test.pete.SynchronousDoor   (and probably something silghtly different for line f).


      Can anyone please shed some light for me as to why each of the lines above passes or fails?


      Greatly appreciated.

        • 1. Re: Understanding Binding Types
          nickarls

          Well, Pete wrote the resolving but from a quick glance I would say that:


          the SynchronousDoor has the binding type Synchronous and can be found with


          manager.getInstanceByType(SynchronousDoor.class, new AnnotationLiteral<Synchronous>(){});
          



          The @Current binding is implicit, if you look for it explicitly, it goes into the resolving algorithm and fails with does not contain all bindings. I think the only real explicit use for @Current is on fields.

          • 2. Re: Understanding Binding Types
            gavin.king

            Right, the reason is that SynchronousDoor doesn't have the binding type @Current, since it explicitly declares a bindng type.

            • 3. Re: Understanding Binding Types
              peteroyle.howardmoon.hitcity.com.au

              Right you are! Thanks.

              • 4. Re: Understanding Binding Types
                peteroyle.howardmoon.hitcity.com.au

                And that explains it! Seems my understanding of @Current was a bit mixed up. Cheers guys.

                • 5. Re: Understanding Binding Types
                  ceda

                  Gavin King wrote on Jan 15, 2009 12:12:


                  Right, the reason is that SynchronousDoor doesn't have the binding type @Current, since it explicitly declares a bindng type.


                  I would like to extend that example, this time with respect to potential ambiguous dependencies.



                  @Named
                  public class Door { }

                  @Synchronous
                  @Named
                  public class SynchronousDoor extends Door { }

                  @Synchronous @Transactional
                  @Named
                  public class SyncTransDoor extends Door { }


                  Now, if I understood the previous posts, in a class



                  public class Walker {
                     @Current private Door doorLeft;
                     @Synchronous private Door doorSync;
                  }


                  the doorLeft injection point will succeed, because of (implicit) @Current annotation on the Door class. However, this magic does not seem to work for doorSync, which is ambiguous: SynchronousDoor, or SyncTransDoor ? In the case Door vs. SynchronousDoor the @Current implicit annotation solved the problem. But there's no implicit discriminator between SynchronousDoor and SyncTransDoor. Note that the Walker really does not care about the 'extra' Transactional feature.


                  How to approach this situation ?

                  • 6. Re: Understanding Binding Types
                    gavin.king

                    Exactly! Your example results in an AmbiguousDependencyException. You need to explicitly tell us that you want the non-@Transactional implementation, since you have specified a contract for which there are two possible satisfying implementations.


                    In practice, you would need to use a second binding type called @NonTransactional to express this.

                    • 7. Re: Understanding Binding Types
                      ceda

                      OK, I thought there is (should) be some way around it, since usually adding a specialized implementation to the system should not impact the existing code. With @NonTransactional, both the SynchronousDoor and the client have to be updated if the SyncTransDoor WebBean is added to the system even though it is unrelated to this code.


                      Also, if I may suggest, please include this caveat in the examples/faqs so people design their Binding Template system properly from the start.

                      • 8. Re: Understanding Binding Types
                        nickarls

                        If you look for a particular person and do a select * from Employee where lastname='Smith' and end up with multiple rows, how can you know which 'Smith' is the one you are looking for? ;-)


                        You could possible play around with deployment types but just extending a class hierarchy and adding binding types will result in ambiguous resolves pretty quick.


                        If you want to roll your own RI, you could add an attribute optional to the binding types and modify the resolving algorithm but a good rule of thumb is if you can't resolve the ambiguity yourself, neither can any algorithm :-)

                        • 9. Re: Understanding Binding Types
                          pmuir

                          I think either specialization or deployment types will help here, depending on the exact use case.