11 Replies Latest reply on Oct 31, 2006 3:25 PM by Scott Stark

    WarDeployer dependency on TomcatClusteringCache

    Brian Stansberry Master

      I've commented out the dependency of the WarDeployer on the TomcatClusteringCache as it was preventing the start of the 'all' config. This thread is to discuss how to restore the relevant dependencies.

      I expect this was failing because a bean loaded via the VFSDeployerScanner can't depend on a bean subsequently loaded via the VFSDeploymentScanner.

      The dependency arises from two causes:

      1) If ClusteredSSO is used, the embedded Tomcat itself depends on the TomcatClusteringCache. The ClusteredSSO valve actually looks up the cache though based on an injected object name, and has some ill-considered code where it won't fail on start if the cache isn't there but rather waits to find it when it needs to service a request. So, expressing the dependency in the WarDeployer isn't strictly necessary, although removing it is hacky.

      2) Distributable webapps need the cache for their sessions. This seems more straightforward -- it's the deployment that has the dependency, not the deployer. The WarDeployer should be able to add a dependency on the cache to any distributable webapp as part of the deployment process. It just needs to know the object name of the cache.

        • 1. Re: WarDeployer dependency on TomcatClusteringCache
          Adrian Brock Master

          There should be two pieces.

          1) The WAR Deployer (that does xml -> metadata -> mbean/pojo metadatas)
          Deployed by the DeployerScanner

          2) The WAR Container (Tomcat or more accurately a collection of mbean/pojos
          that bootstrap Tomcat and its web-apps).
          Deployed by the DeploymentScanner

          You want to add your code to the WAR container NOT the WAR deployer.

          • 2. Re: WarDeployer dependency on TomcatClusteringCache
            Scott Stark Master

            That is how its broken up currently. The WarDeployer.performDeployInternal is generating the ServiceMetaData for the TomcatDeployment mbean, which wraps the web container code. The dependencies should be added to the list of dependencies being declared in the warDeployment:

             List<ServiceDependencyMetaData> dependencies = ...;
             warDeployment.setDependencies(dependencies)
            


            There should already be dependencies coming from the jboss-web.xml metadata, but I don't see this. I must have dropped it at some point. It should be there.


            • 3. Re: WarDeployer dependency on TomcatClusteringCache
              Brian Stansberry Master

              Currently the WarDeployer bean is o.j.w.t.tc6.deployer.TomcatDeployer, which is combining the functions of starting the embedded Tomcat itself and of deploying webapps. If I understand Adrian correctly, he's saying these functions should be separated. That certainly seems cleaner and will eliminate the dependency issue with ClusteredSSO.

              Scott, you mention WarDeployer.performDeployInternal -- looks like that class is a pure deployer. Is the plan to switch over to that class, which would allow us to deploy tomcat itself via the DeploymentScanner? The WarDeployer would then need to add a dependency on the embedded Tomcat service itself to any TomcatDeployment mbean.

              • 4. Re: WarDeployer dependency on TomcatClusteringCache
                Scott Stark Master

                Ok, I was confused about what I ended up with. The org.jboss.web.tomcat.tc6.deployers.WarDeployer should just be deleted as it was an early local prototype.

                org.jboss.web.deployers.AbstractWarDeployer is the base AbstractSimpleRealDeployer that is creating the ServiceMetaData for the web app mbeans in deployWebModule. This is passing on the jboss-web.xml dependencies to the web app ServiceMetaData.

                There is a lot of refactoring to be done once tomcat itself is better broken up, but for now the only problem is that the dependencies declared on the WarDeployer should really be propagated down to the web application mbean. So the war-deployer-beans.xml should just have the names of the beans/services that satisfy the tm, clustering, security, etc. needs, and these should just be added to the WebMetaData depends list for processing by the service layer.

                How these services are injected/accessed is likely going to need to be pushed down into the web app mbean as well.

                • 5. Re: WarDeployer dependency on TomcatClusteringCache
                  Brian Stansberry Master

                  That gets us back to the original issue then -- declaring in the WarDeployer bean a dependency on the TomcatClusteringCache causes the start of the AS to fail due to a missing dependency, I believe before the VFSDeploymentScanner is even created/started.

                  The WarDeployer bean also has a commented-out dependency on CachedConnectionManager. If that were uncommented, I expect the same problem would arise. In both that and the ClusteredSSO case, it's not the webapp that has the dependency; it's the embedded Tomcat service itself.

                  Is a deployer installed via the deployers dir meant to be allowed to have a dependency on a bean installed from the deploy dir?

                  • 6. Re: WarDeployer dependency on TomcatClusteringCache
                    Scott Stark Master

                    What I am saying is that these should not be expressed as dependencies on the WarDeployer. They are the defaults for dependencies that one would describe in a jboss-web.xml. To start the war deployer I don't need any of these other services. So this:

                     <bean name="WarDeployer" class="org.jboss.web.tomcat.tc6.deployers.TomcatDeployer">
                    ...
                     <property name="securityManagerService">
                     <inject bean="jboss.security:service=JaasSecurityManager" />
                     </property>
                     <depends>jboss.cache:service=TomcatClusteringCache</depends>
                    
                     <depends>jboss:service=TransactionManager</depends>
                    
                     <!-- Only needed if the org.jboss.web.tomcat.tc6.jca.CachedConnectionValve
                    TODO: injection
                     is enabled in the tomcat server.xml file.
                     <depends>jboss.jca:service=CachedConnectionManager</depends>
                     -->
                     </bean>
                    


                    should be something like:
                     <bean name="WarDeployer" class="org.jboss.web.tomcat.tc6.deployers.TomcatDeployer">
                    ...
                     <property name="defaultSecurityManagerService">jboss.security:service=JaasSecurityManager</property>
                     <property name="defaultCacheService">jboss.cache:service=TomcatClusteringCache</property>
                     <property name="defaultTM">jboss:service=TransactionManager</property>
                    
                     </bean>
                    


                    These would then be added to each WebMetaData depends list. We need to update the WebModule mbean to expose accessors for these services so that the dependency can be injected and the WebModule can perform the related configuration. This is the minimal necessary refactoring of the WarDeployer.

                    The CachedConnectionValve should be the one expression the injection of the CachedConnectionManager. A similar situation exists with the JBossContextConfig in that the authenticators should be declared directly on it rather than propagated from the WarDeployer via jmx. How we work around this in the interim of tomcat supporting injection of pojos is a todo.



                    • 7. Re: WarDeployer dependency on TomcatClusteringCache
                      Anil Saldanha Master

                       

                      "scott.stark@jboss.org" wrote:
                      A similar situation exists with the JBossContextConfig in that the authenticators should be declared directly on it rather than propagated from the WarDeployer via jmx. How we work around this in the interim of tomcat supporting injection of pojos is a todo.

                      Yes, unless tomcat allows injection, there is limited flexibility with reference to JBossContextConfig.

                      • 8. Re: WarDeployer dependency on TomcatClusteringCache
                        Brian Stansberry Master

                         

                        "scott.stark@jboss.org" wrote:

                        The CachedConnectionValve should be the one expression the injection of the CachedConnectionManager.


                        OK, that's the key point I wanted to get clarity on. Same thing applies to the ClusteredSingleSignOn valve; it needs to express the injection of a JBoss Cache instance.


                        But... will this help with the startup failure? If embedded tomcat is started via the DeployerScanner, does it matter where the dependency on something is deploy is expressed? The dependency still won't be resolved. Unless we start doing things like deploying valves in deploy, independent from server.xml.

                        • 9. Re: WarDeployer dependency on TomcatClusteringCache
                          Anil Saldanha Master

                           

                          "scott.stark@jboss.org" wrote:

                          should be something like:
                           <bean name="WarDeployer" class="org.jboss.web.tomcat.tc6.deployers.TomcatDeployer">
                          ...
                           <property name="defaultSecurityManagerService">jboss.security:service=JaasSecurityManager</property>
                           <property name="defaultCacheService">jboss.cache:service=TomcatClusteringCache</property>
                           <property name="defaultTM">jboss:service=TransactionManager</property>
                          
                           </bean>
                          



                          Scott, your thoughts on the following generic pattern:
                           <bean name="xyz" class="...">
                           <property name="options">
                           a=b
                           c=d
                           </property>
                           </bean>
                          


                          Rather than n property elements, why not 1 with key/value pairs (jbxb property injection)?

                          Think the n property injections in your example is cleaner, implementationwise.

                          • 10. Re: WarDeployer dependency on TomcatClusteringCache
                            Scott Stark Master

                            Yes, it should help because we don't actually use these dependencies unless there is a web app. At that point we create the valve and explicitly stick it into the web app valve stack. This valve setup code needs to be in the WebModule mbean/TomcatDeployment it manages, and this is where the dependencies are expressed.

                            • 11. Re: WarDeployer dependency on TomcatClusteringCache
                              Scott Stark Master

                              Its too weak from a type perspective, and it does not allow things like:

                              1. having the value of a property be described as an injection
                              2. having the value of a property be described as another bean's property
                              3. have the xml declaration of the value come from another namespace with its own custom schema binding/factory.