13 Replies Latest reply on Mar 3, 2011 11:08 AM by arjan tijms

    Run service in EAR before application.xml is processed?

    henk de boer Master

      On JBoss AS 6, I would like to have a service that's included in an EAR  executed before JBoss processes the application.xml file in the archive.

       

      Is this possible?

       

      What I'm trying to achieve is making the context-root of the web module in this ear configurable, based on a single "staging" parameter that I provide when starting up JBoss AS.

       

      E.g. in jboss-app.xml

       

       

      <module>
          <service>conf/${my.stage}/properties-service.xml</service>
      </module>
      
      

       

       

      then in say conf/dev/properties-service.xml:

       

      <server>
        <mbean code="org.jboss.varia.property.SystemPropertiesService" name="jboss:type=Service,name=MySystemProperties">
           <attribute name="Properties">
             my.contextroot=alt
           </attribute>
        </mbean>
      </server>
      
      

       

       

       

      And finally in application.xml:

       

       <web>
          <web-uri>my.war</web-uri>
          <context-root>${my.contextroot}</context-root>
       </web>
      
      

       

      This works when I redeploy my EAR, but it doesn't work when I start JBoss AS the first time.

       

      Can I express somewhere that either application.xml processing depends on a service, or that a service should be run as the very first thing?

        • 1. Run service in EAR before application.xml is processed?
          jaikiran pai Master

          You can add a jboss-dependency.xml. For this specific case (i.e. depending on the properties service) you might want to look at this thread http://community.jboss.org/thread/160576

          • 2. Re: Run service in EAR before application.xml is processed?
            arjan tijms Novice

            jaikiran pai wrote:

             

            You can add a jboss-dependency.xml.

            Can you explain how this works?

             

            The documentation about this file seems to be a little thin.

             

            What do I depend on? The documentation mainly shows this example:

             

            <dependency xmlns="urn:jboss:dependency:1.0">
              <item whenRequired="Real" dependentState="Create">TransactionManager</item>
              <item>my-human-readable-deployment-alias</item>
            </dependency>
            

             

            In order to have this service started before application.xml is processed, it seems I need to know the "simple" name of this service. In case of the property service, what would this simple name be?

             

            And what do I need to enter for the whenRequired and dependentState attributes?

            • 3. Re: Run service in EAR before application.xml is processed?
              Ales Justin Master
              <dependency xmlns="urn:jboss:dependency:1.0">
                <item whenRequired="Parse" dependentState="Installed">MyPropertyService</item>
              </dependency>

              This is what you probably need. **

               

              Each item descibes a dependency.

              * whenRequired -- as the name suggest, this is where you determine when - at which state / stage - you need this dependency resolved

              * dependentState -- this is what the dependency's target state should be at least, in order to resolve your dependency

              * actual <value> -- the name of MC's component that you depend on; either service or deployment

               

              The alias there is to simplify deployment name.

              Usually deployment name is full path name, some long compilcated string; e.g. vfszip://blah/blof/foo/bar/qwert.ear

              Which is of course specific to your OS env, hence not really human readable.

              But as the wiki suggest, you can add aliases.txt, where you define a more human readable name for your deploymemnt.

              e.g. vfszip://blah/blof/foo/bar/qwert.ear --> qwert_app

               

              ** since actual creation of these dependency items happens after parse stage, you will have to move some deployers stages manually

              There is already a forum post about this somewhere, where I described this "move" in more details.

               

              HTH

              • 4. Re: Run service in EAR before application.xml is processed?
                arjan tijms Novice

                Ales Justin wrote:

                 

                This is what you probably need. **

                 

                Each item descibes a dependency.

                * whenRequired -- as the name suggest, this is where you determine when - at which state / stage - you need this dependency resolved

                * dependentState -- this is what the dependency's target state should be at least, in order to resolve your dependency

                * actual <value> -- the name of MC's component that you depend on; either service or deployment


                 

                Okay, I first tried the following. I put a file called jboss-dependency.xml in the META-INF folder of my EAR. Next to that file I created aliases.txt in which I added a single line with "my_test". The contents of jboss-dependency.xml:

                 

                <dependency xmlns="urn:jboss:dependency:1.0">
                  <item whenRequired="PreParse" dependentState="Create">TestBean</item>
                  <item>my_test</item>
                </dependency>
                

                 

                TestBean is a pojo that I put in a test-jboss-beans.xml files:

                 

                 

                <deployment xmlns="urn:jboss:bean-deployer:2.0">
                    <bean name="TestBean" class="org.test.TestBean">
                

                 

                I expected the constructor of this TestBean to be called before e.g. my EJB beans are installed. This however does not seem to be the case. Whether I have the jboss-dependency.xml or not, this TestBean is always called a while after:

                 

                13:55:05,512 INFO  [org.jboss.ejb3.deployers.JBossASKernel] Created KernelDeployment for: test_ejb.jar
                ...
                13:55:05,649 INFO  [org.jboss.ejb3.deployers.JBossASKernel] Added bean(jboss.j2ee:ear=test.ear,jar=test_ejb.jar,name=SomeService,service=EJB3) to KernelDeployment of: test_ejb.jar
                
                [output of an mbean configured in jboss-app.xml]
                
                13:55:07,617 INFO  [org.jboss.resource.connectionmanager.ConnectionFactoryBindingService] Bound ConnectionManager 'jboss.jca:service=DataSourceBinding,name=test_ds' to JNDI name 'java:test_ds'
                
                [breakpoint in TestBean hits here]
                

                 

                jboss-dependency.xml seems to be processed, since if I put an non-existing name there, like "BLABLA" or the URI name of an MBean, the server waits forever.

                 

                I'll try the "Parse" and "Installed" states.

                 

                ** since actual creation of these dependency items happens after parse stage, you will have to move some deployers stages manually

                There is already a forum post about this somewhere, where I described this "move" in more details.

                 

                I'm not sure I understand that. Do you mean there's some kind of bug in jboss-dependency.xml, which means this file itself is processed after everything has been done already, so in practice you can't actually specify dependencies here?

                 

                p.s.

                 

                What I don't understand, JBoss AS obviously reads the jboss-dependency.xml file very early. If I put an invalid state in my file, I get an error right after the server has started:

                 

                 

                14:26:49,243 INFO  [org.jboss.bootstrap.impl.base.server.AbstractServer] JBossAS [6.0.0.Final "Neo"] Started in 15s:784ms
                

                 

                This is before anything specific to my deployment has happened. I then get the following exception right after:

                 

                 

                 java.lang.IllegalArgumentException: An invalid state was used: NotInstalled
                    at org.jboss.dependency.spi.ControllerState.getOrCreateState(ControllerState.java:236) [jboss-dependency.jar:2.2.0.GA]
                    at org.jboss.dependency.spi.ControllerState.getInstance(ControllerState.java:161) [jboss-dependency.jar:2.2.0.GA]
                    at org.jboss.dependency.spi.ControllerStateValueAdapter.cast(ControllerStateValueAdapter.java:39) [jboss-dependency.jar:2.2.0.GA]
                    at org.jboss.xb.builder.runtime.AbstractPropertyHandler.attribute(AbstractPropertyHandler.java:115) [jbossxb.jar:2.0.3.GA]
                    at org.jboss.xb.binding.sunday.unmarshalling.RegisteredAttributesHandler.attributes(RegisteredAttributesHandler.java:64) [jbossxb.jar:2.0.3.GA]
                    at org.jboss.xb.builder.runtime.BeanHandler.startParticle(BeanHandler.java:112) [jbossxb.jar:2.0.3.GA]
                    at org.jboss.xb.builder.runtime.SetParentOverrideHandler.startParticle(SetParentOverrideHandler.java:65) [jbossxb.jar:2.0.3.GA]
                    at org.jboss.xb.binding.sunday.unmarshalling.AbstractPosition.initValue(AbstractPosition.java:147) [jbossxb.jar:2.0.3.GA]
                    at org.jboss.xb.binding.sunday.unmarshalling.ElementPosition.push(ElementPosition.java:582) [jbossxb.jar:2.0.3.GA]
                    at org.jboss.xb.binding.sunday.unmarshalling.SundayContentHandler.startElement(SundayContentHandler.java:205) [jbossxb.jar:2.0.3.GA]
                    at org.jboss.xb.binding.parser.sax.SaxJBossXBParser.startElement(SaxJBossXBParser.java:401) [jbossxb.jar:2.0.3.GA]
                    at org.apache.xerces.parsers.AbstractSAXParser.startElement(Unknown Source) [xercesImpl.jar:6.0.0.Final]
                    at org.apache.xerces.xinclude.XIncludeHandler.startElement(Unknown Source) [xercesImpl.jar:6.0.0.Final]
                    at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source) [xercesImpl.jar:6.0.0.Final]
                    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source) [xercesImpl.jar:6.0.0.Final]
                    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source) [xercesImpl.jar:6.0.0.Final]
                    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source) [xercesImpl.jar:6.0.0.Final]
                    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source) [xercesImpl.jar:6.0.0.Final]
                    at org.apache.xerces.parsers.XMLParser.parse(Unknown Source) [xercesImpl.jar:6.0.0.Final]
                    at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source) [xercesImpl.jar:6.0.0.Final]
                    at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source) [xercesImpl.jar:6.0.0.Final]
                    at org.jboss.xb.binding.parser.sax.SaxJBossXBParser.parse(SaxJBossXBParser.java:209) [jbossxb.jar:2.0.3.GA]
                    ... 82 more
                

                 

                 

                This is thus before any EJBs etc have been processed.

                • 5. Re: Run service in EAR before application.xml is processed?
                  Ales Justin Master
                  Okay, I first tried the following. I put a file called jboss-dependency.xml in the META-INF folder of my EAR. Next to that file I created aliases.txt in which I added a single line with "my_test". The contents of jboss-dependency.xml:

                   

                  <dependency xmlns="urn:jboss:dependency:1.0">
                    <item whenRequired="PreParse" dependentState="Create">TestBean</item>
                    <item>my_test</item>
                  </dependency>

                  No, this means your deployment it depending on itself.

                  Your deployment == my_test, depends on my_test.

                  Remove that item

                  ** since actual creation of these dependency items happens after parse stage, you will have to move some deployers stages manually

                  There is already a forum post about this somewhere, where I described this "move" in more details.

                   

                  I'm not sure I understand that. Do you mean there's some kind of bug in jboss-dependency.xml, which means this file itself is processed after everything has been done already, so in practice you can't actually specify dependencies here?

                  That's what's missing -- we need to find that forum post.

                  * http://community.jboss.org/message/578987#578987

                  • 6. Re: Run service in EAR before application.xml is processed?
                    arjan tijms Novice

                    Ales Justin wrote:


                    There is already a forum post about this somewhere, where I described this "move" in more details.


                     

                    Would that be this post? http://community.jboss.org/thread/160576

                     

                    One thing I don't understand there is this part:

                     

                     

                    <dependency xmlns="urn:jboss:dependency:1.0">
                      <item whenRequired="Parse">istep:type=Properties,name=SystemProperties</item>
                    </dependency>
                    

                     

                    In the previous explanation it was said the body of the item tag was a simple name, but here it seems to have some structure. Does JBoss AS parses this in any way or is "istep:type=Properties,name=SystemProperties" just taken as a single opaque string?

                    • 7. Re: Run service in EAR before application.xml is processed?
                      jaikiran pai Master

                      arjan tijms wrote:

                       

                      One thing I don't understand there is this part:

                       

                       

                      <dependency xmlns="urn:jboss:dependency:1.0">
                        <item whenRequired="Parse">istep:type=Properties,name=SystemProperties</item>
                      </dependency>
                      

                       

                      In the previous explanation it was said the body of the item tag was a simple name, but here it seems to have some structure. Does JBoss AS parses this in any way or is "istep:type=Properties,name=SystemProperties" just taken as a single opaque string?

                      That's the ObjectName of the SystemPropertiesService MBean. In your case (the example that you posted in your post), that value will be jboss:type=Service,name=MySystemProperties


                      • 8. Re: Run service in EAR before application.xml is processed?
                        arjan tijms Novice

                        Ales Justin wrote:

                         

                        No, this means your deployment it depending on itself.

                        Your deployment == my_test, depends on my_test.

                        Remove that item


                         

                        Okay, I removed the item so I now have the following in my EAR's META-INF/jboss-dependency.xml

                         

                        <dependency xmlns="urn:jboss:dependency:1.0">
                          <item whenRequired="Parse">TestBean</item>  
                        </dependency>
                        

                         

                        Following the advice of the referenced topic, I changed server/default/deployers/dependency-deployers-jboss-beans.xml from:

                         

                         

                        <!-- jboss-dependency.xml -->
                        <bean name="DependenciesParserDeployer" class="org.jboss.deployers.vfs.plugins.dependency.DependenciesParserDeployer"/>
                        <bean name="DependenciesMDDeployer" class="org.jboss.deployers.vfs.plugins.dependency.DependenciesMetaDataDeployer"/>
                        <bean name="DeploymentDependenciesDeployer" class="org.jboss.deployers.vfs.plugins.dependency.DeploymentDependencyDeployer"/>
                        

                         

                        into:

                         

                          <!-- jboss-dependency.xml -->
                          <bean name="DependenciesParserDeployer" class="org.jboss.deployers.vfs.plugins.dependency.DependenciesParserDeployer">
                            <property name="stage"><inject bean="PreParseStage"/></property>
                          </bean>
                          <bean name="DependenciesMDDeployer" class="org.jboss.deployers.vfs.plugins.dependency.DependenciesMetaDataDeployer">
                            <property name="stage"><inject bean="PreParseStage"/></property>
                          </bean>
                          <bean name="DeploymentDependenciesDeployer" class="org.jboss.deployers.vfs.plugins.dependency.DeploymentDependencyDeployer">
                            <property name="stage"><inject bean="PreParseStage"/></property>
                          </bean>
                        
                          <bean name="PreParseStage" class="org.jboss.deployers.spi.deployer.DeploymentStage">
                            <constructor>
                              <parameter class="java.lang.String">PreParse</parameter>
                              <parameter class="java.lang.String">Not Installed</parameter>
                            </constructor>
                          </bean>
                        

                         

                        But now starting up the server hangs again.

                         

                        The jboss-beans.xml in which TestBean is defined is referenced from META-INF/jboss-app.xml (since the entire purpose of this exercise is that I can choose a properties file via a -D option when starting up JBoss AS).

                         

                        Could that be a reason for the hang?

                         

                        E.g. jboss-dependencies.xml needs to kick in after META-INF/jboss-app.xml has been processed and the jboss-beans.xml containing TestBean is known, but before application.xml is processed.

                        • 9. Re: Run service in EAR before application.xml is processed?
                          arjan tijms Novice

                          jaikiran pai wrote:

                           

                          That's the ObjectName of the SystemPropertiesService MBean. In your case (the example that you posted in your post), that value will be jboss:type=Service,name=MySystemProperties


                          Okay, that's clear now. In my example (TestBean) I fell back to a POJO defined in a jboss-beans.xml file, but with that syntax I can also depend on (old) MBeans.

                          • 10. Re: Run service in EAR before application.xml is processed?
                            Ales Justin Master
                            The jboss-beans.xml in which TestBean is defined is referenced from META-INF/jboss-app.xml (since the entire purpose of this exercise is that I can choose a properties file via a -D option when starting up JBoss AS).

                             

                            Could that be a reason for the hang?

                             

                            E.g. jboss-dependencies.xml needs to kick in after META-INF/jboss-app.xml has been processed and the jboss-beans.xml containing TestBean is known, but before application.xml is processed.

                            jboss-dependency.xml only makes sense for two separate deployments.

                            Where in jb-dep.xml you define dependencies from the 2nd deployment.

                            This is due to the fact that we can only control lifecycle of the top deployment, but not sub-deployments.

                            • 11. Re: Run service in EAR before application.xml is processed?
                              arjan tijms Novice

                              Ales Justin wrote:

                               

                              jboss-dependency.xml only makes sense for two separate deployments.

                              Where in jb-dep.xml you define dependencies from the 2nd deployment.

                              This is due to the fact that we can only control lifecycle of the top deployment, but not sub-deployments.

                              Okay. Hmmm... so for having this property service (defined inside the ear) installed before application.xml is processed, jboss-dependency.xml is a dead end isn't it?

                               

                              Any other suggestions?

                              • 12. Re: Run service in EAR before application.xml is processed?
                                Ales Justin Master
                                Okay. Hmmm... so for having this property service (defined inside the ear) installed before application.xml is processed, jboss-dependency.xml is a dead end isn't it?

                                Yes, unfortunately.

                                 

                                Any other suggestions?

                                Separate them in two deployments?

                                 

                                Or, fill in the properties at build time.

                                • 13. Re: Run service in EAR before application.xml is processed?
                                  arjan tijms Novice

                                  Ales Justin wrote:

                                   

                                  Okay. Hmmm... so for having this property service (defined inside the ear) installed before application.xml is processed, jboss-dependency.xml is a dead end isn't it?

                                  Yes, unfortunately.

                                   

                                  Okay, unfortunately indeed. But it is as it is I guess. Is there any work going on that you know of that might make this possible in the future?

                                   

                                   

                                  Separate them in two deployments?

                                   

                                  That would indeed be a solution. I was trying to prevent this, to make it as easy as possible for people to deploy the app in question.

                                   

                                  Idealistically they could start JBoss AS with only a single staging parameter, and nothing more. Requiring them to deploy two apps, or asking them to provide additional startup (-Dsomething=foo) parameters is an extra burden that I was trying to prevent.