[jboss-user] [JBoss jBPM] - Actions and async=
jeffj55374
do-not-reply at jboss.com
Thu Aug 9 14:25:17 EDT 2007
org.jbpm.JbpmException: token '18547' can't be locked by 'job[18548]' cause it's already locked by 'token[18547]'
Full stack trace, process definition, action handler are all below.
Environment
jBPM 3.2.1
| Standalone Java 1.6 (no appserver)
| Actions and async="true" don't mix.
| JobExecutor is configured for one thread.
| Hibernate 3.2.4.sp1
| Oracle 10g
|
|
| Summary:
| 1. Token is signaled to start the process.
| 2. Token transitions to node1 from the start node.
| 3. Node one has an action handler defined so Node.execute(...) calls GraphElement.executeAction() which locks the token.
| 4. The action handler calls ctx.leaveNode after it does its work. (Section 9.5 of the user guide states: "Note the difference
| between an action that is placed in an event versus an action that is placed in a node. Actions that are put in an event
| are executed when the event fires. Actions on events have no way to influence the flow of control of the process.
| It is similar to the observer pattern. On the other hand, an action that is put on a node has the responsibility of propagating the execution.
| 5. ctx.leaveNode on Node1 ultimately results in Node.enter() being called on Node2
| 6. Since Node2 is an async node, rather than executing the node, the code prepares for an async continuation.
| 7. After sending the message the code attempts to lock the token, but it already locked as a result of #3
| // execute the node
| if (isAsync) {
| ExecuteNodeJob job = createAsyncContinuationJob(token);
| MessageService messageService = (MessageService) Services.getCurrentService(Services.SERVICENAME_MESSAGE);
| messageService.send(job);
| token.lock(job.toString()); // ** THIS IS THE PROBLEM LINE!!!! ***
| } else {
| execute(executionContext);
| }
|
| The conflict:
| Javadoc for Token.lock():
| /**
| * locks a process instance for further execution. A locked token
| * cannot continue execution. This is a non-persistent
| * operation. This is used to prevent tokens being propagated during
| * the execution of actions.
| * @see #unlock(String)
| */
| public void lock(String lockOwnerId) {
|
| But Section 9.5 of the user's guide says that an action is responsible for propagating the execution, but the token is locked in an attempt to propagate it.
|
| I'm currently trying to understand the design and come up with a solution to allow my process to run as designed.
| What I don't understand yet is why the token is used to prevent propagation or why the code in Node.execute is trying to lock the token with the job id.
| Should the code unlock the token and then lock it with the job? Is the token lock really necessary?
| If I remove the action fron Node 1, things work fine.
|
| Possibly related to http://jira.jboss.com/jira/browse/JBPM-983. Similar, but a little different twist
|
| Any ideas?
|
| Once I research this a little more, I might submit a bug, but I'd like a little feedback to verify that I'm on the right track.
|
| Thanks for your help.
|
| Full stack trace:
|
| org.jbpm.JbpmException: token '18547' can't be locked by 'job[18548]' cause it's already locked by 'token[18547]'
| at org.jbpm.graph.exe.Token.lock(Token.java:646)
| at org.jbpm.graph.def.Node.enter(Node.java:316)
| at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
| at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
| at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
| at java.lang.reflect.Method.invoke(Unknown Source)
| at org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer.invoke(CGLIBLazyInitializer.java:157)
| at org.jbpm.graph.def.Node$$EnhancerByCGLIB$$dc89a302.enter()
| at org.jbpm.graph.def.Transition.take(Transition.java:151)
| at org.jbpm.graph.def.Node.leave(Node.java:393)
| at org.jbpm.graph.def.Node.leave(Node.java:357)
| at org.jbpm.graph.exe.ExecutionContext.leaveNode(ExecutionContext.java:120)
| at com.digitalriver.mds.jbpm.SampleActionHandler.execute(SampleActionHandler.java:46)
| at org.jbpm.graph.def.Action.execute(Action.java:122)
| at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
| at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
| at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
| at java.lang.reflect.Method.invoke(Unknown Source)
| at org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer.invoke(CGLIBLazyInitializer.java:157)
| at org.jbpm.graph.def.Action$$EnhancerByCGLIB$$5863de36.execute()
| at org.jbpm.graph.def.GraphElement.executeAction(GraphElement.java:255)
| at org.jbpm.graph.def.Node.execute(Node.java:338)
| at org.jbpm.graph.def.Node.enter(Node.java:318)
| at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
| at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
| at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
| at java.lang.reflect.Method.invoke(Unknown Source)
| at org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer.invoke(CGLIBLazyInitializer.java:157)
| at org.jbpm.graph.def.Node$$EnhancerByCGLIB$$dc89a302.enter()
| at org.jbpm.graph.def.Transition.take(Transition.java:151)
| at org.jbpm.graph.def.Node.leave(Node.java:393)
| at org.jbpm.graph.node.StartState.leave(StartState.java:70)
| at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
| at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
| at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
| at java.lang.reflect.Method.invoke(Unknown Source)
| at org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer.invoke(CGLIBLazyInitializer.java:157)
| at org.jbpm.graph.def.Node$$EnhancerByCGLIB$$dc89a302.leave()
| at org.jbpm.graph.exe.Token.signal(Token.java:194)
| at org.jbpm.graph.exe.Token.signal(Token.java:139)
| at com.digitalriver.proto.StandaloneSample.runStandaloneSample(StandaloneSample.java:89)
| at com.digitalriver.proto.StandaloneSample.run(StandaloneSample.java:130)
| at com.digitalriver.proto.StandaloneSample.main(StandaloneSample.java:40)
|
|
|
|
| The Job Executor bean config
|
| <bean id="jbpm.job.executor" class="org.jbpm.job.executor.JbpmJobExecutor">
| | <property name="jbpmConfiguration" ref="jbpmConfiguration" />
| | <property name="name" value="JbpmJobExector"/>
| | <property name="nbrOfThreads" value="1"/>
| | <property name="idleInterval" value="5000"/>
| | <property name="maxIdleInterval" value="300000"/>
| | <property name="historyMaxSize" value="20"/>
| | <property name="maxLockTime" value="600000"/> <!-- 10 minutes -->
| | <property name="lockMonitorInterval" value="60000"/> <!-- 1 minute -->
| | <property name="lockBufferTime" value="5000"/> <!-- 5 seconds -->
| | </bean>
|
|
| The Process Definition
|
| <?xml version="1.0" encoding="UTF-8"?>
| |
| | <process-definition
| | xmlns="" name="StandaloneSample">
| | <start-state name="start">
| | <transition name="" to="node1"></transition>
| | </start-state>
| | <end-state name="end1"></end-state>
| | <node name="node1">
| | <action class="com.digitalriver.mds.jbpm.SampleActionHandler"></action>
| | <transition name="" to="node2"></transition>
| | </node>
| | <node async="true" name="node2">
| | <action class="com.digitalriver.mds.jbpm.SampleActionHandler"></action>
| | <transition name="" to="end1"></transition>
| | </node>
| | </process-definition>
|
| The action handler
| package com.digitalriver.mds.jbpm;
| |
| | /** Copyright (c) Digital River, Inc. All rights reserved. 2007
| | * Filename: SampleActionHandler.java
| | * Author: @author
| | */
| |
| |
| | import java.io.FileWriter;
| |
| | import org.apache.commons.logging.Log;
| | import org.apache.commons.logging.LogFactory;
| | import org.jbpm.context.exe.ContextInstance;
| | import org.jbpm.graph.def.ActionHandler;
| | import org.jbpm.graph.exe.ExecutionContext;
| |
| | /**
| | * @author jpjohnson
| | *
| | */
| | public class SampleActionHandler
| | implements ActionHandler {
| |
| | /**
| | *
| | */
| | private static final long serialVersionUID = 1L;
| | @SuppressWarnings("unused")
| | private static final Log log = LogFactory.getLog(SampleActionHandler.class);
| |
| | /* (non-Javadoc)
| | * @see org.jbpm.graph.def.ActionHandler#execute(org.jbpm.graph.exe.ExecutionContext)
| | */
| | public void execute(final ExecutionContext ctx) throws Exception
| | {
| | log.debug("JPJ execute called for task " + ctx.getNode().getName() +
| | " action " + ctx.getAction().getName());
| |
| | ContextInstance contextInstance = ctx.getProcessInstance().getContextInstance();
| | Integer id = (Integer) contextInstance.getVariable("MyID");
| |
| | FileWriter file = new FileWriter("Node-" + ctx.getNode().getName() + " PI-" +
| | ctx.getProcessInstance().getId() + ".txt");
| | file.write("Test output: Process ID " + id);
| | file.close();
| |
| | ctx.leaveNode();
| | // ctx.getToken().signal();
| | }
| |
| | }
| |
|
|
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4072679#4072679
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4072679
More information about the jboss-user
mailing list