4 Replies Latest reply on Sep 30, 2013 3:05 PM by Nicholas Whitehead

    Multi-WAR EAR Seam 2.2.2.Final fails deployment (race condition?)

    Todd Sproule Newbie

      I asked this question on the AS7 forum, but got not response.. so I'm trying here.

      I am not sure if this is a Seam 2 problem or AS7.

      I am migrating a legacy Seam 2.2.2.Final multi-war/ejb EAR app to AS7 - with some success thus far.  I'm really liking AS7.

      However, our multi-WAR EAR deployment was failing whenever I included both WARs in the EAR.  If I packaged the EAR with just one WAR or the other, then the deployment would succeed. With both WARs Seam would always complain about a (seemingly random) duplicate component definition for one of WARs.

      In the process of trying to debug this, I noticed that if I introduced a 'hack' delay (Thread.sleep) within the Seam listener, then the deployment would succeed.

      I have managed to replicate the problem with a simple bare-bones Seam 2.2.2.Final 'hello world' EAR mavenized app migrated to AS7. (Thanks to Kasper for the genesis of the example)

      • Unpack the attached zip

      • mvn clean install

      • deploy seam-hello-multiwarfail.ear within ear/target to vanilla AS7 7.0.1.Final (or jboss-as-7.1.0.Alpha2-SNAPSHOT (-1852)) and you'll get output similar to the following showing deployment descriptor failed for the war (ore or the other localhost:8080/seam-hello1 or localhost:8080/seam-hello2 may work).   See the log output for the deployment failure below.

      • to apply the hack workaround, run mvn clean install -P workaround and deploy seam-hello-multiwarfail-workaround.ear and it will deploy successfully (goto localhost:8080/seam-hello1) - this installs a hacked SeamListener class that simply introduces a 10 second delay to the deployment of the second war.  You'll see that both localhost:8080/seam-hello1 and localhost:8080/seam-hello2 work as expected.

      public class ServletDelayedInit extends SeamListener {
         private static final LogProvider log = Logging.getLogProvider(ServletContextListener.class);
         public void contextInitialized(ServletContextEvent event) {
            log.info( "Welcome to Overrided Seam Startup");
            log.info( "Waiting for 10 seconds...");
            try {
            } catch (Exception e) {
                      log.error( "Exception caught waiting",e);

      This really does look like a race condition within Seam since AS7 does both WAR deployments in concurrently.  But surely Seam should be able to handle this?  Or do I have some type of isolation problem?

      This is the part of the failed deployment log....

      type: JAVA_BEAN, class: org.jboss.seam.persistence.ManagedPersistenceContext
      16:19:13,594 INFO  [org.jboss.seam.Component] (MSC service thread 1-4) Component: simpleEntity, scope: CONVERSATION, type: ENTITY_BEAN, class: dk.lundogbendsen.seam.SimpleEntity
      16:19:13,597 INFO  [org.jboss.seam.Component] (MSC service thread 1-3) Component: seamHelloDatabase, scope: CONVERSATION, type: JAVA_BEAN, class: org.jboss.seam.persistence.ManagedPersistenceContext
      16:19:13,602 WARNING [org.jboss.seam.security.permission.PersistentPermissionResolver] (MSC service thread 1-4) no permission store available - please install a PermissionStore with the name 'org.jboss.seam.security.jpaPermissionStore' if persistent permissions are required.
      16:19:13,605 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/seam-hello1]] (MSC service thread 1-3) Exception sending context initialized event to listener instance of class org.jboss.seam.servlet.SeamListener: java.lang.IllegalStateException: duplicate factory for: org.jboss.seam.web.webSession (duplicate is specified in components.xml)
                at org.jboss.seam.core.Init.checkDuplicateFactoryExpressions(Init.java:227) [jboss-seam-2.2.2.Final.jar:]
                at org.jboss.seam.core.Init.checkDuplicateFactory(Init.java:220) [jboss-seam-2.2.2.Final.jar:]
                at org.jboss.seam.core.Init.addFactoryValueExpression(Init.java:283) [jboss-seam-2.2.2.Final.jar:]
                at org.jboss.seam.init.Initialization.installComponents(Initialization.java:1152) [jboss-seam-2.2.2.Final.jar:]
                at org.jboss.seam.init.Initialization.init(Initialization.java:737) [jboss-seam-2.2.2.Final.jar:]
                at org.jboss.seam.servlet.SeamListener.contextInitialized(SeamListener.java:36) [jboss-seam-2.2.2.Final.jar:]
                at org.apache.catalina.core.StandardContext.contextListenerStart(StandardContext.java:3368) [jbossweb-7.0.1.Final.jar:7.0.1.Final]
                at org.apache.catalina.core.StandardContext.start(StandardContext.java:3821) [jbossweb-7.0.1.Final.jar:7.0.1.Final]
                at org.jboss.as.web.deployment.WebDeploymentService.start(WebDeploymentService.java:70) [jboss-as-web-7.0.1.Final.jar:7.0.1.Final]
                at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1765)
                at org.jboss.msc.service.ServiceControllerImpl$ClearTCCLTask.run(ServiceControllerImpl.java:2291)
                at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) [:1.6.0_26]
                at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) [:1.6.0_26]
                at java.lang.Thread.run(Thread.java:662) [:1.6.0_26]
      16:19:13,688 INFO  [javax.enterprise.resource.webcontainer.jsf.config] (MSC service thread 1-4) Initializing Mojarra (1.2_13-b01-FCS) for context '/seam-hello2'
      16:19:13,693 INFO  [javax.enterprise.resource.webcontainer.jsf.config] (MSC service thread 1-3) Initializing Mojarra (1.2_13-b01-FCS) for context '/seam-hello1'
      16:19:14,702 WARNING [org.jboss.seam.jsf.SeamPhaseListener] (MSC service thread 1-4) There should only be one Seam phase listener per application