7 Replies Latest reply on Dec 19, 2005 8:53 AM by ummadiravi78

    JBOSS jBPM tool evaluation >> Help Required

    nildon

      Hi,

      We are evaluating JBOSS jBPM tool for one of our projects. For the prototype we are trying to integrate the workflow engine and web based user interaction.

      The approach for the above proptotype is as mentioned below:
      1. State node is used in workflow at the point where external user input / intervention is required.

      2. Before state node is reached, the workflow instance is persisted in database.

      3. User input is received from web page.

      4. After procesisng the user input, the corresponding process instance is retrieved from database.

      5. We now try to re-execute the workflow from the next point (point after the current wait state) using API:
      processInstance.signal("<Node Name>");

      6. This above method call results in following error:
      java.lang.IllegalStateException: couldn't signal token 'Token(/)' : couldn't leave node 'null' over the its transition 'Process Loan Decision'
      at org.jbpm.graph.exe.Token.signal(Token.java:101)
      at org.jbpm.graph.exe.ProcessInstance.signal(ProcessInstance.java:213)
      at com.sample.SimpleProcessTest.testSimpleProcess(SimpleProcessTest.java:59)
      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 junit.framework.TestCase.runTest(TestCase.java:154)
      at junit.framework.TestCase.runBare(TestCase.java:127)
      at junit.framework.TestResult$1.protect(TestResult.java:106)
      at junit.framework.TestResult.runProtected(TestResult.java:124)
      at junit.framework.TestResult.run(TestResult.java:109)
      at junit.framework.TestCase.run(TestCase.java:118)
      at junit.framework.TestSuite.runTest(TestSuite.java:208)
      at junit.framework.TestSuite.run(TestSuite.java:203)
      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:478)
      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:344)
      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)

      Could you please kindly help us to trouble-shoot the above error?

      Your help is much appreciated.

      Thanks and Regards,
      Nilesh Dongre
      Architect

        • 1. Re: JBOSS jBPM tool evaluation >> Help Required
          kukeltje

          you should signal the node passing it a transitionname (not null!) or use the signal without a parameter.

          • 2. Re: JBOSS jBPM tool evaluation >> Help Required
            nildon

            Following changes I did:

            1. Read rootToken from the instance I read from the database.

            Token rootToken = procInst.getRootToken();

            2. signal the rootToken by specifying transition name

            rootToken.signal("toReadLoansData");

            But now I am getting following error
            java.lang.IllegalStateException: couldn't signal token 'Token(/)' : couldn't leave node 'null' over the its transition 'toReadLoansData'
            at org.jbpm.graph.exe.Token.signal(Token.java:101)
            at com.sample.SimpleProcessTest.readProcessInstance(SimpleProcessTest.java:199)
            at com.sample.SimpleProcessTest.testSimpleProcess(SimpleProcessTest.java:25)
            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 junit.framework.TestCase.runTest(TestCase.java:154)
            at junit.framework.TestCase.runBare(TestCase.java:127)
            at junit.framework.TestResult$1.protect(TestResult.java:106)
            at junit.framework.TestResult.runProtected(TestResult.java:124)
            at junit.framework.TestResult.run(TestResult.java:109)
            at junit.framework.TestCase.run(TestCase.java:118)
            at junit.framework.TestSuite.runTest(TestSuite.java:208)
            at junit.framework.TestSuite.run(TestSuite.java:203)
            at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:478)
            at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:344)
            at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)

            I don't understand when it says 'couldn't leave node 'null'' , which node it is refering to and which it getting as NULL.

            I want to achieve following:
            - Create Process Definition and store it in database using
            jbpmSession.getGraphSession().saveProcessDefinition(definition);

            I am using MSSQL. This process has one State node at which execution should wait for external input. I have to use State and not task-node as i want to take user input.

            - create process instances of this process and start execution. The instance will wait at the State node. Store the waiting processing instance in database.

            - Read the saved process instance from the database when external input is received and restart the execution.

            Please confirm that the approach is correct. Thanks for any better approaches.

            Regards,
            Nilesh

            • 3. Re: JBOSS jBPM tool evaluation >> Help Required
              kukeltje

              please post the processdefinition and the code. Include it in code tags to make it visible (do a preview to see if it is ok)

              • 4. Re: JBOSS jBPM tool evaluation >> Help Required
                nildon

                Please find following code

                <?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="simple">
                 <start-state name="start">
                 <transition name="toCheckDSCR" to="Check DSCR">
                 <action name="Read DSC Ratio" class="com.sample.action.FirstActionHandler"></action>
                 </transition>
                 </start-state>
                 <end-state name="end">
                 </end-state>
                 <decision name="Check DSCR">
                 <transition name="toReadLoansData" to="Read Loans Data">
                 <condition>
                 executionContext.getVariable("DSCRatio").intValue() > 0
                 </condition>
                 </transition>
                 <transition name="toRejectLoan" to="Reject Loan">
                 <condition>
                 executionContext.getVariable("DSCRatio").intValue() == 0
                 </condition>
                 </transition>
                 </decision>
                 <task-node name="Reject Loan">
                 <transition name="toEndFromRejectLoan" to="end">
                 <action name="action1" class="com.sample.action.LoanRejectHandler"></action>
                 </transition>
                 </task-node>
                 <state name="Read Loans Data">
                
                 <transition name="toProcessLoanDecision" to="Process Loan Decision">
                 <action name="action1" class="com.sample.action.DatabaseActionHandler"></action>
                 </transition>
                 </state>
                 <decision name="Process Loan Decision">
                 <transition name="toProcessLoan" to="Process Loan">
                 <condition>
                 executionContext.getVariable("LoanProcessingDecision").toString().equals("Yes")
                 </condition>
                 </transition>
                 <transition name="toEndFromProcessLoanDecision" to="end">
                 <condition>
                 executionContext.getVariable("LoanProcessingDecision").toString().equals("No")
                 </condition>
                 </transition>
                 </decision>
                 <task-node name="Process Loan">
                 <transition name="toEndFromProcessLoan" to="end">
                 <action name="action1" class="com.sample.action.ProcessLoanHandler"></action>
                 </transition>
                 </task-node>
                
                </process-definition>


                Code for Test class
                package com.sample;
                
                import java.io.FileReader;
                import java.util.ArrayList;
                
                
                
                import junit.framework.TestCase;
                
                import org.jbpm.db.JbpmSession;
                import org.jbpm.db.JbpmSessionFactory;
                import org.jbpm.graph.def.ProcessDefinition;
                import org.jbpm.graph.exe.ProcessInstance;
                import org.jbpm.graph.exe.Token;
                import org.jbpm.jpdl.xml.JpdlXmlReader;
                
                public class SimpleProcessTest extends TestCase {
                
                 static JbpmSessionFactory jbpmSessionFactory = JbpmSessionFactory.buildJbpmSessionFactory();
                
                 public void testSimpleProcess() throws Exception {
                
                 //saveProcessDefinition();
                 //saveProcessInstance();
                 readProcessInstance();
                
                 }
                
                 public void saveProcessInstance() {
                
                 // obtain a session
                 JbpmSession jbpmSession = jbpmSessionFactory.openJbpmSession();
                 try {
                 ProcessDefinition loanProcess = jbpmSession.getGraphSession().findLatestProcessDefinition("simple");
                 // start a user managed transaction
                 jbpmSession.beginTransaction();
                
                 ProcessInstance loanInstance = new ProcessInstance(loanProcess);
                 loanInstance.signal();
                
                 // store the result in the database
                 jbpmSession.getGraphSession().saveProcessInstance(loanInstance);
                
                 // commit the user transaction
                 jbpmSession.getConnection().commit();
                
                 }
                 catch(Exception e)
                 {
                 e.printStackTrace();
                 }
                 finally {
                 // close the session.
                 jbpmSession.close();
                 }
                 }
                
                 public void readProcessInstance()
                 {
                 JbpmSession jbpmSession = jbpmSessionFactory.openJbpmSession();
                 ProcessDefinition procDef = jbpmSession.getGraphSession().findLatestProcessDefinition("simple");
                
                 ArrayList arlProcInsts = (ArrayList) jbpmSession.getGraphSession().findProcessInstances(procDef.getId());
                
                
                 int count = arlProcInsts.size();
                 ProcessInstance procInst = null;
                 System.out.println(">>>>>> "+count + " >>>>>>> " + procDef);
                 for (int i = 0; i < count; i++)
                 {
                 procInst = (ProcessInstance) arlProcInsts.get(i);
                 System.out.println("Process Instance ID = " + procInst.getId());
                 System.out.println("Has Ended Value = " + procInst.hasEnded());
                 }
                
                 Token rootToken = procInst.getRootToken();
                
                 Token token = rootToken.findToken("Check DSCR/Read Loans Data");
                 System.out.println("token = " + token);
                
                 rootToken.signal("toReadLoansData");
                 procInst.signal();
                
                 jbpmSession.close();
                 }
                
                 public void saveProcessDefinition(){
                
                
                 JbpmSession jbpmSession = jbpmSessionFactory.openJbpmSession();
                 try{
                 ProcessDefinition definition = new JpdlXmlReader(new FileReader("D:/TestProcess/src/process/simple.par/processdefinition.xml")).readProcessDefinition();
                
                 /* assertNotNull("Definition should not be null", definition);
                
                 // Create an instance of the process definition.*/
                 //ProcessInstance instance = new ProcessInstance(definition);
                 //*********************************************************************
                 //instance.signal();
                
                 jbpmSession.getGraphSession().saveProcessDefinition(definition);
                 jbpmSession.getConnection().commit();
                
                 }
                 catch(Exception e)
                 {
                 e.printStackTrace();
                 }
                 finally {
                 // close the session.
                 jbpmSession.close();
                 }
                
                 }
                
                }
                
                


                1. In 'saveProcessDefinition' method, I am reading the process definition XML from file system and store it to jBPM database.
                2. In 'saveProcessInstance' method, the process definition is read from the database and instance is created. This instance is saved to database.
                3. In 'readProcessInstance' the instance is read from database and executed further.

                I am getting the error in step 3. But not sure that steps 1 and 2 above are correct and are not the root cause of error in step 3.

                Please confirm that the code is correct. Saving the process definition in database must be the common task, are there any best practices defined to do such common tasks.

                Thanks and Regards,
                Nilesh


                • 5. Re: JBOSS jBPM tool evaluation >> Help Required
                  ummadiravi78

                  Can you place the following lines in ur code:

                  System.out.println("root token name="+rootToken.getNode().getName());

                  After the following line:

                  Token rootToken = procInst.getRootToken();

                  Let me know the result.

                  Ravi Prakash

                  • 6. Re: JBOSS jBPM tool evaluation >> Help Required
                    nildon

                    Hi Ravi,

                    I got following result after adding the sop.

                    root token name=Read Loans Data

                    where 'Read Loans Data' is the state where the instance is waiting.

                    Regards,
                    Nilesh

                    • 7. Re: JBOSS jBPM tool evaluation >> Help Required
                      ummadiravi78

                      That means, the root token points to node 'Read Lones Data' and again you are trying to signal to the same node in the following line:

                      rootToken.signla("toReadLoansData");

                      You have already reached that node.

                      I think you can just use token.signal() to execute the node 'Read Lones Data'.