2 Replies Latest reply on Feb 23, 2010 1:58 PM by jaikiran

    Processed BMD as an input to a deployer

    jaikiran
      I am trying to create a chain of deployers which would allow me to do something like the following:
      
      - DeployerA in POST_CLASSLOADER phase would attach some metadata XYZ to a unit and *also* attach the same XYZ as a BeanMetaData to the unit, so that some of the fields marked with @Inject get processed appropriately.
      
      - DeployerB in REAL phase adds XYZ as an input and expects a completely processed XYZ (i.e. the @Inject within XYZ to have been completed) when the deploy method is called.
      
      The pseudo-code:
      
      {code:java}
      public class DeployerA extends AbstractDeployer
      {
         public DeployerA()
         {
            // Set the Stage to post-CL
            this.setStage(DeploymentStages.POST_CLASSLOADER);
      
            this.setInput(blah.class);
            
            // we output XYZ  
            this.addOutput(XYZ.class);
            // we also output XYZ as BMD
            this.addOutput(BeanMetaData.class);
            
         }
      
         /**
          * @see org.jboss.deployers.spi.deployer.Deployer#deploy(org.jboss.deployers.structure.spi.DeploymentUnit)
          */
         @Override
         public void deploy(DeploymentUnit unit) throws DeploymentException
         {
           
      
            XYZ output = new XYZ();
            // add as a attachment
            unit.addAttachment(XYZ.class, output);
            
            BeanMetaDataBuilder builder = BeanMetaDataBuilder.createBuilder("blahbmd", output.getClass().getName());
            builder.setConstructorValue(output);
            // attach XYZ as a BMD
            unit.addAttachment(BeanMetaData.class + ":" + "blahbmd", builder.getBeanMetaData());
         }
      
      }
      {code}
      
      {code:java}
      public class DeployerB extends AbstractSimpleRealDeployer
      {
      
         
         public DeployerB()
         {
            // input
            super(XYZ.class);
            
            
         }
      
         
         @Override
         public void deploy(DeploymentUnit unit, XYZ mcProcessedXYZ) throws DeploymentException
         {
              // here we expect a XYZ which has been processed for @Inject points by MC
              Object injectedField = mcProcessedXYZ.getInjectedField();
         }
      
      }
      
      {code}
      
      So the DeployerB is expecting an input which is already processed as a BMD. However, from what i see, the DeployerB gets called before any of the processing happens on XYZ. So, although the unit has XYZ has an attachment, when it gets processed in DeployerB, it's not injected with any injectable fields. I can see that the injection into XYZ takes place after this DeployerB is done with the processing.
      
      I am sure that i am not doing it right. So is there a way wherein i can achieve what i am trying to do?
      
      P.S: incallback for XYZ is not an option because i need "deployer" semantics in this usecase.
      
        • 1. Re: Processed BMD as an input to a deployer
          alesj

          I am sure that i am not doing it right. So is there a way wherein i can achieve what i am trying to do?

          Not completely wrong, but not right either. :-)

           

          Why it doesn't work is b/c you're dependant on the Deployers order.

          And even if BMDDeployer kicked in eariler, it wouldn't be done right.

          e.g. your DeployerB is used before BMDDeployer installs XYZ into Controller, but than XYZ' dependency might be missing

           

          What you need to do is the following.

          Instead of attaching BMD, you should simply install it into Controller -- with proper CL metadata, etc ...

          Plus, add proper dependencies between underlying Deployment[Unit] and your new BMD's KernelControllerContext.

          This way your deployment will only move into DeployerB once the XYZ' injection is satisified.

           

          OK?

          If you have problems hacking this, let me know, and I'll put together a quick prototype for you.

          • 2. Re: Processed BMD as an input to a deployer
            jaikiran

            alesj wrote:

             

            Why it doesn't work is b/c you're dependant on the Deployers order.

            And even if BMDDeployer kicked in eariler, it wouldn't be done right.

            e.g. your DeployerB is used before BMDDeployer installs XYZ into Controller, but than XYZ' dependency might be missing

            Makes sense.

             

            alesj wrote:


             

            What you need to do is the following.

            Instead of attaching BMD, you should simply install it into Controller -- with proper CL metadata, etc ...


             


            Thanks, that helped. I followed that and have my deployer chain working now.

             

            alesj wrote:


            Plus, add proper dependencies between underlying Deployment[Unit] and your new BMD's KernelControllerContext.

             

             

            I haven't looked into this detail yet - will do it tomorrow

             

            Thanks for the help!