3 Replies Latest reply on Jan 11, 2010 6:15 AM by jbarrez

    Problem retrieving running process instance

      Hello everybody,

       

      I'm quite new to JBPM and am currently investigating on how to start a process with a client application A, having it end up in a certain wait state and finally continuing this process instance with a client application B which then of course has to receive the correct process instance and send a signal to continue it.

       

      Client Application A:

       

      =======================================


      package publications.eu.jbpm;

       

      import java.text.ParseException;
      import java.text.SimpleDateFormat;
      import java.util.Date;
      import java.util.HashMap;
      import java.util.Map;

       

      import org.jbpm.api.Configuration;
      import org.jbpm.api.ExecutionService;
      import org.jbpm.api.ProcessEngine;
      import org.jbpm.api.ProcessInstance;
      import org.jbpm.api.RepositoryService;
      import org.jbpm.api.TaskService;

       

      public class PodlTest {

       

          public static void main(String[] args) throws Exception {
              Map<String, Object> variables = new HashMap<String, Object>();

       

              variables.put("catnum", "CDNA12239ENC");
              variables.put("filePath",
                      "C:\\temp\\10168_CDNA12239ENC_20080922232844.zip");
              variables.put("version", new Integer(1));

       

              SimpleDateFormat sdfToDate = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss");
              Date receptionDate = sdfToDate.parse("05.01.2010 11:07:54");
              variables.put("receptionDate", receptionDate);

       

              ProcessEngine processEngine = new Configuration().buildProcessEngine();
              RepositoryService repositoryService = processEngine
                      .getRepositoryService();
              ExecutionService executionService = processEngine.getExecutionService();
              TaskService taskService = processEngine.getTaskService();

       

              String deploymentID = repositoryService.createDeployment()
                      .addResourceFromClasspath("publications/eu/jbpm/podl.jpdl.xml")
                      .deploy();
              ProcessInstance processInstance = executionService
                      .startProcessInstanceByKey("podl", variables, "CDNA12239ENC");
              String pID = processInstance.getId();

       

              System.out.println("(before completeTask) processInstance : "
                      + processInstance);
              System.out.println("(before completeTask) processInstance getId : "
                      + processInstance.getId());
              System.out.println("(before completeTask) processInstance getState : "
                      + processInstance.getState());
              System.out.println("(before completeTask) processInstance isEnded : "
                      + processInstance.isEnded());
          }

       

      }

       

      =======================================

       

       

      Client application B:

       

      =======================================

       

      package publications.eu.jbpm;

       

      import java.text.ParseException;
      import java.text.SimpleDateFormat;
      import java.util.Date;
      import java.util.HashMap;
      import java.util.Map;

       

      import org.jbpm.api.Configuration;
      import org.jbpm.api.Execution;
      import org.jbpm.api.ExecutionService;
      import org.jbpm.api.ProcessEngine;
      import org.jbpm.api.ProcessInstance;
      import org.jbpm.api.RepositoryService;
      import org.jbpm.api.TaskService;

       

      public class PodlClientTest {

       

          public static void main(String[] args) throws Exception {
              ProcessEngine processEngine = new Configuration().getProcessEngine();
              RepositoryService repositoryService = processEngine
                      .getRepositoryService();
              ExecutionService executionService = processEngine.getExecutionService();
              TaskService taskService = processEngine.getTaskService();

       

              ProcessInstance runningInstance = executionService.findProcessInstanceById("podl.CDNA12239ENC");
              Execution executionInWaitRedelivery = runningInstance.findActiveExecutionIn("wait_test");
              executionService.signalExecutionById(executionInWaitRedelivery.getId());
          }

       

      }

       

      =======================================

       

       

      After executing the first application, I have a running instance which stopped in the wait state (entries in table JBPM4_EXECUTION).


      Unfortunately after starting the second client, I am not able to retrieve the previous process instance.

      executionService.findProcessInstanceById("podl.CDNA12239ENC"); returns null.

       

      The problem I guess is that ProcessEngine processEngine = new Configuration().getProcessEngine(); recreates all the schemas resulting in the loss of any previously stored process data.

       

      Could anyone please give me some advice on how to fix this?

       

      Thank you very much in advance and

       

      kind regards,

      Oliver Schneider

        • 1. Re: Problem retrieving running process instance

          With JBPM 3 it worked as shown in the example below. But this way does not work any more with JBPM 4.

          What am I doing wrong?

           

          package org.jbpm.tutorial.db;

           

          import java.util.List;

           

          import junit.framework.TestCase;

           

          import org.jbpm.db.GraphSession;
          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;

           

          public class HelloWorldDbTest extends TestCase {

           

            // We need one JbpmSessionFactory per application.  So we put it in
            // a static variable. The JbpmSessionFactory will be used in the
            // test methods to create JbpmSession's.
            static JbpmSessionFactory jbpmSessionFactory =
                JbpmSessionFactory.buildJbpmSessionFactory();
           
            static {
              // Since the hypersonic in-memory database is a new, fresh database,
              // we need to create the schema at runtime before we start the tests.
              // The next line creates the database tables and foreign key
              // constraints.
              jbpmSessionFactory.getJbpmSchema().createSchema();
            }

           

            public void testSimplePersistence() {
              // Between the 3 method calls below, all data is passed via the
              // database.  Here, in this unit test, these 3 methods are executed
              // right after each other because we want to test a complete process
              // scenario.  But in reality, these methods represent different
              // requests to a server.
             
              // Since we start with a clean, empty in-memory database, we have to
              // deploy the process first.  In reality, this is done once by the
              // process developer.
              deployProcessDefinition();

           

              // Suppose we want to start a process instance (=process execution)
              // when a user submits a form in a web application...
              processInstanceIsCreatedWhenUserSubmitsWebappForm();

           

              // Then, the arrival of an asynchronous message will continue
              // execution.
              theProcessInstanceContinuesWhenAnAsyncMessageIsReceived();
            }

           

            public void deployProcessDefinition() {
              // This test shows a process definition and one execution
              // of the process definition.  The process definition has
              // 3 nodes: an unnamed start-state, a state 's' and an
              // end-state named 'end'.
              ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(
                "<process-definition name='hello world'>" +
                "  <start-state name='start'>" +
                "    <transition to='s' />" +
                "  </start-state>" +
                "  <state name='s'>" +
                "    <transition to='end' />" +
                "  </state>" +
                "  <end-state name='end' />" +
                "</process-definition>"
              );
             
              // Let's open a new persistence session
              JbpmSession jbpmSession = jbpmSessionFactory.openJbpmSession();
              // ... and begin a transaction on the persistence session
              jbpmSession.beginTransaction();
             
              // Save the process definition in the database
              jbpmSession
                  .getGraphSession()
                  .saveProcessDefinition(processDefinition);
             
              // Commit the transaction
              jbpmSession.commitTransaction();
              // And close the jbpmSession.
              jbpmSession.close();
            }

           

            public void processInstanceIsCreatedWhenUserSubmitsWebappForm() {
              // The code in this method could be inside a struts-action
              // or a JSF managed bean.
             
              // Let's open a new persistence session
              JbpmSession jbpmSession = jbpmSessionFactory.openJbpmSession();
              // ... and begin a transaction on the persistence session.
              jbpmSession.beginTransaction();
             
              // Now we can query the database for the process definition that we
              // deployed above.
              ProcessDefinition processDefinition =
                  jbpmSession
                    .getGraphSession()
                    .findLatestProcessDefinition("hello world");
             
              // With the processDefinition that we retrieved from the database, we
              // can create an execution of the process definition just like in the
              // hello world example (which was without persistence).
              ProcessInstance processInstance =
                  new ProcessInstance(processDefinition);
             
              Token token = processInstance.getRootToken();
              assertEquals("start", token.getNode().getName());
              // Let's start the process execution
              token.signal();
              // Now the process is in the state 's'.
              assertEquals("s", token.getNode().getName());
             
              // Now the processInstance is saved in the database.  So the
              // current state of the execution of the process is stored in the
              // database. 
              jbpmSession
                  .getGraphSession()
                  .saveProcessInstance(processInstance);
              // The method below will get the process instance back out
              // of the database and resume execution by providing another
              // external signal.

           

              // At the end of the webapp action, the transaction is committed.
              jbpmSession.commitTransaction();
              // And close the jbpmSession.
              jbpmSession.close();
            }

           

            public void theProcessInstanceContinuesWhenAnAsyncMessageIsReceived() {
              // The code in this method could be the content of a message driven bean.
             
              // Let's open a new persistence session.
              JbpmSession jbpmSession = jbpmSessionFactory.openJbpmSession();
              // ... and begin a transaction on the persistence session
              // note that it's also possible to use a jdbc connection from a
              // DataSource in your application server.
              jbpmSession.beginTransaction();
              GraphSession graphSession = jbpmSession.getGraphSession();

           

              // First, we need to get the process instance back out of the database.
              // There are several options to know what process instance we are dealing
              // with here.  The easiest in this simple test case is just to look for
              // the full list of process instances.  That should give us only one
              // result.  So let's look up the process definition.
              ProcessDefinition processDefinition =
                  graphSession.findLatestProcessDefinition("hello world");

           

              // Now, we search for all process instances of this process definition.
              List processInstances =
                  graphSession.findProcessInstances(processDefinition.getId());
             
              // Because we know that in the context of this unit test, there is
              // only one execution.  In real life, the processInstanceId can be
              // extracted from the content of the message that arrived or from
              // the user making a choice.
              ProcessInstance processInstance =
                  (ProcessInstance) processInstances.get(0);
             
              // Now we can continue the execution.  Note that the processInstance
              // delegates signals to the main path of execution (=the root token).
              processInstance.signal();
             
              // After this signal, we know the process execution should have
              // arrived in the end-state.
              assertTrue(processInstance.hasEnded());
             
              // Now we can update the state of the execution in the database
              graphSession.saveProcessInstance(processInstance);

           

              // At the end of the MDB, the transaction is committed.
              jbpmSession.commitTransaction();
              // And the jbpmSession is closed.
              jbpmSession.close();
            }
          }

          • 2. Re: Problem retrieving running process instance

            In the meantime I found the cause of the problem:

             

            I had to comment out the following line of file jbpm.hibernate.xfg.xml:


            <!-- property name="hibernate.hbm2ddl.auto">create-drop</property-->

            • 3. Re: Problem retrieving running process instance
              jbarrez
              Right. Enabling this property will recreate your db schema every time Hibernate boots up. In many dev environments, this functionality is wanted.