Possible bug in BusinessProcess.resumeProcess()
cerker Oct 30, 2008 12:40 PMHello,
we're using Seam 2.0.2 SP1, and detected the following behaviour:
when calling BusinessProcess.resumeProcess(id) with a non-existent processId, the following exception gets thrown when seam cleans up the contexts:
Caused by: java.lang.NullPointerException at org.jboss.seam.bpm.BusinessProcess.hasActiveProcess(BusinessProcess.java:62) at org.jboss.seam.contexts.Contexts.flushAndDestroyContexts(Contexts.java:347) at org.jboss.seam.contexts.Lifecycle.endCall(Lifecycle.java:96) at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:122) at org.jboss.seam.intercept.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:50) at sun.reflect.GeneratedMethodAccessor212.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:585) at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:118) at org.jboss.ejb3.interceptor.EJB3InterceptorsInterceptor.invoke(EJB3InterceptorsInterceptor.java:63) at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101) at org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor.invoke(TransactionScopedEntityManagerInterceptor.java:54) at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101) at org.jboss.ejb3.AllowedOperationsInterceptor.invoke(AllowedOperationsInterceptor.java:47) at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101) at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:79) ... 36 more
Taking a look at the source code of BusinessProcess.java, we found that resumeProcess() stores the processId, no matter if the process exists or not:
public boolean resumeProcess(Long processId) { setProcessId(processId); ProcessInstance process = org.jboss.seam.bpm.ProcessInstance.instance(); return afterResumeProcess(processId, process); }
Later, hasActiveProcess() checks for that processId, and tries to invoke a process instance if the id is found:
public boolean hasActiveProcess() { return hasCurrentProcess() && !org.jboss.seam.bpm.ProcessInstance.instance().hasEnded(); } public boolean hasCurrentProcess() { return processId!=null; }
We did a workaround like this to avoid the nullpointer:
boolean exists = bprocess.resumeProcess(pId); if(!exists) { bprocess.setProcessId(null); }
To us, it seems like an error that resumeProcess() doesn't clean up the state of the business process when the processId is not found.