]
Tom Baeyens updated JBPM-2535:
------------------------------
Fix Version/s: jBPM 4.3
(was: jBPM 4.x)
Assignee: Tom Baeyens
Priority: Critical (was: Major)
Exception during async execution causes multiple instances of the
same task being inserted to the database
----------------------------------------------------------------------------------------------------------
Key: JBPM-2535
URL:
https://jira.jboss.org/jira/browse/JBPM-2535
Project: jBPM
Issue Type: Bug
Security Level: Public(Everyone can see)
Components: Runtime Engine
Affects Versions: jBPM 4.x
Reporter: Peter Horvath
Assignee: Tom Baeyens
Priority: Critical
Fix For: jBPM 4.3
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);
...
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: