5 Replies Latest reply on Jul 21, 2009 3:38 PM by bdamato

    redeployable webapp strategy

      I am trying to determine the best strategy for packaging up and deploying code for my environment. I'm running JBoss 5.1 in windows, linux and solaris, using JDK1.6.x both 32 bit and 64 bit.

      I have about 15-20 "third party" jars (like apache commons stuff), 5-10 custom developed jars (services, pojos and such) , and about 40 different webapps that, at some level, rely on the third party jars and our custom jars. Ideally, I would like to be able to deploy/redeploy each the webapps independently without causing a reload of all 40 webapps. I've done quite a bit of prototyping and searching and can't really find a good approach. My current set up is a single ear for the third party jars and a single ear for my custom jars. I had a requirement that both ears were able to see classes in each other and I've found that I can do that by by adding something like

       <loader-repository>
       com.mycorp:loader=MyLoader
       </loader-repository>
      


      to the jboss-app.xml for each ear.

      I experimented a bit with embedding each webapp into its own ear with the same load-repository setting. That mostly worked, except if I redeployed my custom or third party .ear. Redeploying those ears gave me different varieties of this exception:

      org.apache.jasper.JasperException: java.lang.IllegalStateException: BaseClassLoader@2a81df82{vfsfile:/app/jboss-5.1.0.GA/server/local/deploy/local/local.ear/} classLoader is not connected to a domain (probably undeployed?) for class java.io.PrintWriter
      
      org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:515)
      org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:405)
       org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:322)
       org.apache.jasper.servlet.JspServlet.service(JspServlet.java:249)
       javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
      org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
      
      root cause
      
      java.lang.IllegalStateException: BaseClassLoader@2a81df82{vfsfile:/app/jboss-5.1.0.GA/server/local/deploy/local/local.ear/} classLoader is not connected to a domain (probably undeployed?) for class java.io.PrintWriter
      org.jboss.classloader.spi.base.BaseClassLoader.loadClassFromDomain(BaseClassLoader.java:793)
      org.jboss.classloader.spi.base.BaseClassLoader.loadClass(BaseClassLoader.java:441)
       java.lang.ClassLoader.loadClass(ClassLoader.java:252)
       java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
      org.apache.commons.lang.exception.NestableDelegate.printStackTrace(NestableDelegate.java:292)
      org.apache.commons.lang.exception.NestableDelegate.printStackTrace(NestableDelegate.java:280)
      org.apache.commons.lang.exception.NestableRuntimeException.printStackTrace(NestableRuntimeException.java:179)
       org.apache.jsp.index_jsp._jspService(index_jsp.java:83)
       org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
       javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
      org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:369)
       org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:322)
       org.apache.jasper.servlet.JspServlet.service(JspServlet.java:249)
       javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
      org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
      


      Does anyone have any recommendations for how to achieve my basic goal of being able to hot deploy web apps and ears where the webapps are dependent on the ears? I wouldn't mind a solution that triggered a redeploy of all the webapps if one of my core ears was redeployed, but I want to avoid a redeploy of everything if I just change a single webapp.

        • 1. Re: redeployable webapp strategy

          Anyone?

          Here's a simpler question that may help me on my way.

          Is it possible to configure a war (outside of an ear) to be reloaded if the ear is redeployed? I read somewhere else that it's supposedly possible if I put something like this in my ear's jboss-app.xml:

          <jmx-name>myservice:service=OwnService</jmx-name>
          

          and this in my webapps jboss-web.xml:
          <depends>myservice:service=OwnService</depends>
          

          I have not been able to make this work though. I get this:
          DEPLOYMENTS MISSING DEPENDENCIES:
           Deployment "jboss.web.deployment:war=/bobTest" is missing the following dependencies:
           Dependency "myservice:service=OwnService" (should be in state "Create", but is actually in state "** NOT FOUND Depends on 'myservice:service=OwnService' **")
          
          DEPLOYMENTS IN ERROR:
           Deployment "myservice:service=OwnService" is in error due to the following reason(s): ** NOT FOUND Depends on 'myservice:service=OwnService' **
          


          • 2. Re: redeployable webapp strategy
            peterj

            Are there EJBs in your EAR? If so, the app server creates an mbean for each EJB, thus you could have the WAR depend on one of those mbeans.

            • 3. Re: redeployable webapp strategy

              No, I don't have any EJBs at this point.

              • 4. Re: redeployable webapp strategy
                peterj

                There might be some other mbeans created for your EAR. You can use JNDIView to look for them - use your browser's search capability to look for any mbean containing your EARs name.

                • 5. Re: redeployable webapp strategy

                  Okay, I think I'm close now. I couldn't find any MBeans for my ear, so I created one.

                  package bob.bobtest;
                  public interface BobTestMBeanInterface {
                   void create() throws Exception;
                   void start() throws Exception;
                   void stop();
                   void destroy();
                  }
                  
                  package bob.bobtest;
                  import org.jboss.ejb3.annotation.Management;
                  import org.jboss.ejb3.annotation.Service;
                  
                  @Service(objectName = "bob.bobtest:serviceName=BobTest")
                  @Management(BobTestMBeanInterface.class)
                  public class BobTestMBean implements BobTestMBeanInterface {
                   public void create() throws Exception {
                   System.out.println("create called");
                   }
                   public void destroy() {
                   System.out.println("destroy called");
                   }
                   public void start() throws Exception {
                   System.out.println("start called");
                   }
                   public void stop() {
                   System.out.println("stop called");
                   }
                  
                  }
                  

                  This shows up in JNDIView and I was able to add a dependency to my war. When I redeploy the ear that contains that MBean, it does trigger my war to undeploy, but it generates a NullPointerException when it attempts to redeploy the war. Here is the console output from the whole process starting with the redeploy of the ear:
                  15:30:43,033 INFO [ClientENCInjectionContainer] STOPPED CLIENT ENC CONTAINER: jtds-1.2
                  15:30:43,037 INFO [ClientENCInjectionContainer] STOPPED CLIENT ENC CONTAINER: jconn3
                  15:30:43,039 INFO [ClientENCInjectionContainer] STOPPED CLIENT ENC CONTAINER: jconn2
                  15:30:43,042 INFO [TomcatDeployment] undeploy, ctxPath=/bobTest
                  15:30:43,046 INFO [STDOUT] stop called
                  15:30:43,048 INFO [EJBContainer] STOPPED EJB: bob.bobtest.BobTestMBean ejbName: BobTestMBean
                  15:30:43,048 INFO [STDOUT] destroy called
                  15:30:46,495 INFO [Ejb3DependenciesDeployer] Encountered deployment AbstractVFSDeploymentContext@495782416{vfsfile:/app/jboss-5.1.0.GA/server/local/deploy/valpak/local.ear/javaapps/ja_bobTest.jar/}
                  15:30:46,495 INFO [Ejb3DependenciesDeployer] Encountered deployment AbstractVFSDeploymentContext@495782416{vfsfile:/app/jboss-5.1.0.GA/server/local/deploy/valpak/local.ear/javaapps/ja_bobTest.jar/}
                  15:30:46,503 INFO [JBossASKernel] Created KernelDeployment for: jconn2.jar
                  15:30:46,503 INFO [JBossASKernel] installing bean: jboss.j2ee:ear=local.ear,jar=jconn2.jar,name=jconn2,service=EJB3
                  15:30:46,503 INFO [JBossASKernel] with dependencies:
                  15:30:46,504 INFO [JBossASKernel] and demands:
                  15:30:46,504 INFO [JBossASKernel] and supplies:
                  15:30:46,504 INFO [JBossASKernel] Added bean(jboss.j2ee:ear=local.ear,jar=jconn2.jar,name=jconn2,service=EJB3) to KernelDeployment of: jconn2.jar
                  15:30:46,506 INFO [JBossASKernel] Created KernelDeployment for: jconn3.jar
                  15:30:46,506 INFO [JBossASKernel] installing bean: jboss.j2ee:ear=local.ear,jar=jconn3.jar,name=jconn3,service=EJB3
                  15:30:46,506 INFO [JBossASKernel] with dependencies:
                  15:30:46,506 INFO [JBossASKernel] and demands:
                  15:30:46,506 INFO [JBossASKernel] and supplies:
                  15:30:46,506 INFO [JBossASKernel] Added bean(jboss.j2ee:ear=local.ear,jar=jconn3.jar,name=jconn3,service=EJB3) to KernelDeployment of: jconn3.jar
                  15:30:46,507 INFO [JBossASKernel] Created KernelDeployment for: jtds-1.2.jar
                  15:30:46,507 INFO [JBossASKernel] installing bean: jboss.j2ee:ear=local.ear,jar=jtds-1.2.jar,name=jtds-1.2,service=EJB3
                  15:30:46,507 INFO [JBossASKernel] with dependencies:
                  15:30:46,508 INFO [JBossASKernel] and demands:
                  15:30:46,508 INFO [JBossASKernel] and supplies:
                  15:30:46,508 INFO [JBossASKernel] Added bean(jboss.j2ee:ear=local.ear,jar=jtds-1.2.jar,name=jtds-1.2,service=EJB3) to KernelDeployment of: jtds-1.2.jar
                  15:30:47,488 INFO [JBossASKernel] Created KernelDeployment for: ja_bobTest.jar
                  15:30:47,488 INFO [JBossASKernel] installing bean: jboss.j2ee:ear=local.ear,jar=ja_bobTest.jar,name=BobTestMBean,service=EJB3
                  15:30:47,488 INFO [JBossASKernel] with dependencies:
                  15:30:47,488 INFO [JBossASKernel] and demands:
                  15:30:47,488 INFO [JBossASKernel] jboss.ejb:service=EJBTimerService
                  15:30:47,489 INFO [JBossASKernel] and supplies:
                  15:30:47,489 INFO [JBossASKernel] jndi:local/BobTestMBean/remote
                  15:30:47,489 INFO [JBossASKernel] Class:bob.bobtest.BobTestMBeanInterface
                  15:30:47,489 INFO [JBossASKernel] Added bean(jboss.j2ee:ear=local.ear,jar=ja_bobTest.jar,name=BobTestMBean,service=EJB3) to KernelDeployment of: ja_bobTest.jar
                  15:30:48,036 INFO [JBossASKernel] installing bean: bob.bobtest:serviceName=BobTest
                  15:30:48,036 INFO [JBossASKernel] with dependencies:
                  15:30:48,036 INFO [JBossASKernel] and demands:
                  15:30:48,036 INFO [JBossASKernel] jboss.ejb:service=EJBTimerService
                  15:30:48,036 INFO [JBossASKernel] jboss.j2ee:ear=local.ear,jar=ja_bobTest.jar,name=BobTestMBean,service=EJB3
                  15:30:48,036 INFO [JBossASKernel] and supplies:
                  15:30:48,036 INFO [JBossASKernel] jndi:local/BobTestMBean/remote
                  15:30:48,036 INFO [JBossASKernel] Class:bob.bobtest.BobTestMBeanInterface
                  15:30:48,037 INFO [JBossASKernel] Installing bean(bob.bobtest:serviceName=BobTest) into kernel
                  15:30:48,039 INFO [STDOUT] create called
                  15:30:48,039 INFO [EJBContainer] STARTED EJB: bob.bobtest.BobTestMBean ejbName: BobTestMBean
                  15:30:48,040 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
                  
                  
                  15:30:48,044 INFO [STDOUT] start called
                  15:30:48,050 ERROR [AbstractKernelController] Error installing to Start: name=jboss.web.deployment:war=/bobTest state=Create mode=Manual requiredState=Installed
                  java.lang.NullPointerException
                   at org.jboss.web.deployers.WebModule.startModule(WebModule.java:117)
                   at org.jboss.web.deployers.WebModule.start(WebModule.java:97)
                   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                   at java.lang.reflect.Method.invoke(Method.java:597)
                   at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:157)
                   at org.jboss.mx.server.Invocation.dispatch(Invocation.java:96)
                   at org.jboss.mx.server.Invocation.invoke(Invocation.java:88)
                   at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
                   at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:668)
                   at org.jboss.system.microcontainer.ServiceProxy.invoke(ServiceProxy.java:206)
                   at $Proxy38.start(Unknown Source)
                   at org.jboss.system.microcontainer.StartStopLifecycleAction.installAction(StartStopLifecycleAction.java:42)
                   at org.jboss.system.microcontainer.StartStopLifecycleAction.installAction(StartStopLifecycleAction.java:37)
                   at org.jboss.dependency.plugins.action.SimpleControllerContextAction.simpleInstallAction(SimpleControllerContextAction.java:62)
                   at org.jboss.dependency.plugins.action.AccessControllerContextAction.install(AccessControllerContextAction.java:71)
                   at org.jboss.dependency.plugins.AbstractControllerContextActions.install(AbstractControllerContextActions.java:51)
                   at org.jboss.dependency.plugins.AbstractControllerContext.install(AbstractControllerContext.java:348)
                   at org.jboss.system.microcontainer.ServiceControllerContext.install(ServiceControllerContext.java:286)
                   at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:1631)
                   at org.jboss.dependency.plugins.AbstractController.incrementState(AbstractController.java:934)
                   at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:1082)
                   at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:984)
                   at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:774)
                   at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:540)
                   at org.jboss.deployers.vfs.deployer.kernel.BeanMetaDataDeployer.deploy(BeanMetaDataDeployer.java:121)
                   at org.jboss.deployers.vfs.deployer.kernel.BeanMetaDataDeployer.deploy(BeanMetaDataDeployer.java:51)
                   at org.jboss.deployers.spi.deployer.helpers.AbstractSimpleRealDeployer.internalDeploy(AbstractSimpleRealDeployer.java:62)
                   at org.jboss.deployers.spi.deployer.helpers.AbstractRealDeployer.deploy(AbstractRealDeployer.java:50)
                   at org.jboss.deployers.plugins.deployers.DeployerWrapper.deploy(DeployerWrapper.java:171)
                   at org.jboss.deployers.plugins.deployers.DeployersImpl.doDeploy(DeployersImpl.java:1439)
                   at org.jboss.deployers.plugins.deployers.DeployersImpl.doInstallParentFirst(DeployersImpl.java:1157)
                   at org.jboss.deployers.plugins.deployers.DeployersImpl.doInstallParentFirst(DeployersImpl.java:1178)
                   at org.jboss.deployers.plugins.deployers.DeployersImpl.doInstallParentFirst(DeployersImpl.java:1210)
                   at org.jboss.deployers.plugins.deployers.DeployersImpl.install(DeployersImpl.java:1098)
                   at org.jboss.dependency.plugins.AbstractControllerContext.install(AbstractControllerContext.java:348)
                   at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:1631)
                   at org.jboss.dependency.plugins.AbstractController.incrementState(AbstractController.java:934)
                   at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:1082)
                   at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:984)
                   at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:822)
                   at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:553)
                   at org.jboss.deployers.plugins.deployers.DeployersImpl.process(DeployersImpl.java:781)
                   at org.jboss.deployers.plugins.main.MainDeployerImpl.process(MainDeployerImpl.java:702)
                   at org.jboss.system.server.profileservice.repository.MainDeployerAdapter.process(MainDeployerAdapter.java:117)
                   at org.jboss.system.server.profileservice.hotdeploy.HDScanner.scan(HDScanner.java:362)
                   at org.jboss.system.server.profileservice.hotdeploy.HDScanner.run(HDScanner.java:255)
                   at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
                   at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:317)
                   at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:150)
                   at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(ScheduledThreadPoolExecutor.java:98)
                   at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(ScheduledThreadPoolExecutor.java:181)
                   at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:205)
                   at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
                   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
                   at java.lang.Thread.run(Thread.java:619)
                  15:30:48,056 INFO [ClientENCInjectionContainer] STARTED CLIENT ENC CONTAINER: jconn2
                  15:30:48,060 INFO [ClientENCInjectionContainer] STARTED CLIENT ENC CONTAINER: jconn3
                  15:30:48,065 INFO [ClientENCInjectionContainer] STARTED CLIENT ENC CONTAINER: jtds-1.2