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

Exception during async execution causes multiple instances of the same task being inserted to the database

XMLWordPrintable

      If a task is reached in an asynchronous execution and notification email sending (or any automated activity)
      throws an exception, new task instances are inserted to the database on every retry of the asynchronous job.

      ExecuteJobCmd creates a JobExceptionHandler to re-try the execution of the job.
      Since org.jbpm.jpdl.internal.activity.TaskActivity.execute() method is called on every retry,
      and this method creates a new task instance each time it is called, multiple instances of the
      same task with the same execution id will be inserted to the database.

      All operations that try to query the task by execution will fail due to a NonUniqueResultException.

      Example process definition: (note continue="async" attribute on start tag)

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

      <process name="task_error" xmlns="http://jbpm.org/4.0/jpdl">
      <start name="start1" g="93,78,48,48" continue="async">
      <transition name="to Test Task" to="Test Task" g="1,-20"/>
      </start>
      <end name="end1" g="315,236,48,48"/>

      <task name="Test Task" g="178,159,92,52" assignee="johnsmith">
      <notification>
      <to users="${task.assignee}"/>
      <cc addresses="invalid@email@address"/>
      <subject>${task.name}</subject>
      <text>
      <![CDATA[Hi ${task.assignee},
      Task "${task.name}" has been assigned to you.
      ${task.description}
      Sent by JBoss jBPM
      ]]>
      </text>
      </notification>

      <transition name="to end1" to="end1" g="-6,-22"/>
      </task>
      </process>

      The notification email will fail (email sender throws an exception) because of the invalid email address (invalid@email@address) that is set in CC tag.

      First run fails because of this invalid email address:

      SEVERE: exception while executing 'ExecuteActivityMessage[25]'
      org.jbpm.api.JbpmException: failed to add invalid@email@address to recipients of type Cc
      at org.jbpm.pvm.internal.email.impl.MailProducerImpl.fillRecipients(MailProducerImpl.java:197)
      at org.jbpm.pvm.internal.email.impl.MailProducerImpl.fillRecipients(MailProducerImpl.java:180)
      at org.jbpm.pvm.internal.email.impl.MailProducerImpl.produce(MailProducerImpl.java:79)
      at org.jbpm.jpdl.internal.activity.MailListener.notify(MailListener.java:56)
      at org.jbpm.pvm.internal.model.op.ExecuteEventListener.perform(ExecuteEventListener.java:81)
      at org.jbpm.pvm.internal.model.ExecutionImpl.performAtomicOperationSync(ExecutionImpl.java:637)
      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.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:197)
      at org.jbpm.pvm.internal.model.ExecutionImpl_$$javassist_4.performAtomicOperationSync(ExecutionImpl$$_javassist_4.java)
      at org.jbpm.pvm.internal.model.op.ExecuteActivityMessage.execute(ExecuteActivityMessage.java:46)
      at org.jbpm.pvm.internal.cmd.ExecuteJobCmd.execute(ExecuteJobCmd.java:74)
      at org.jbpm.pvm.internal.cmd.ExecuteJobCmd.execute(ExecuteJobCmd.java:41)
      at org.jbpm.pvm.internal.svc.DefaultCommandService.execute(DefaultCommandService.java:42)
      at org.jbpm.pvm.internal.spring.CommandTransactionCallback.doInTransaction(CommandTransactionCallback.java:50)
      at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:128)
      at org.jbpm.pvm.internal.tx.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:79)
      at org.jbpm.pvm.internal.svc.EnvironmentInterceptor.execute(EnvironmentInterceptor.java:54)
      at org.jbpm.pvm.internal.svc.RetryInterceptor.execute(RetryInterceptor.java:55)
      at org.jbpm.pvm.internal.jobexecutor.JobExecutorThread.run(JobExecutorThread.java:63)
      Caused by: javax.mail.internet.AddressException: Illegal character in domain in string ``invalid@email@address''
      at javax.mail.internet.InternetAddress.checkAddress(InternetAddress.java:947)
      at javax.mail.internet.InternetAddress.parse(InternetAddress.java:833)
      at javax.mail.internet.InternetAddress.parse(InternetAddress.java:569)
      at javax.mail.internet.InternetAddress.parse(InternetAddress.java:546)
      at org.jbpm.pvm.internal.email.impl.MailProducerImpl.fillRecipients(MailProducerImpl.java:194)
      ... 21 more

      First retry fails since there are two tasks with the same execution id in the database (query returns 2 results):

      SEVERE: exception while executing 'ExecuteActivityMessage[25]'
      org.hibernate.NonUniqueResultException: query did not return a unique result: 2
      at org.hibernate.impl.AbstractQueryImpl.uniqueElement(AbstractQueryImpl.java:844)
      at org.hibernate.impl.AbstractQueryImpl.uniqueResult(AbstractQueryImpl.java:835)
      at org.jbpm.pvm.internal.hibernate.DbSessionImpl.findTaskByExecution(DbSessionImpl.java:382)
      at org.jbpm.jpdl.internal.activity.MailListener.notify(MailListener.java:50)
      at org.jbpm.pvm.internal.model.op.ExecuteEventListener.perform(ExecuteEventListener.java:81)
      at org.jbpm.pvm.internal.model.ExecutionImpl.performAtomicOperationSync(ExecutionImpl.java:637)
      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.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:197)
      at org.jbpm.pvm.internal.model.ExecutionImpl_$$javassist_4.performAtomicOperationSync(ExecutionImpl$$_javassist_4.java)
      at org.jbpm.pvm.internal.model.op.ExecuteActivityMessage.execute(ExecuteActivityMessage.java:46)
      at org.jbpm.pvm.internal.cmd.ExecuteJobCmd.execute(ExecuteJobCmd.java:74)
      at org.jbpm.pvm.internal.cmd.ExecuteJobCmd.execute(ExecuteJobCmd.java:41)
      at org.jbpm.pvm.internal.svc.DefaultCommandService.execute(DefaultCommandService.java:42)
      at org.jbpm.pvm.internal.spring.CommandTransactionCallback.doInTransaction(CommandTransactionCallback.java:50)
      at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:128)
      at org.jbpm.pvm.internal.tx.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:79)
      at org.jbpm.pvm.internal.svc.EnvironmentInterceptor.execute(EnvironmentInterceptor.java:54)
      at org.jbpm.pvm.internal.svc.RetryInterceptor.execute(RetryInterceptor.java:55)
      at org.jbpm.pvm.internal.jobexecutor.JobExecutorThread.run(JobExecutorThread.java:63)

      Second retry fails since there are three tasks with the same execution id in the database (query returns 3 results):

      SEVERE: exception while executing 'ExecuteActivityMessage[25]'
      org.hibernate.NonUniqueResultException: query did not return a unique result: 3
      at org.hibernate.impl.AbstractQueryImpl.uniqueElement(AbstractQueryImpl.java:844)
      at org.hibernate.impl.AbstractQueryImpl.uniqueResult(AbstractQueryImpl.java:835)
      at org.jbpm.pvm.internal.hibernate.DbSessionImpl.findTaskByExecution(DbSessionImpl.java:382)
      at org.jbpm.jpdl.internal.activity.MailListener.notify(MailListener.java:50)
      at org.jbpm.pvm.internal.model.op.ExecuteEventListener.perform(ExecuteEventListener.java:81)
      at org.jbpm.pvm.internal.model.ExecutionImpl.performAtomicOperationSync(ExecutionImpl.java:637)
      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.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:197)
      at org.jbpm.pvm.internal.model.ExecutionImpl_$$javassist_4.performAtomicOperationSync(ExecutionImpl$$_javassist_4.java)
      at org.jbpm.pvm.internal.model.op.ExecuteActivityMessage.execute(ExecuteActivityMessage.java:46)
      at org.jbpm.pvm.internal.cmd.ExecuteJobCmd.execute(ExecuteJobCmd.java:74)
      at org.jbpm.pvm.internal.cmd.ExecuteJobCmd.execute(ExecuteJobCmd.java:41)
      at org.jbpm.pvm.internal.svc.DefaultCommandService.execute(DefaultCommandService.java:42)
      at org.jbpm.pvm.internal.spring.CommandTransactionCallback.doInTransaction(CommandTransactionCallback.java:50)
      at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:128)
      at org.jbpm.pvm.internal.tx.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:79)
      at org.jbpm.pvm.internal.svc.EnvironmentInterceptor.execute(EnvironmentInterceptor.java:54)
      at org.jbpm.pvm.internal.svc.RetryInterceptor.execute(RetryInterceptor.java:55)
      at org.jbpm.pvm.internal.jobexecutor.JobExecutorThread.run(JobExecutorThread.java:63)

      I believe org.jbpm.jpdl.internal.activity.TaskActivity.execute() method should be modified to try to look up the task instance first and create a new instance only if there is no existing one in the database:

      public void execute(ExecutionImpl execution) {
      DbSession dbSession = Environment.getFromCurrent(DbSession.class);
      TaskImpl task = dbSession.findTaskByExecution(execution);
      if(task == null) {
      task = (TaskImpl) dbSession.createTask();
      task.setTaskDefinition(taskDefinition);
      task.setExecution(execution);
      ...

            rebody HuiSheng Xu (Inactive)
            h.peter Peter Horvath (Inactive)
            Votes:
            2 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: