3 Replies Latest reply on Mar 29, 2010 2:17 PM by Ales Justin

    Inputs to deployers

    jaikiran pai Master

      I am trying to understand the usage of setInput()/setInputs()/addInput() APIs on the deployers:

       public void setInput(Class<?> input)
      
       public void setInputs(Set<String> inputs)
      
       public void setInputs(String... inputs)
      
       public void setInputs(Class<?>... inputs)
      
       public void addInput(String input)
      
       public void addInput(Class<?> input)
      


      I thought i had understood the usage the last time Emanuel mentioned about this here http://www.jboss.org/index.html?module=bb&op=viewtopic&t=156725#4236298

      But after seeing the behaviour of setInput(Class<?> input), i am not sure again. I tried this in a simple deployer:
      // Just a test deployer
      MyDeployer extends AbstractDeployer
      {
      
       MyDeployer()
       {
       // let's add a requirement on an attachment in the unit of type String.class
       setInput(String.class);
       }
      ...
      }
      


      Then there was a different deployer which added a attachment of type String to the unit. However none of the units ever got passed to this deployer. So looking into the MC code, i see that the check for relevance does this:

       protected boolean isRelevant(Deployer deployer, DeploymentUnit unit, boolean isTopLevel, boolean isComponent)
       {
       ...
       if (deployer.isAllInputs() == false)
       {
       // No attachment for the input type
       Class<?> input = deployer.getInput();
       if (input != null && unit.getAttachment(input) == null)
       return false;
      
       }
       return true;
       }
      


      deployer.getInput returns String.class which is passed to unit.getAttachment(String.class) which ultimately does this:
      public <T> T getAttachment(Class<T> type)
       {
       if (type == null)
       throw new IllegalArgumentException("Null type");
       return getAttachment(type.getName(), type);
       }
      


      The code finally ends up looking for an attachment with the name "java.lang.String" key. So unless the unit has an attachment with the key named "java.lang.String" the deployer is not going to be called.

      So what is the expected behaviour of setInput(Class<?> clazz). If it was intended to use the classname as the attachment key, then any reason why the API expects a Class<?> instead of a String?

      Also, how does the addInput API influence the deployers?



        • 1. Re: Inputs to deployers
          Ales Justin Master

           

          "jaikiran" wrote:

          So what is the expected behaviour of setInput(Class<?> clazz). If it was intended to use the classname as the attachment key, then any reason why the API expects a Class<?> instead of a String?

          To help us with generic usage.

          In most cases real deployers are meant to be component deployers,
          where we expect only a single attachment by that type,
          hence we are able to store it under class name.

          It can also be used if you're aware that there will be only single
          deployer storing its attachment under that class name.
          I agree here with you that this might not be completely obvious,
          hence you must use caution and common sense on when you use this single input. ;-)

          "jaikiran" wrote:

          Also, how does the addInput API influence the deployers?

          It helps with the "natural" order (order by inputs/outputs).
          It might also help with something you wanted - AbstractAllInputDeployer.

          • 2. Re: Inputs to deployers
            jaikiran pai Master

             

            Ales Justin wrote:

             

             


            In most cases real deployers are meant to be component deployers,
            where we expect only a single attachment by that type,
            hence we are able to store it under class name.

            A bit of a old thread, but I happened to run into something along these lines recently and am not sure I understand how the BeanMetadataDeployer works in cases like this one. I see many deployers which do this:

             

            
            public class ADeployer
            {
              public ADeployer()
             {
               setOutput(BeanMetadata.class);
             }
            
             public void deploy(DeploymentUnit du)
             {
                String blahOne = "blah";
                BeanMetaDataBuilder builder = BeanMetaDataBuilderFactory.createBuilder(blahOne, SomeClass.class);
                // ... some more specifics
                BeanMetaData bmdOne = builder.getBeanMetaData();
            
            
                String blahTwo = "onemoreblah";
                BeanMetaDataBuilder  builderTwo = BeanMetaDataBuilderFactory.createBuilder(blahTwo,  SomeClass.class);
                // ... some more specifics
                BeanMetaData bmdTwo =  builderTwo.getBeanMetaData();
            
               // add both these as attachments to unit
              unit.addAttachment(blahOne, bmdOne);
            
             unit.addAttachment(blahTwo, bmdTwo);
             }
            }
            
            

             

            So we have ADeployer which outputs BeanMetaData. In its deploy, it attaches 2 different instances of BeanMetaData and uses some *random* unique keys (i.e. does *not* use BeanMetadata.class.getName() as the key) to add it as attachment.

             

            I see that we have many such deployers around and strangely the BeanMetaDataDeployer is considered relevant and the BeanMetaDataDeployer ends up deploying these BMDs. How does that work (since the attachment keys are *not* the type name of the BeanMetadataDeployer's input)? Is there some specific deployer specific config that allows this to work?

            • 3. Re: Inputs to deployers
              Ales Justin Master
              I see that we have many such deployers around and strangely the BeanMetaDataDeployer is considered relevant and the BeanMetaDataDeployer ends up deploying these BMDs. How does that work (since the attachment keys are *not* the type name of the BeanMetadataDeployer's input)? Is there some specific deployer specific config that allows this to work?

              The component deployers use DU::getAllMetaData(BMD.class) which checks the actual type of attachment.

              Why is relevant? -- there is no reason not to be, for that component deployer -- see KernelDeploymentDeployer