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

    Understanding Binding Types

    Peter Royle Newbie

      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
          Nicklas Karlsson Master

          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 Master

            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
              Peter Royle Newbie

              Right you are! Thanks.

              • 4. Re: Understanding Binding Types
                Peter Royle Newbie

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

                • 5. Re: Understanding Binding Types
                  Svata Dedic Newbie

                  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 Master

                    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
                      Svata Dedic Newbie

                      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
                        Nicklas Karlsson Master

                        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
                          Pete Muir Master

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