[jbpm-issues] [JBoss JIRA] Updated: (JBPM-2535) Exception during async execution causes multiple instances of the same task being inserted to the database

Tom Baeyens (JIRA) jira-events at lists.jboss.org
Tue Jan 5 05:08:37 EST 2010


     [ https://jira.jboss.org/jira/browse/JBPM-2535?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Tom Baeyens updated JBPM-2535:
------------------------------

    Assignee: Koen Aers  (was: Tom Baeyens)


> 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: Koen Aers
>            Priority: Critical
>             Fix For: jBPM 4.4
>
>
> 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 at 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 at 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 at 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 at 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: https://jira.jboss.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        


More information about the jbpm-issues mailing list