AnsweredAssumed Answered

Getting Error:org.jbpm.JbpmException: closed JbpmContext...

Question asked by dynamolalit on Dec 8, 2009
Hi,

I have modified submit_processdefinition.xml to get status of content which is submitted from content creator to editor for review/approve/reject as:


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

<!– This describes a process for submitting changed content in a user –>
<!– sandbox, via an approver, to the staging sandbox. –>

<process-definition xmlns="urn:jbpm.org:jpdl-3.1" name="wcmwf:submit">

    <swimlane name="initiator"/>

    <!–              –>
    <!– Start Review –>
    <!–              –>

    <start-state name="start">
        <task name="wcmwf:submitReviewTask" swimlane="initiator"/>
        <transition name="" to="initialise"/>
    </start-state>

    <decision name="initialise">
        <event type="node-enter">
            <script>
                <variable name="wcmwf_reviewCycle" access="write"/>
                <expression>
                   wcmwf_reviewCycle = 1;
                </expression>
            </script>
        </event>       
        <transition name="" to="serialorparallel" />
        <transition name="checklinks" to="checklinks">
           <condition>#{wcmwf_validateLinks != null &amp;&amp; wcmwf_validateLinks == true}</condition>
        </transition>
    </decision>
   
    <!–                                –>
    <!– Validate Links being submitted –>
    <!–                                –>
   
    <decision name="checklinks">
        <event type="node-enter">
            <action class="org.alfresco.repo.avm.wf.AVMSubmitLinkChecker" />
        </event>
        <transition name="brokenlinkspresent" to="verifybrokenlinks" />
        <transition name="nobrokenlinks" to="serialorparallel" >
            <condition>#{wcmwf_brokenLinks == 0}</condition>
        </transition>
    </decision>
   
    <task-node name="verifybrokenlinks">
        <task name="wcmwf:verifyBrokenLinksTask" swimlane="initiator" />
        <transition name="abort" to="end" />
        <transition name="continue" to="serialorparallel" />
    </task-node>

    <!–                                      –>
    <!– Split into Serial or Parallel Review –>
    <!–                                      –>

    <decision name="serialorparallel">
       <event type="node-enter">
            <script>
               <variable name="wcmwf_reviewerCnt" access="write"/>
               <variable name="wcmwf_approveCnt" access="write"/>
               <variable name="wcmwf_reviewType" access="write"/>
               <expression>
                  wcmwf_reviewerCnt = bpm_assignees.size();
                  wcmwf_approveCnt = 0;
                  wcmwf_reviewType = wcmwf_submitReviewType;
               </expression>
            </script>
       </event>

       <transition name="serial" to="submitserialreview" />
       <transition name="parallel" to="submitparallelreview">
          <condition>#{wcmwf_reviewType == "Parallel"}</condition>
       </transition>
    </decision>  


    <!–               –>
    <!– Serial Review –>
    <!–               –>

    <decision name="submitserialreview">
       <transition name="endreview" to="endreview" />
       <transition name="review" to="serialreview">
         <condition>#{wcmwf_approveCnt &lt; wcmwf_reviewerCnt}</condition>
       </transition>
    </decision>  

    <task-node name="serialreview">
        <task name="wcmwf:reviewTask">
           <assignment class="org.alfresco.repo.workflow.jbpm.AlfrescoAssignment">
              <actor>#{bpm_assignees.get(wcmwf_approveCnt)}</actor>
           </assignment>
           <event type="task-assign">
              <script>
                 if (wcmwf_reviewCycle > 1)
                    taskInstance.description = taskInstance.description + " (" + wcmwf_reviewCycle + ")";
              </script>
           </event>          
        </task>

        <transition name="approve" to="submitserialreview">
           <script>
              <variable name="wcmwf_approveCnt" access="read, write"/>
              <expression>
                 wcmwf_approveCnt = wcmwf_approveCnt + 1;
              </expression>
           </script>
        </transition>
        <transition name="reject" to="endreview" />
    </task-node>


    <!–                 –>
    <!– Parallel Review –>
    <!–                 –>

    <node name="submitparallelreview">
        <action class="org.alfresco.repo.workflow.jbpm.ForEachFork">
            <foreach>#{bpm_assignees}</foreach>
            <var>reviewer</var>
        </action>
        <transition name="review" to="parallelreview" />
    </node>

    <task-node name="parallelreview">
        <task name="wcmwf:parallelReviewTask">
           <assignment class="org.alfresco.repo.workflow.jbpm.AlfrescoAssignment">
              <actor>#{reviewer}</actor>
           </assignment>
        
           <event type="task-assign">
              <script>
                 if (wcmwf_reviewCycle > 1)
                    taskInstance.description = taskInstance.description + " (" + wcmwf_reviewCycle + ")";
              </script>
           </event>          
        </task>
        <transition name="approve" to="joinparallelreview">
            <script>
                <variable name="wcmwf_approveCnt" access="read,write" />
                <expression>
                    wcmwf_approveCnt = wcmwf_approveCnt +1;
                </expression>
            </script>
        </transition>
        <transition name="reject" to="joinparallelreview" />
    </task-node>

    <join name="joinparallelreview">
        <transition to="endreview" />
    </join>


    <!–                –>
    <!– End the Review –>
    <!–                –>

    <decision name="endreview">
       <transition name="rejected" to="rejected" />
       <transition name="approved" to="onapprove">
           <condition>#{wcmwf_approveCnt == wcmwf_reviewerCnt}</condition>
       </transition>
    </decision>  

    <task-node name="rejected">
        <task name="wcmwf:rejectedTask" swimlane="initiator" >
            <event type="task-assign">
                <script>
                    if (wcmwf_reviewCycle > 1)
                        taskInstance.description = taskInstance.description + " (" + wcmwf_reviewCycle + ")";
                </script>
            </event>
        </task>
        <transition name="abort" to="end" />
        <transition name="resubmit" to="serialorparallel">        <!– restart review process (next cycle) –>
           <script>
               <variable name="wcmwf_reviewCycle" access="read,write" />
               <expression>
                   wcmwf_reviewCycle = wcmwf_reviewCycle +1;
               </expression>
           </script>
        </transition>
    </task-node>

    <decision name="onapprove">
       <transition name="launchnow" to="submitted" />
       <transition name="launchpending" to="submitpending">
           <condition>#{wcmwf_launchDate != null}</condition>
       </transition>
    </decision>

    <task-node name="submitpending" end-tasks="true">
       <!– Updated by Lalit on July 12,2009 for Workflow customization.
       <task name="wcmwf:submitpendingTask" swimlane="initiator">
      <task name="wcmwf:submitpendingTask" swimlane="assignee">–>
      <task name="wcmwf:submitpendingTask" swimlane="assignee">      
           <event type="task-create">
              <script>
                 taskInstance.dueDate = wcmwf_launchDate;
              </script>
           </event>       
           <timer duedate="#{wcmwf_launchDate}" transition="launch" >
               <action class="org.alfresco.repo.workflow.jbpm.AlfrescoJavaScript">
                   <script>
                      logger.log("WCM Submission on 81209" + bpm_workflowDescription + " submitted at " + wcmwf_launchDate + " by " + person.properties.userName);
                   </script>
               </action>
           </timer>
        </task>
        <transition name="cancel" to="submitcancelled" />
        <transition name="launch" to="submitted" />
    </task-node>

    <task-node name="submitcancelled">
        <task name="wcmwf:submitcancelledTask" swimlane="initiator" />
        <transition name="" to="end" />
    </task-node>

    <task-node name="submitted" end-tasks="true">
         <!– Updated by Lalit on July 12,2009 for Workflow customization.
       <task name="wcmwf:submittedTask" swimlane="initiator">
      <task name="wcmwf:submittedTask" swimlane="assignee">–>
      
      <task name="wcmwf:submittedTask" swimlane="assignee">
            <timer duedate="5 seconds" transition="onsubmit">
                <action class="org.alfresco.repo.workflow.jbpm.AlfrescoJavaScript">
                    <script>
                        logger.log("WCM Submit Process: Triggering submit for on 81209" + bpm_workflowDescription);
                    </script>
                </action>
            </timer>
          

           <event type="task-end">
                <script>
                   <variable name="submitfailed" access="write"/>
                   <expression>submitfailed = false;</expression>
                </script>
          
               <action class="org.alfresco.repo.workflow.jbpm.AlfrescoJavaScript">
                   <script>
                       logger.log("WCM Submit Process: Start submit for on 81209" + bpm_workflowDescription + " (by " + person.properties.userName + ")");
                   </script>
               </action>
              
                <action class="org.alfresco.repo.workflow.jbpm.AlfrescoJavaScript">
                   <script>
                   <expression>                      
                     logger.log("Submit Process: Start submit for wcmwf:submit @ task-start " + bpm_workflowDescription);
                     logger.log("Submit Process: Start submit for wcmwf:submit @ task-start "+ person.properties.userName + ")"+"with status " +bpm_status);
                     var ecmsusername = person.properties.userName;
                     executionContext.setVariable("cmsusername", ecmsusername);
                     logger.log(" cmsusername @task-start"+ecmsusername);
                     var tid = executionContext.processInstance.getId();
                     executionContext.setVariable("tid", tid);
                     logger.log(" tid "+tid);
                     var execTask = executionContext.getTaskInstance().getId();
                      logger.log("Submit Process:execTask "+execTask);
                      executionContext.setVariable("execTask", execTask);
                   </expression>
                   </script>
               </action>    
      <action class="eu.europa.ejustice.bo.action.ContentJbpmStatus"/>
               <action class="org.alfresco.repo.avm.wf.AVMSubmitPackageHandler"/>
               <action class="org.alfresco.repo.avm.wf.AVMDeployHandler"/>
             
               <action class="org.alfresco.repo.workflow.jbpm.AlfrescoJavaScript">
                   <script>
                        logger.log("WCM Submit Process: End submit for @712" + bpm_workflowDescription + " (by " + person.properties.userName + ")");
                   </script>
               </action>
           </event>
        </task>
        <transition name="onsubmit" to="checkfailedsubmit">
         <exception-handler>
                <script>
               <variable name="submitfailed" access="write"/>
               <expression>
                        logger.log("WCM Submit Process: Submit failed for " + bpm_workflowDescription + " (by " + person.properties.userName + ")");
                  submitfailed = true;
               </expression>
            </script>
         </exception-handler>
        </transition>
    </task-node>

    <decision name="checkfailedsubmit">
        <transition name="failure" to="submitfailed">
           <condition>#{submitfailed == true}</condition>
        </transition>
        <transition name="success" to="end">
           <condition>#{submitfailed == false}</condition>
        </transition>
    </decision>

    <task-node name="submitfailed">
        <task name="wcmwf:submitfailedTask" swimlane="initiator"/>
        <transition name="" to="end"/>
    </task-node>

    <!–                 –>
    <!– End the Process –>
    <!–                 –>

    <end-state name="end"/>
   
    <event type="process-end">
        <action class="org.alfresco.repo.avm.wf.AVMRemoveAllSrcWebappsHandler"/>
        <action class="org.alfresco.repo.avm.wf.AVMReleaseTestServerHandler"/>
        <action class="org.alfresco.repo.avm.wf.AVMRemoveWFStoreHandler"/>
    </event>

</process-definition>

In this i am using my ActionHandler "eu.europa.ejustice.bo.action.ContentJbpmStatus" with following content to get submitted content details which is invoked from prcessdefintion file above:


package eu.europa.ejustice.bo.action;

import java.util.List;

import org.alfresco.repo.workflow.jbpm.JBPMSpringActionHandler;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.avm.AVMService;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.cmr.workflow.WorkflowService;
import org.apache.log4j.Logger;
import org.jbpm.JbpmConfiguration;
import org.jbpm.JbpmContext;
import org.jbpm.context.exe.ContextInstance;
import org.jbpm.graph.exe.ExecutionContext;
import org.springframework.beans.factory.BeanFactory;


/**
* Class to get jbpm approved/rejected status for a particular content item.
*
* @author JangraL
*
*/
public class ContentJbpmStatus extends JBPMSpringActionHandler {

   private static Logger logger = Logger.getLogger(ContentJbpmStatus.class);
   private static final long serialVersionUID = 1L;
   private ServiceRegistry services;
   private ContentService contentService;
   private WorkflowService workflowService;
   private AVMService avmServ;
   private AuthenticationService authserv;
   JbpmContext jbpmContext = null;

   @Override
   protected void initialiseHandler(BeanFactory factory) {
      logger.info("Inside initialiseHandler() of ContentJbpmStatus");
      services = (ServiceRegistry) factory
            .getBean(ServiceRegistry.SERVICE_REGISTRY);

      contentService = (ContentService) factory.getBean("contentService");

      workflowService = services.getWorkflowService();
      avmServ = services.getAVMService();
      authserv = services.getAuthenticationService();

   }

   public void execute(ExecutionContext executionContext) throws Exception {
      logger.info("Inside execute() of ContentJbpmStatus on 8 Dec 09 ");      
      NodeRef htmlNref = null;
      NodeRef xmlNref = null;
      String htmlId = null;
      String xmlId = null;
      String htmlName = null;
      String xmlName = null;
      String langCodeNew = null;
      try{
         Object tid = ctx.getVariable("tid");
         logger.debug("tid in execute() of ContentJbpmStatus on 81209" + tid);
         Object execTask = ctx.getVariable("execTask");
         String execTaskStr = execTask.toString();
         logger.debug("execTaskStr in execute() of ContentJbpmStatus " + execTaskStr);
         String execTaskStrFinal = null;
         String execTaskStrMod = execTaskStr.replace('.', ':');
         String[] execTaskArray = execTaskStrMod.split(":");
         
         jbpmContext = JbpmConfiguration.getInstance().createJbpmContext();
         
         if (execTaskArray != null) {
            logger.debug("Length execTaskArray in execute() of ContentJbpmStatus " + execTaskArray.length);
            execTaskStrFinal = execTaskArray[0];
            logger.debug("execTaskStrFinal in execute() of ContentJbpmStatus " + execTaskStrFinal);
         }
         String execTaskFinal = "jbpm$" + execTaskStrFinal;
         List<NodeRef> execTaskref = workflowService.getPackageContents(execTaskFinal);
         logger.debug("execTaskref " + execTaskref + " with "+ execTaskref.size());
         if (execTaskref != null && execTaskref.size() > 0) {
            for (int i = 0; i < execTaskref.size(); i++) {
               String taskidMain = execTaskref.get(i).getId();
               logger.debug(i + "execTaskref " + execTaskref.get(i));
               logger.debug(i + "execTaskref id " + taskidMain);
               logger.debug(i + "execTaskref node "+ execTaskref.get(i).getStoreRef());

            }
         }      
         if (execTaskref != null && execTaskref.size() > 0 && execTaskref.size() == 2) {
            htmlNref = execTaskref.get(0);
            String[] temp = htmlNref.toString().split("//");
            String msCode = temp[1].substring(0,2);
            
            logger.debug("htmlNref in execute() of ContentJbpmStatus " + htmlNref);
            xmlNref = execTaskref.get(1);
            logger.debug("xmlNref in execute() of ContentJbpmStatus " + xmlNref);
            htmlId = execTaskref.get(0).getId();
            logger.debug("htmlId in execute() of ContentJbpmStatus " + htmlId);
            xmlId = execTaskref.get(1).getId();
            logger.debug("xmlId in execute() of ContentJbpmStatus " + xmlId);
            String forHtmlName = htmlId;
            logger.debug("forHtmlName in execute() of ContentJbpmStatus " + forHtmlName);
            int positionNew = htmlId.indexOf("ROOT;cms;") + 9;
            htmlId = htmlId.substring(positionNew, htmlId.length());
            String taxId = htmlId.substring(0, htmlId.indexOf(";"));
            logger.debug("taxId in execute() of ContentJbpmStatus " + taxId);
            htmlName = forHtmlName.substring(forHtmlName.length() - 15);
            logger.debug("File Name in execute() of ContentJbpmStatus " + htmlName);
            xmlName = xmlId.substring(xmlId.length() - 14);
            logger.debug("xmlName in execute() of ContentJbpmStatus " + xmlName);
            langCodeNew = xmlName.substring(xmlName.length() - 6, xmlName
                  .length() - 4);
            logger.debug("langCode in execute() of ContentJbpmStatus " + langCodeNew);
            logger.debug("msCode in execute() of ContentJbpmStatus "+msCode);
            
         }
      }catch (Exception e) {
         logger.error("error in getting status "+e.getMessage());
         e.printStackTrace();
      }
      finally{
         logger.debug("Closing jbpm context on on 7 dec 09");
          jbpmContext.close();
          logger.error("After closing context on 81209 ");

      }
      
   }

}


Its giving what i want but i am getting this error and content is not getting submitted.

06:29:26,716 INFO  [STDOUT] 06:29:26,716  ERROR [job.executor.JobExecutorThread] problem committing job execution transaction
org.jbpm.JbpmException: closed JbpmContext in different order then they were created… check your try-finally's around JbpmContexts blocks
        at org.jbpm.JbpmConfiguration.popJbpmContext(JbpmConfiguration.java:573)
        at org.jbpm.JbpmConfiguration.jbpmContextClosed(JbpmConfiguration.java:585)
        at org.jbpm.JbpmContext.close(JbpmContext.java:144)
        at org.jbpm.job.executor.JobExecutorThread.executeJob(JobExecutorThread.java:184)
        at org.alfresco.repo.workflow.jbpm.AlfrescoJobExecutorThread.access$201(AlfrescoJobExecutorThread.java:43)
        at org.alfresco.repo.workflow.jbpm.AlfrescoJobExecutorThread$TransactionJob.execute(AlfrescoJobExecutorThread.java:138)
        at org.alfresco.repo.transaction.RetryingTransactionHelper.doInTransaction(RetryingTransactionHelper.java:322)
        at org.alfresco.repo.transaction.RetryingTransactionHelper.doInTransaction(RetryingTransactionHelper.java:229)
        at org.alfresco.repo.workflow.jbpm.AlfrescoJobExecutorThread.executeJob(AlfrescoJobExecutorThread.java:113)
        at org.jbpm.job.executor.JobExecutorThread.run(JobExecutorThread.java:64)
06:29:27,737 INFO  [STDOUT] 06:29:27,737  ERROR [repo.transaction.AlfrescoTransactionSupport] After completion (rolled-back) listener exception:
   listener: org.alfresco.repo.workflow.jbpm.JBPMTransactionTemplate@63362c51
org.jbpm.JbpmException: closed JbpmContext in different order then they were created… check your try-finally's around JbpmContexts blocks
        at org.jbpm.JbpmConfiguration.popJbpmContext(JbpmConfiguration.java:573)
        at org.jbpm.JbpmConfiguration.jbpmContextClosed(JbpmConfiguration.java:585)
        at org.jbpm.JbpmContext.close(JbpmContext.java:144)
        at org.springmodules.workflow.jbpm31.JbpmTemplate.releaseContext(JbpmTemplate.java:111)
        at org.alfresco.repo.workflow.jbpm.JBPMTransactionTemplate.afterRollback(JBPMTransactionTemplate.java:195)
        at org.alfresco.repo.transaction.AlfrescoTransactionSupport$TransactionSynchronizationImpl.afterCompletion(AlfrescoTransactionSupport.java:776)
        at org.springframework.transaction.support.TransactionSynchronizationUtils.invokeAfterCompletion(TransactionSynchronizationUtils.java:133)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.invokeAfterCompletion(AbstractPlatformTransactionManager.java:904)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerAfterCompletion(AbstractPlatformTransactionManager.java:879)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback(AbstractPlatformTransactionManager.java:782)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.rollback(AbstractPlatformTransactionManager.java:730)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.completeTransactionAfterThrowing(TransactionAspectSupport.java:332)
        at org.alfresco.util.transaction.SpringAwareUserTransaction.completeTransactionAfterThrowing(SpringAwareUserTransaction.java:561)
        at org.alfresco.util.transaction.SpringAwareUserTransaction.rollback(SpringAwareUserTransaction.java:531)
        at org.alfresco.repo.transaction.RetryingTransactionHelper.doInTransaction(RetryingTransactionHelper.java:383)
        at org.alfresco.repo.transaction.RetryingTransactionHelper.doInTransaction(RetryingTransactionHelper.java:229)
        at org.alfresco.repo.workflow.jbpm.AlfrescoJobExecutorThread.executeJob(AlfrescoJobExecutorThread.java:113)
        at org.jbpm.job.executor.JobExecutorThread.run(JobExecutorThread.java:64)
06:29:27,877 INFO  [STDOUT] 06:29:27,877  ERROR [job.executor.JobExecutorThread] exception in job executor thread. waiting 5000 milliseconds
org.jbpm.JbpmException: closed JbpmContext in different order then they were created… check your try-finally's around JbpmContexts blocks
        at org.jbpm.JbpmConfiguration.popJbpmContext(JbpmConfiguration.java:573)
        at org.jbpm.JbpmConfiguration.jbpmContextClosed(JbpmConfiguration.java:585)
        at org.jbpm.JbpmContext.close(JbpmContext.java:144)
        at org.jbpm.job.executor.JobExecutorThread.executeJob(JobExecutorThread.java:184)
        at org.alfresco.repo.workflow.jbpm.AlfrescoJobExecutorThread.access$201(AlfrescoJobExecutorThread.java:43)
        at org.alfresco.repo.workflow.jbpm.AlfrescoJobExecutorThread$TransactionJob.execute(AlfrescoJobExecutorThread.java:138)
        at org.alfresco.repo.transaction.RetryingTransactionHelper.doInTransaction(RetryingTransactionHelper.java:322)
        at org.alfresco.repo.transaction.RetryingTransactionHelper.doInTransaction(RetryingTransactionHelper.java:229)
        at org.alfresco.repo.workflow.jbpm.AlfrescoJobExecutorThread.executeJob(AlfrescoJobExecutorThread.java:113)
        at org.jbpm.job.executor.JobExecutorThread.run(JobExecutorThread.java:64)


To me it seems the order in which jbpmcontextes which are getting created and closed is mismatching as:

<action class="eu.europa.ejustice.bo.action.ContentJbpmStatus"/>
               <action class="org.alfresco.repo.avm.wf.AVMSubmitPackageHandler"/>
               <action class="org.alfresco.repo.avm.wf.AVMDeployHandler"/>

I think that for each of the ActionHandlers created above,there will be separate jbpmcontext created & closed.But i have put my actionhandler

<action class="eu.europa.ejustice.bo.action.ContentJbpmStatus"/>

Before others which may cause this issue.If so  :?: ..can anyone help me how to tackle this issue or atleast tell me how to get status with content which has been submitted.

Outcomes