-
1. Re: process instance persistence and reexecution
dharraj Jan 10, 2006 2:13 PM (in response to dharraj)Can any one out there help me PLEASE.
Raj -
2. Re: process instance persistence and reexecution
enazareno Jan 10, 2006 6:57 PM (in response to dharraj)Hi Raj,
First, I would not suggest you save process instance inside an action handler. Normally, you would place saving of instances in a servlet or probably a session bean.
Second, I think the error is in your defintion. You have set the transition to a node that does not exist. Review the definition or you can post it.
Regards,
Elmo -
3. Re: process instance persistence and reexecution
dharraj Jan 17, 2006 7:55 PM (in response to dharraj)Hello Elmo,
First of all, thanks a lot for your reply. Here is the process definition.<?xml version="1.0" encoding="UTF-8"?> <process-definition xmlns="http://jbpm.org/3/jpdl" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jbpm.org/3/jpdl http://jbpm.org/xsd/jpdl-3.0.xsd" name="dbexample"> <start-state name="start"> <transition name="tr1" to="first"></transition> </start-state> <end-state name="end"></end-state> <node name="first"> <action class="jpl.mipl.pgs.test.Testing"> <leaveNode>true</leaveNode> <waitTimeBound>2000</waitTimeBound> </action> <transition name="tr1" to="second"></transition> </node> <node name="second"> <action class="jpl.mipl.pgs.test.Testing"> <leaveNode>true</leaveNode> <waitTimeBound>8000</waitTimeBound> </action> <transition name="tr1" to="end"></transition> </node> </process-definition>
I was using jBPM 3.0.1. I switched to jBPM 3.0.2 and now I am getting the following exception running the above process definition.java.lang.RuntimeException: couldn't save process instance 'org.jbpm.graph.exe.ProcessInstance@5a2eaa' at org.jbpm.db.GraphSession.saveProcessInstance(GraphSession.java:209) at jpl.mipl.pgs.jbpm.action.ActionUponTransition.execute(ActionUponTransition.java:53) at org.jbpm.graph.def.Action.execute(Action.java:79) at org.jbpm.graph.def.GraphElement.executeActions(GraphElement.java:186) at org.jbpm.graph.def.GraphElement.fireAndPropagateEvent(GraphElement.java:149) at org.jbpm.graph.def.GraphElement.fireEvent(GraphElement.java:133) at org.jbpm.graph.def.Transition.take(Transition.java:79) at org.jbpm.graph.def.Node.leave(Node.java:349) at org.jbpm.graph.node.StartState.leave(StartState.java:73) at org.jbpm.graph.exe.Token.signal(Token.java:127) at org.jbpm.graph.exe.Token.signal(Token.java:92) at org.jbpm.graph.exe.ProcessInstance.signal(ProcessInstance.java:201) at jpl.mipl.pgs.jbpm.JBPMExeEngine.execute(JBPMExeEngine.java:469) at jpl.mipl.pgs.jbpm.JBPMExeEngine.main(JBPMExeEngine.java:529) Caused by: java.lang.RuntimeException: couldn't save process log 'transition[start-->unnamed-node]' at org.jbpm.db.LoggingSession.saveProcessLog(LoggingSession.java:101) at org.jbpm.db.LoggingSession.saveLogs(LoggingSession.java:87) at org.jbpm.db.GraphSession.saveProcessInstance(GraphSession.java:204) ... 13 more Caused by: org.hibernate.exception.GenericJDBCException: could not insert: [org.jbpm.graph.log.TransitionLog] at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:91) at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:79) at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43) at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:1986) at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2405) at org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:37) at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:243) at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:269) at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:167) at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:101) at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:186) at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:33) at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:175) at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:27) at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70) at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:544) at org.hibernate.impl.SessionImpl.save(SessionImpl.java:533) at org.hibernate.impl.SessionImpl.save(SessionImpl.java:529) at org.jbpm.db.LoggingSession.saveProcessLog(LoggingSession.java:97) ... 15 more Caused by: java.sql.SQLException: File input/output error: ./temp/.log in statement [insert into JBPM_LOG (INDEX_, DATE_, TOKEN_, PARENT_, TRANSITION_, SOURCENODE_, DESTINATIONNODE_, CLASS_, ID_) values (?, ?, ?, ?, ?, ?, ?, 'T', null)] at org.hsqldb.jdbc.Util.throwError(Unknown Source) at org.hsqldb.jdbc.jdbcPreparedStatement.executeUpdate(Unknown Source) at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeUpdate(NewProxyPreparedStatement.java:104) at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:1976) ... 30 more OOOOOOOOOOOOOOkay got it... org.jbpm.graph.def.DelegationException at org.jbpm.graph.def.GraphElement.raiseException(GraphElement.java:299) at org.jbpm.graph.def.GraphElement.raiseException(GraphElement.java:293) at org.jbpm.graph.def.GraphElement.executeActions(GraphElement.java:195) at org.jbpm.graph.def.GraphElement.fireAndPropagateEvent(GraphElement.java:149) at org.jbpm.graph.def.GraphElement.fireEvent(GraphElement.java:133) at org.jbpm.graph.def.Transition.take(Transition.java:79) at org.jbpm.graph.def.Node.leave(Node.java:349) at org.jbpm.graph.node.StartState.leave(StartState.java:73) at org.jbpm.graph.exe.Token.signal(Token.java:127) at org.jbpm.graph.exe.Token.signal(Token.java:92) at org.jbpm.graph.exe.ProcessInstance.signal(ProcessInstance.java:201) at jpl.mipl.pgs.jbpm.JBPMExeEngine.execute(JBPMExeEngine.java:469) at jpl.mipl.pgs.jbpm.JBPMExeEngine.main(JBPMExeEngine.java:529) Caused by: java.lang.NullPointerException at jpl.mipl.pgs.jbpm.DefaultExceptionHandler.handleException(DefaultExceptionHandler.java:36) at org.jbpm.graph.def.GraphElement.raiseException(GraphElement.java:279) ... 12 more
Please let me know if you need more info. Again, thanks for your help.
Sincerely,
Raj -
4. Re: process instance persistence and reexecution
enazareno Jan 17, 2006 8:18 PM (in response to dharraj)Hi Raj,
Try adding an event in your node example:<node name="first"> <event type="node-enter"> <action class="jpl.mipl.pgs.test.Testing"> <leaveNode>true</leaveNode> <waitTimeBound>2000</waitTimeBound> </action> </event> <transition name="tr1" to="second"></transition> </node>
In your first post, I think this is what happened. The process executed normally however you were waiting for the action to happen which did not. When you clicked on signal, being not a wait state, it has thrown the error "couldn't signal token 'Token(/)' : couldn't leave node 'null' over
its default transition" because the process has already ended. Try also checking the jbpm_action table if there are entries. I could be mistaken.
Regards,
Elmo -
5. Re: process instance persistence and reexecution
dharraj Jan 18, 2006 4:07 PM (in response to dharraj)Hello Elmo,
Again many thanks for you reply.
I did added the action to "node-enter" event but it did not changed any thing. Let me try to elaborate on exactly what I am doing. I have a jBPM execution engine that first adds a generic action handler to each transition. The action handler prints a message stating the name of the "from" node and "to" node and also saves process instance into database. The engine than saves the modified process definition and creates process instance using the modified process definition and runs the process instance by calling signal() on it. In the test jBPM process, I only have node and each node has an action handler associated with it that waits for specified time and than calls executionContext.leaveNode(). If I do not interrupt the execution, all works fine and I do see entries into the process definition, process instance and action table. However, when I interrupt the process instance execution (by Ctrl-C when the action handler on the second node is waiting) and try to rerun the process instance I get the null node exception. The 'End' attribute of the process instance table has null value in this case and the 'isabletoreactiveparent' attrubute of the token table has value 'true' in it (see below for the few of the table contents). The one thing I am not able so sure about is in what table does it specify where the process instance should (re)start from? Is it some combination of action/transition table?
Please give any help you can. Thanks again for your time and help.
Thanks
Raj
Process Instance Table:ID_ START_ END_ PROCESSDEFINITION_ ROOTTOKEN_ SUPERPROCESSTOKE N_ --- ----------------------------- ----------------------------- ------------------ ---------- ---------------- -- 1 2006-01-18 12:11:47.411000000 2006-01-18 12:11:58.155000000 1 1 (null) 2 2006-01-18 12:16:16.520000000 (null) 2 2 (null)
Action table (only non-null attributes):ID_ CLASS ISPROPAGATIONALLOWED_ ACTIONDELEGATION_ EVENT_ EVENTINDEX_ --- ----- --------------------- ----------------- ------ ----------- 1 A true 1 1 0 2 A true 2 1 1 3 A true 3 2 0 4 A true 4 3 0 5 A true 5 4 0 6 A true 6 5 0 7 A true 7 6 0 8 A true 8 6 1 9 A true 9 7 0 10 A true 10 8 0 11 A true 11 9 0 12 A true 12 10 0
Delegation table:ID_ CLASSNAME_ CONFIGURATION_ CONFIGTYPE_ PROCE SSDEFINITION_ --- --------------------------------------------- ------------------------------------------------------------ -------------------------------------------------------------------------------------------- ----------- ----- ------------- 1 jpl.mipl.pgs.jbpm.action.SetUpEnv <UPFFileName>/project/rt/dev/rrp/pgs/test/upfDir/testJBPM.up f</UPFFileName> (null) (null ) 2 jpl.mipl.pgs.jbpm.action.ActionUponTransition <toNode>first</toNode><fromNode>start</fromNode> (null) (null ) 3 jpl.mipl.pgs.test.Testing <leaveNode xmlns="http://jbpm.org/3/jpdl">true</leaveNode> <waitTimeBound xmlns="http://jbpm.org/3/jpdl">2000</waitTimeBound> (null) 1 4 jpl.mipl.pgs.jbpm.action.ActionUponTransition <toNode>second</toNode><fromNode>first</fromNode> (null) (null ) 5 jpl.mipl.pgs.test.Testing <leaveNode xmlns="http://jbpm.org/3/jpdl">true</leaveNode> <waitTimeBound xmlns="http://jbpm.org/3/jpdl">8000</waitTimeBound> (null) 1 6 jpl.mipl.pgs.jbpm.action.ActionUponTransition <toNode>end</toNode><fromNode>second</fromNode> (null) (null ) 7 jpl.mipl.pgs.jbpm.action.SetUpEnv <UPFFileName>/project/rt/dev/rrp/pgs/test/upfDir/testJBPM.up f</UPFFileName> (null) (null ) 8 jpl.mipl.pgs.jbpm.action.ActionUponTransition <toNode>first</toNode><fromNode>start</fromNode> (null) (null ) 9 jpl.mipl.pgs.test.Testing <leaveNode xmlns="http://jbpm.org/3/jpdl">true</leaveNode> <waitTimeBound xmlns="http://jbpm.org/3/jpdl">2000</waitTimeBound> (null) 2 10 jpl.mipl.pgs.jbpm.action.ActionUponTransition <toNode>second</toNode><fromNode>first</fromNode> (null) (null ) 11 jpl.mipl.pgs.test.Testing <leaveNode xmlns="http://jbpm.org/3/jpdl">true</leaveNode> <waitTimeBound xmlns="http://jbpm.org/3/jpdl">8000</waitTimeBound> (null) 2 12 jpl.mipl.pgs.jbpm.action.ActionUponTransition <toNode>end</toNode><fromNode>second</fromNode> (null) (null )
Event table:ID_ EVENTTYPE_ TYPE_ GRAPHELEMENT_ PROCESSDEFINITION_ NODE_ TRANSITION_ TASK_ --- ---------- ----- ------------- ------------------ ------ ----------- ------ 1 transition T 1 (null) (null) 1 (null) 2 node-enter N 3 (null) 3 (null) (null) 3 transition T 2 (null) (null) 2 (null) 4 node-enter N 4 (null) 4 (null) (null) 5 transition T 3 (null) (null) 3 (null) 6 transition T 4 (null) (null) 4 (null) 7 node-enter N 7 (null) 7 (null) (null) 8 transition T 5 (null) (null) 5 (null) 9 node-enter N 8 (null) 8 (null) (null)
Node table:ID_ CLASS_ NAME_ PROCESSDEFINITION_ ACTION_ SUPERSTATE_ SUBPROCESSDEFINITION_ DECISIONDELEGATION SIGNAL_ CREA TETASKS_ NODECOLLECTIONINDEX_ --- ------ ------ ------------------ ------- ----------- --------------------- ------------------ ------- ---- -------- -------------------- 1 R start 1 (null) (null) (null) (null) (null) (nul l) 0 2 E end 1 (null) (null) (null) (null) (null) (nul l) 1 3 N first 1 (null) (null) (null) (null) (null) (nul l) 2 4 N second 1 (null) (null) (null) (null) (null) (nul l) 3 5 R start 2 (null) (null) (null) (null) (null) (nul l) 0 6 E end 2 (null) (null) (null) (null) (null) (nul l) 1 7 N first 2 (null) (null) (null) (null) (null) (nul l) 2 8 N second 2 (null) (null) (null) (null) (null) (nul l) 3
Transition table:ID_ NAME_ PROCESSDEFINITION_ FROM_ TO_ FROMINDEX_ --- ----- ------------------ ----- --- ---------- 1 tr1 1 1 3 0 2 tr1 1 3 4 0 3 tr1 1 4 2 0 4 tr1 2 5 7 0 5 tr1 2 7 8 0 6 tr1 2 8 6 0
-
6. Re: process instance persistence and reexecution
enazareno Jan 18, 2006 7:37 PM (in response to dharraj)Hi,
Couple of questions.
Are you referring to/calling another process inside the action handler?The action handler prints a message stating the name of the "from" node and "to" node and also saves process instance into database.
Are you modifying another process definition inside your action handler??The engine than saves the modified process definition and creates process instance using the modified process definition and runs the process instance by calling signal() on it
If you interrupt or break a process, a desired behavior would be to rollback all transactions including the external process called and retains the old state. If you get a null node then it has probably persisted something and was not able to rollback.However, when I interrupt the process instance execution (by Ctrl-C when the action handler on the second node is waiting)
By the way, I am using 3.1 beta using CMT. Transactions are already automatically handled. I have not tried interrupting it though. If you're using web only, I can't relate how to handle transactions. Why dont you check out the newer version if you have the time.
Regards,
Elmo -
7. Re: process instance persistence and reexecution
dharraj Jan 18, 2006 8:08 PM (in response to dharraj)Hello Almo
Are you referring to/calling another process inside the action handler?
I am not referring or calling another process inside the action handler. The action handler's main job is to save the process instance.Are you modifying another process definition inside your action handler
No. My modification, I was referring to the process definition that have the action handler added each of it's transition.
What I am trying to do is as processing at each node is completed, save the process instance so if the processing at next node fails, I can start rerunning from the same node where the failure occured. For the example process definition listed below, say if the processing at node 'second' fails, then I want to start reprocessing from state 'second'.
I think I can justify why I was getting the exception (I may very well be wrong). I was saving process instance upon each transition. However, which node of the transition is associated with the token at that point is not clear to me. I think this is why the exception stating 'null' node.
I modified to store process instance in a action handler that is executed upon node enter event. Now I am getting the following exception when I try to resume.org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: org.jbpm.graph.def.Node.leavingTransitions, no session or session was closed at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:358) at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:350) at org.hibernate.collection.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:97) at org.hibernate.collection.PersistentList.size(PersistentList.java:91) at org.jbpm.graph.def.Node.getDefaultLeavingTransition(Node.java:189) at org.jbpm.graph.exe.Token.signal(Token.java:89) at org.jbpm.graph.exe.ProcessInstance.signal(ProcessInstance.java:201) at jpl.mipl.pgs.jbpm.JBPMExeEngine.execute(JBPMExeEngine.java:471) at jpl.mipl.pgs.jbpm.JBPMExeEngine.main(JBPMExeEngine.java:531)
-
8. Re: process instance persistence and reexecution
enazareno Jan 18, 2006 8:57 PM (in response to dharraj)Hi,
Like in my first post, normally i don't suggest you save process instances during executions. when you issue an open session, it actually assigns a new db connection for it. so in your process execution you are actually calling different connections per each transition (unless you use getCurrentSession so it will use the same connection) I don't know what kind of effects it will give you, but i know it isn't desirable. If you want to observe a node, try state instead of node. A state node is a wait state whereas a node continues execution. Normally in your application, you have a servlet or a session bean that loads the processinstance. Place your persistence routines in there (save only once). Does this makes sense?
Regards,
Elmo -
9. Re: process instance persistence and reexecution
dharraj Jan 25, 2006 1:46 PM (in response to dharraj)Hello,
Thanks for your input.
First of all, we are not using servlets or EJB in our application, atleast not yet. The application is a standalone application that only executes the given process definition. Having said that, how do you think I can solve this problem. Is it possible to write a generic class/program that executes any given process definition while persisting it after visiting each node (or state or tasknode, etc.). I know different node type acts differently. For example, for node type the execution is propagated by the action handler or node depending on where the action handler is placed. On the other hand, a state node needs explicit signal. And let's not forget the bean shell script conditions. So, is there a way to write a generic execution engine?
Thanks
Raj -
10. Re: process instance persistence and reexecution
katador Jan 25, 2006 2:14 PM (in response to dharraj)Hello,
It's posible lauch a process instance trough webservices?
greetings,
Ktdr -
11. Re: process instance persistence and reexecution
enazareno Jan 25, 2006 8:03 PM (in response to dharraj)Hi Raj,
When you say stand-alone, are you referring to swing applications? If so, I suggest you can write a generic singleton class that acts as a delegate for the jbpm. The methods for this class is really quite simple, and minimalistic probably only a createProcessInstance method or a signalProcess method, etc. Example call from an application:Workflow.getInstance().signalProcess( processid, map );
The Workflow wraps the jbpm and the signalProcess is the only location where the process execution is saved, not in the transitions. This is the main context for your begin and end/commit transactions. The map represents probably variables that you may need to introduce when signalling the process. Anyway, this is just an example but this is how I developed my session beans.
For katador:
Jbpm does not rely on J2ee or servlets or other containers. It just probably relies only on hibernate for persistence strategy. With a little creativity, you can do pretty much what you want. If you're interested with web services or the like, maybe you can also check out their BPEL extension. I have not yet gone into that so I can't give you much insight on that.
Regards
Elmo -
12. Re: process instance persistence and reexecution
dharraj Jan 26, 2006 7:43 PM (in response to dharraj)Hello Elmo,
When you say stand-alone, are you referring to swing applications?
No. I mean a command line java application. No GUI yet. Actually, these is what we are trying to do. We need to run a set of programs in a given order. The order in which the programs are executed depends on various well defined conditions. The conditions may change, however, we do not want to modify any code (decision handler or action handler). JBPM's beanshell expressions and conditions are sufficient for us. However, here is the catch. Some of the programs takes hours to run. In an event of failure, we want to be able to pickup from where we left off. Thus, according to my understanding, after each node (or state or ...) is visited, the process instance state needs to be saved. Also, we intent to use the execution context to pass information between processes (nodes).
I hope I have made myself clear. If you need more info let me know.
Thanks,
Raj -
13. Re: process instance persistence and reexecution
ralfoeldi Jan 27, 2006 2:25 AM (in response to dharraj)Hi Raj,
there are a number of very long threads here concerning your problem. Try a search for asych execution, etc.
You ought to find all you need.
And yes, your problem is very well solvable with jBPM. You probably will need a bit more infrastructure than a JVM. A bit of JMS wouldn't be bad either.
Greetings -
14. Re: process instance persistence and reexecution
enazareno Jan 27, 2006 7:02 AM (in response to dharraj)Hi Raj,
For starters, don't use nodes in your case. In your first example, your main context is blocked from continuing when your action executes. In this case your db connection in your main context is still open. You should not hold on to open connections for so long, besides having timeouts, there are other issues. Use states instead, and use async actions.<state name="x"> <event type="node-enter"> <action class="runAsyncAction"/> </event> <transition to="second"/> </state>
Send your process id into your action class so it will remember what process it will send a signal when it completes. Your action should run asynchronously, like previously suggested, or if you're just testing you can even use a thread. When the asynchronous thread completes, signal the process using the process id that you passed into it. Let me know if this isn't very clear.
Regards,
Elmo