Uploaded image for project: 'jBPM'
  1. jBPM
  2. JBPM-5870

ExternalTaskEventListener.completeWorkItem() hanging due to No active JTA transaction on joinTransaction

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • Major
    • None
    • jBPM 6.5.0.Final
    • Persistence, Runtime Engine
    • NEW
    • NEW

    Description

      I have a SpringBoot/jBPM app and am observing that

      ExternalTaskEventListener.completeWorkItem() 
      

      is hanging when trying to complete a work Item for a task, but only on the second time it is invoked. This causes our workflows not to complete, and hence is a blocker.

      Recap:

       The app [SpringBoot/jBPM 6.5.0] starts a top-level process workflow which starts a subprocess, and the subprocess executes 5 steps sequentially with each step being a bpmn
       All of the steps except 2 are simple and have only start > script task > end and are basic no-ops
       2 of the steps – pickup and delivery – start human tasks: start > script task > human task > script task > end
       The script tasks just display messages, so they are basically no-ops
       So the subprocess sequence is
      1. Assignment [simple no-op
      2. Procurement [simple no-op]
      3. Pickup [starts human task]
      4. Delivery [starts human task]
      5. Confirmation [simple no-op]
      I.e.
      Start > Assignment > Procurement > Pickup > Delivery > Confirmation > End

       REST endpoints drive the workflow. The critical endpoints are:
       /create: starts the top-level which starts the subprocess, which proceeds immediately through steps 1 and 2, enters node 3 and creates the task. Sends correlation key and task Id of first human task – in pickup - as response
       /start: starts a task; takes correlation key and task ID as inputs
       /complete: completes a task: takes correlation key and task ID as inputs

       Local environment configured to use out-of-the-box JPA with H2 and JTA

      What I am observing now:
       /create runs successfully, starts the workflow, subprocess, and creates the first human task in the workflow in pickup
       /start runs successfully and starts the pickup human task. Verified the state of the processes and task in H2 [using the H2 console]
       /complete runs successfully and completes the pickup human task and creates the delivery pickup task. Verified the state of the processes and task in H2 [using the H2 console]
       /start runs successfully and starts the delivery human task. Verified the state of the processes and tasks in H2 [using the H2 console]: pickup is completed and delivery is in progress
       /complete hangs and is doing so on a call to

      ExternalTaskEventListener.completeWorkItem()
      

      . [NB: ExternalTaskEventListener is required to be registered in order to enable task completion, per my understanding. This is being done in the RegisterableItemsFactory, but the registrations get cleared by the engine while trying to retrieve process variables. I resorted to adding a manual registration just before calling

      taskService.complete() 
      

      to try to make sure that tasks get completed]

      The call to

       ExternalTaskEventListener.completeWorkItem() 
      

      ultimately invokes

      org.drools.persistence.SingleSessionCommandService.TransactionInterceptor.execute() 
      

      [code snippet below] and throws this TransationRequired exception when invoking
      persistenceContext.joinTransaction():

      javax.persistence.TransactionRequiredException: No active JTA transaction on joinTransaction call
      
      

      It is expecting a transaction to be active but there is none.

      I ran in the debugger and this code is executed during both /start and /complete, and executes successfully on /start pickup, /complete pickup, and /start delivery, meaning that there is at least one transaction active at those points in time. It is very strange indeed that it would hang on /complete delivery.

      The path through the application is straightforward for /start and /complete: the REST controller endpoints invoke corresponding methods in a helper service class that invokes taskService.create() and taskService.complete() respectively and is independent of which step in the process is executing.

      The app only interacts via the jBPM API, and the persistence and transaction are being done completely by it behind the scenes.

      Here is another very curious observation: As a test, a human task was added in the last step, confirmation. What happens then is that delivery completes and it hangs on the completion in the confirmation step. So apparently there is something about completing a human task in the last step. A clue but still no idea as to the root cause.

      Attached are screenshots of the bpmn2 diagrams for the master process, subprocess, pickup and delivery worksflows [NB: the "Process suborders" node in the master process is a multi-instance invocation of the subprocess workflow.]

      Questions:

      • Have I provided enough information?
      • Any idea what this might be?
      • How can it be diagnosed?
      • Alternatives/workaround?
      • Anything the app can do?
      package org.drools.persistence;
      private class TransactionInterceptor extends AbstractInterceptor
      
              public <T> T execute(Command<T> command) {
                  if (command instanceof UnpersistableCommand) {
                      throw new UnsupportedOperationException("Command " + command + " cannot be issued on a persisted session");
                  }
      
                  if (command instanceof DisposeCommand) {
                      T result = executeNext( command );
                      jpm.dispose();
                      return result;
                  }
      
                  // Open the entity manager before the transaction begins.
                  PersistenceContext persistenceContext = jpm.getApplicationScopedPersistenceContext();
      
                  boolean transactionOwner = false;
                  try {
                      transactionOwner = txm.begin();
                      
                   persistenceContext.joinTransaction();
                      
                      initExistingKnowledgeSession( sessionInfo.getId(),
                              marshallingHelper.getKbase(),
                              marshallingHelper.getConf(),
                              persistenceContext );
      
                      jpm.beginCommandScopedEntityManager();
      
                      registerRollbackSync();
      
                      if (txm != null) {
                          ObjectMarshallingStrategy[] strategies = (ObjectMarshallingStrategy[]) env.get(EnvironmentName.OBJECT_MARSHALLING_STRATEGIES);
      
                          for (ObjectMarshallingStrategy strategy : strategies) {
                              if (strategy instanceof TransactionAware) {
                                  ((TransactionAware) strategy).onStart(txm);
                              }
                          }
                      }
      
                      T result = null;
                      if( command instanceof BatchExecutionCommand) {
                          // Batch execution requires the extra logic in
                          //  StatefulSessionKnowledgeImpl.execute(Context,Command);
                          result = ksession.execute(command);
                      }
                      else {
                          logger.trace("Executing " + command.getClass().getSimpleName());
                          result = executeNext(command);
                      }
                      registerUpdateSync();
                      txm.commit( transactionOwner );
      
                      return result;
      
                  } catch ( RuntimeException re ) {
                      rollbackTransaction( re,
                              transactionOwner );
      
      
      
      

      Attachments

        Activity

          People

            swiderski.maciej Maciej Swiderski (Inactive)
            fmbulah_jira Fred Bulah (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated: