2 Replies Latest reply on Nov 16, 2012 1:00 AM by bobzer

    Incorrect Undeployment Order

    rodos77

      Hello,

      I believe I have found a bug in the jboss-deployers project that comes with JBoss 5.1.0.GA. It appears that during the normal shutdown of the server (triggered by Ctrl-C on Win XP SP3 machine with JDK 1.5), the Resource Adapters are being stopped/undeployed prior to the application being stopped/undeployed. This is contrary to the JCA Spec 5.3.4.1:

      5.3.4.1 Phase One
      
       Before calling the stop method on the ResourceAdapter JavaBean, the application
       server must ensure that all dependant applications using the specific resource
       adapter instance are stopped. This includes deactivating all message endpoints
       receiving messages via the specific resource adapter. Note, however, since
       dependant applications typically cannot be stopped until they are undeployed, the
       application server may have to delay stopping the resource adapter instance, until
       all such dependant applications are undeployed.
      
       Completion of phase one guarantees that application threads will not use the
       resource adapter instance, even though the resource adapter instance specific objects
       may still be in the memory heap. This ensures that all application activities
       including transactional activities are completed.
      
       Thus, phase one ensures that even if a resource adapter instance does not properly
       shutdown during phase two, the resource adapter instance is practically unusable.


      I think I have traced down the problem to the fact that the list of deployments is reversed twice during undeployment - once, correctly, to perform the undeployment in the reverse order of deployment and the second time incorrectly.

      The following is the code where this happens:

      Called first:
      org.jboss.deployers.plugins.main.MainDeployerImpl:

      public void undeploy(String... names) throws DeploymentException
       {
       ...
      
       List<DeploymentContext> undeployContexts = null;
       if (undeploy.isEmpty() == false)
       {
       // Undeploy in reverse order (subdeployments first)
       undeployContexts = new ArrayList<DeploymentContext>(undeploy);
       undeploy.clear();
       Collections.reverse(undeployContexts);
       if (reverted != null)
       Collections.sort(undeployContexts, reverted);
       }
      
       ...
       }


      Called later:
      org.jboss.deployers.plugins.deployers.DeployersImpl:

      public void process(List<DeploymentContext> deploy, List<DeploymentContext> undeploy)
       {
       ...
      
       // Build a list in reverse order
       List<DeploymentControllerContext> toUndeploy = new ArrayList<DeploymentControllerContext>();
       for (int i = undeploy.size() - 1; i >= 0; --i)
       {
       DeploymentContext context = undeploy.get(i);
       if (DeploymentState.ERROR.equals(context.getState()) == false)
       context.setState(DeploymentState.UNDEPLOYING);
       log.debug("Undeploying " + context.getName());
       DeploymentControllerContext deploymentControllerContext = context.getTransientAttachments().getAttachment(ControllerContext.class.getName(), DeploymentControllerContext.class);
       if (deploymentControllerContext == null)
       {
       log.debug("DeploymentContext has no DeploymentControllerContext during undeploy request, ignoring: " + context);
       }
       else
       {
       toUndeploy.add(deploymentControllerContext);
       }
       }
      
       ...
       }


      This is causing our application to hang because one of the resource adapters that ships with our application has logic in its shutdown code to block until the whole application is shutdown. This is done to make sure that all requests from the application to the RA finish processing and no new ones are received.

      Because the deployment list is reversed twice, the RA is getting undeployed before the application and since this all happens in the single JBoss Shutdown thread, when the above logic in our RA is invoked, the block causes the whole shutdown process to hang.

      Even not taking into consideration my specific case, shutting down the RAs before the app is very bad as any new requests coming from the app will not have a running RA to service them, transactions that should otherwise commit can be rolled back and vise versa, etc.

      Please note that this problem only manifests itself under the default server configuration. Under the all configuration, it does not show up. I did not fully trace the reason but it has to do with the fact that under all, the ear file is deployed in a separate directory (farm vs deploy) and because of that the app gets undeployed before the RAs.

      I think this should be a high priority bug as this affects a critical component of the J2EE architecture not to mention the fact that it results in a difference in behavior between the all and default JBoss configurations as well as a difference in behavior between JBoss 4 and JBoss 5.

      If my analysis of the problem is correct, can someone please open a JIRA for it to allow tracking of status and progress?

      Thx.