1 2 3 Previous Next 37 Replies Latest reply on Feb 20, 2013 3:31 AM by bmaxwell Go to original post
      • 15. Re: Deployment order for multiple EARs
        stepanov

        Tim,

         

        Unfortunately, I haven't got any closer to implementation of such a service since it requires rather deep understanding of JBoss 7 deployers architecture (which is not yet documented). Reading the sources with no clues would take too much time.

         

        However, I implemented a simple workaround: in my servlet I check if the service it depends on is available. If it is not then I pause current thread for a certain ammount of time (1 sec) and retry after that (in "while" loop). The only drawback of this hack is that deployers are given only 1 minute to start; thus if dependency service is still not available (that is, if it takes it more than 1 minute to start) then war deployer will fail with timeout.

        • 16. Re: Deployment order for multiple EARs
          stianst

          This may not fit your usecase, but I have a similar problem where I have on EAR ("binding.ear") that contains a @Singleton (with @Startup) which binds various resources on startup. Then I have a number of other EARs and JARs that looks up these resources from JNDI. Obiviously "binding.ear" has to be deployed first for this to work. I've solved that by adding a dependency on "binding.ear" in "jboss-deployment-structure.xml".

           

          Example "jboss-deployment-structure.xml" from a JAR that has to be deployed after "binding.ear" has registered the resources in JNDI:

           

          <jboss-deployment-structure>
                    <deployment>
                              <dependencies>
                                        <module name="deployment.binding.ear" />
                              </dependencies>
                    </deployment>
          </jboss-deployment-structure>
          
          • 17. Re: Deployment order for multiple EARs
            jason.greene

            There are two very different problems with cross top-level deployment references(references between ears, jars, or wars). One is class-loading, the other is service lifecycle related.

             

            The classloading problem stems from the fact that every deployment is isolated. The approach Stian has above with a jboss-deployment-structure.xml is one way to solve this. You can also create a shared jar for classes which are shared and either create it as a static module (a module in the modules/ dir) or place the shard jar on the filesystem and reference it with Class-Path. Both static approaches do not require ordering. We could potentially add a feature for specifying a wait style dependency on deployment modules, but if such a feature existed there could be no cycles (else you deadlock).

             

            The service lifeycle problem is not unique to cross TLD, and can also happen in the same deployment/application since AS7 starts all services in parallel. The best way to solve this problem is to ensure you have dependencies between components that have dependencies. For example, assume you  only have have two ejbs with deps A and B. A is in ejb1.jar and B is in ejb2.jar. B injects A (using either @EJB or ejb-ref in ejb-jar.xml). All other EJBs (assume you have 20 of them) will be able to start in parellel, and everything will work out fine no matter which order ejb1 and ejb2 are deployed in, as long as they are deployed together (by default, you can also have it so that a dep resolves much later). There are caveats though. EJB's for example allow circular references (A can also inject B). Due to this aspect of the spec, you cant rely on chaining lifecycle calls like postconstruct (A's postconstruct can't reliably call on B). Singleton EJBs however add a @DependsOn annotation which does not allow cycles, and does allow you to ref other ejbs in @PostConstruct. As a vendor specific add-on, we also allow you to use @DependsOn with session beans.  For portability though, it's a good idea to use singleton beans as gatekeepers of service ordering. Advanced users can also take advantage of the service container and write MSC services for any kind of exotic use case. A last resort solution to lifecycle problems within the ear is to use the initialize-in-order option, which will order subdeployments in a particular way, but this adds a performance penalty since parallel deployment is enabled.

             

            Another feature we could potentially pursue if the parallel nature of AS7.x causes too much heartburn for users, is a deploy-in-serial-order setting that would require that deployments listed in standalone.xml wait until the one preceeding it was completed. This would slow down startup but would ensure that all services are available between each interval. Since we believe that having correct deps is the better approach though, it would take a lot of advocacy/votes (or a patch) to pursue it.

            • 18. Re: Deployment order for multiple EARs
              jaikiran

              Jason Greene wrote:

               

               

              Another feature we could potentially pursue if the parallel nature of AS7.x causes too much heartburn for users, is a deploy-in-serial-order setting that would require that deployments listed in standalone.xml wait until the one preceeding it was completed.

              One thing to note though is that, such a feature would not work for filesystem based deployments, since those deployments never make it to the domain/standalone configuration. If at all we have such a feature, we perhaps would have to enhance the filesystem deployment scanner to allow some kind of ordering (filename based, for example).

              • 19. Re: Deployment order for multiple EARs
                thebravedave

                Hi, I have 2 ear's, MapServer-ear-0.9.9-SNAPSHOT.ear and AreaVault-ear-0.9.9-SNAPSHOT.ear.

                MapServer ear has dependencies that reside in AreaVault ear.

                 

                I created a jboss-deployment-structure.xml file as such

                 

                <?xml version="1.0" encoding="UTF-8"?>

                <jboss-deployment-structure>

                    <!-- By default, we'll make all artifacts in this ear visible to each other by setting isolation to false -->

                    <ear-subdeployments-isolated>false</ear-subdeployments-isolated>

                    <deployment>

                        <dependencies>

                            <module name="deployment.AreaVault-ear-0.9.9-SNAPSHOT.ear" export="true"/> <!-- I hope it will get me everything in EAR/lib -->

                            <module name="deployment.AreaVault-ear-0.9.9-SNAPSHOT.ear.AreaVault-ejb-0.9.9-SNAPSHOT.jar" export="true" />

                        </dependencies>

                    </deployment>

                </jboss-deployment-structure>

                 

                 

                When I try and start up jboss I get this error

                 

                2012-06-04 10:55:57,002 ERROR [org.jboss.msc.service.fail] MSC00001: Failed to start service jboss.module.service."deplo

                yment.MapServer-ear-0.9.9-SNAPSHOT.ear.MapServer-ejb-0.9.9-SNAPSHOT.jar".main: org.jboss.msc.service.StartException in s

                ervice jboss.module.service."deployment.MapServer-ear-0.9.9-SNAPSHOT.ear.MapServer-ejb-0.9.9-SNAPSHOT.jar".main: Failed

                to load module: deployment.MapServer-ear-0.9.9-SNAPSHOT.ear.MapServer-ejb-0.9.9-SNAPSHOT.jar:main

                        at org.jboss.as.server.moduleservice.ModuleLoadService.start(ModuleLoadService.java:91)

                        at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811)

                        at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746)

                        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)

                        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)

                        at java.lang.Thread.run(Thread.java:722)

                Caused by: org.jboss.modules.ModuleNotFoundException: deployment.AreaVault-ear-0.9.9-SNAPSHOT.ear:main

                        at org.jboss.modules.Module.addExportedPaths(Module.java:990)

                        at org.jboss.modules.Module.addPaths(Module.java:883)

                        at org.jboss.modules.Module.link(Module.java:1181)

                        at org.jboss.modules.Module.relinkIfNecessary(Module.java:1207)

                        at org.jboss.modules.ModuleLoader.loadModule(ModuleLoader.java:208)

                        at org.jboss.as.server.moduleservice.ModuleLoadService.start(ModuleLoadService.java:70)

                        ... 5 more

                 

                So basically it says it can't find the AreaVault ear.

                If I start up the server with just AreaVault ear, and let it deploy and then after AreaVault has completely deployed and started up I drop my MapServer ear into the deployment folder, then

                the server knows about AreaVault ear and AreaVault ear deploys properly.

                 

                In another scenario, I have an ear UserServer ear that also has a dependency on AreaVault. I set it up the same way with a jboss-deployment-structure.xml file and it doesn't err (because AreaVault deploys first).

                I'm not sure how it decides what deployment to try and deploy first.

                 

                I saw that Jason said you could put the deployment in the modules section of the server.

                I was looking at this, but all the modules section is for jar's and not ears. Can you put an ear in the modules and make it a global module?

                 

                Please help.

                • 20. Re: Deployment order for multiple EARs
                  thebravedave

                  Answering my own problem here.

                   

                  MapServer had a dependency on AreaVault that was specified in jboss-deployment-structure.xml, but AreaVault wasn't being loaded first, so jboss was errin'g saying that it couldnt find AreaVault module (see above posting by me).

                   

                  I added in my MapServer's MANIFEST.MF file a  dependency on AreaVault as such

                   

                  Dependencies: deployment.AreaVault-ear-0.9.9-SNAPSHOT.ear.AreaVault-ejb-0.9.9-SNAPSHOT.jar

                   

                  After I added this to MANIFEST.MF jboss then realized that it should wait for AreaVault to load before trying to load MapServer.

                  I still kept jboss-deployment-structure.xml in MapServer because MapServer also needs access to AreaVault's lib folder, and believe that you can only specify individual jars in the MANIFEST.MF's Dependencies section, and I have too many

                  jars in my lib folder to want to add manually to MANIFEST.MF.

                   

                  So if jboss isn't recognizing your dependencies in jboss-deployment-structure.xml, you can always add the dependency in MANIFEST.MF

                   

                  dave

                  • 21. Re: Deployment order for multiple EARs
                    kristjan273

                    As this discussion has made some progress and I have nearly completely solved my original problem.

                     

                    Original problem is classloading separation and possible dangerous service call before it is instantiated. First issue can be addressed by adding dependency entry to manifest.mf pointing to other package and be prefixed by 'deployment.'. Second issue can be addressed by taking into account the Jason's answer (use @Singleton and @DependsOn, be careful with @PostConstruct). I have also created some independent cache structure which tracks the deployments (and it's services) status, so service A can only call B if B's package is deployed and service is ready.

                     

                    To completely solve my problem, lets assume my exotic implementation where coreA.ear is not aware of possible pluginB.ear. PluginB.ear is easy to have dependency inserted to manifest.mf, while coreA.ear is not. My idea is that pluginB.ear would register itself as an optional dependency to coreA.ear at it's deployment time. Since extending as7 is not that hard any more to me (due to excelent Tomaz's tutorial!, see - https://docs.jboss.org/author/display/AS71/Extending+JBoss+AS+7), I would just like to hear if the idea is reasonable and would be glad for some hint where to look in MSC world to achieve that.

                    • 22. Re: Deployment order for multiple EARs
                      kristjan273

                      Finally found some time slot to continue a dig into my problem.  (I also heard that some work had been done in the as 7.2, but currently I am sticking to 7.1 as it is reasonable stable for my use).

                       

                      I have created custom extension  subsystem based on archetype. Now I am kind of able to follow deployment chain of the top level deployments (.ear's ) for my case. This is the fundament for implementing the idea from the post above.

                      So, the idea is that pluginB.ear dynamically register itself to the coreA.ear as an deployment.pluginB.ear dependency. So I 'invented' the snippet inside my deployment processor:

                       

                       

                      
                      // finding current deployment unit name
                      DeploymentUnit currentDeploymentUnit = phaseContext.getDeploymentUnit();
                      String currentName = currentDeploymentUnit.getName();
                      
                      // finding core deployment unit (should be already deployed or in some deployment phase as is staticaly
                      // set as dependecy inside pluginB.ear MANIFEST.MF)
                      final String deploymentUnitNameCore = "coreA.ear";
                      final ServiceName deploymentUnitNameCore = Services.deploymentUnitName(deploymentUnitNameParent);
                      
                      ServiceRegistry serviceRegistry = phaseContext.getServiceRegistry();
                      ServiceController<DeploymentUnit> container = (ServiceController<DeploymentUnit>) serviceRegistry.getService(deploymentUnitNameCore);
                      
                      if (container != null) {
                      
                          DeploymentUnit coreAasDeploymentUnit = container.getValue();
                      
                          if (currentName.equals("pluginB.ear")) {
                              final ServiceModuleLoader deploymentModuleLoader = coreAasDeploymentUnit.getAttachment(Attachments.SERVICE_MODULE_LOADER);
                              final ModuleIdentifier dependencyId = ModuleIdentifier.fromString("deployment.pluginB.ear");
                      
                              final ModuleDependency dependency = new ModuleDependency(deploymentModuleLoader, dependencyId, false, false, false, true);
                              log.info(audit + " adding dependecy to coreA.ear (triggered by "+currentName+",newDep=" + dependency);
                              coreAasDeploymentUnit.addToAttachmentList(Attachments.MANIFEST_DEPENDENCIES, dependency);
                      
                              final ModuleSpecification coreModuleSpecification = coreAasDeploymentUnit.getAttachment(Attachments.MODULE_SPECIFICATION);
                              coreModuleSpecification.addUserDependency(dependency);
                      
                          }
                      }
                      

                       

                      The code above does IMO the same as if I would put 'Dependecies: deployment.pluginB.ear optional' to coreA.ear's MANIFEST.MF. The only difference is that putting that to MANIFEST.MF makes the dependency effective (eq. class is found) while my dynamic variant results in Ejb marshaling / ClassNotFound ex.

                       

                       

                      Now I would be really glad for some hint what is still missing (do I need to put something else somewhere, notify something on the change, ...?)

                       

                      Tnx in advance

                      • 23. Re: Deployment order for multiple EARs
                        ctomc

                        Hi,

                         

                        In what phase your deployment processor runs?

                         

                         

                         

                        --

                        tomaz

                        • 24. Re: Deployment order for multiple EARs
                          kristjan273

                          Looks like that it is running

                           

                           

                          public static final Phase PHASE = Phase.DEPENDENCIES;
                          public static final int PRIORITY = 0x4000;
                          
                          • 25. Re: Deployment order for multiple EARs
                            muthukumaran_m

                            All,

                             

                            I do have a similar problem in my application in which I have a persistence unit in a jar which registers the PU in JNDI and I have two wars which uses spring to inject the PU from JNDI.

                             

                            What happens is that the WAR deploys first and fails to find the JNDI.

                             

                            We are using Jboss 7.2, is there any help in this version of JBoss for this issue?

                             

                            Thanks,

                            Muthu

                            • 26. Re: Deployment order for multiple EARs
                              yunshi

                              I spent a long temps to search the posibilities to control the deployment order while doing the jboss4 to jboss7 migration.

                               

                              I have tried :

                               

                              1. Repackage the applications to force them to be independent with each other. But I found it very hard as we have the services that depend on other services. So I gave up.

                               

                              2. Define the dependences in standalone.xml. I found it not funny as each time we increase the version number of the application, we need to change it in the standalone.xml.

                               

                              3. Finally we finished by defining the scripts to use jboss-cli to deploy the applications one by one.

                               

                              That may not be the best solution, but at least it resolve the problem for a moment.

                              • 27. Re: Deployment order for multiple EARs
                                muthukumaran_m

                                Hello,

                                 

                                Please check my previous post and please let me know if there is any workaround for this.

                                 

                                This is turning out to be a big showstopper for our upgrade project.

                                 

                                I would really appreciate any help on this, any clues.....

                                 

                                Thanks,

                                Muthu

                                • 28. Re: Deployment order for multiple EARs
                                  jason.greene

                                  M Muthukumaran wrote:

                                   

                                  Hello,

                                   

                                  Please check my previous post and please let me know if there is any workaround for this.

                                   

                                  This is turning out to be a big showstopper for our upgrade project.

                                   

                                  I would really appreciate any help on this, any clues.....

                                   

                                  Thanks,

                                  Muthu

                                   

                                  The only way to share a PU between deployments is to package them in the same EAR.

                                  • 29. Re: Deployment order for multiple EARs
                                    jason.greene

                                    Note there is a feature request to define a mechanism for cross top level deployment PU sharing

                                    https://issues.jboss.org/browse/AS7-1769