1 Reply Latest reply on Jan 27, 2012 5:09 PM by Ricardo Chiriboga

    Problem with persistence, rules & fireUntilHalt

    Demian Calcaprina Master

      Hi All,

       

      I have simple flow like this:

      Start->Ruleflow->...

      And I am running it with persistence. I am running the process in this way:

      ProcessInstance process = session.createProcessInstance(

                                              "pid", parameters);

                          session.insert(process);

                          long processInstanceId = process.getId();

                          new Thread(new Runnable() {

                                    public void run() {

                                              session.fireUntilHalt();

                                    }

                          }).start();

                          session.startProcessInstance(processInstanceId);

      And it breaks after executing the activation (I can see that the right side of the rule is run, as I put a variable in the process and it is there after the execution):

      Exception in thread "Thread-6" org.drools.RuntimeDroolsException: Unexpected exception executing action org.drools.common.RuleFlowGroupImpl$DeactivateCallback@645ccb

                at org.drools.common.AbstractWorkingMemory.executeQueuedActions(AbstractWorkingMemory.java:996)

                at org.drools.common.DefaultAgenda.fireUntilHalt(DefaultAgenda.java:1036)

                at org.drools.common.AbstractWorkingMemory.fireUntilHalt(AbstractWorkingMemory.java:777)

                at org.drools.common.AbstractWorkingMemory.fireUntilHalt(AbstractWorkingMemory.java:753)

                at org.drools.command.runtime.rule.FireUntilHaltCommand$1.run(FireUntilHaltCommand.java:50)

                at java.lang.Thread.run(Thread.java:662)

      Caused by: java.lang.NullPointerException

                at bitronix.tm.resource.jdbc.JdbcConnectionHandle.prepareStatement(JdbcConnectionHandle.java:259)

                at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

                at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

                at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

                at java.lang.reflect.Method.invoke(Method.java:597)

                at bitronix.tm.resource.jdbc.BaseProxyHandlerClass.invoke(BaseProxyHandlerClass.java:63)

                at $Proxy20.prepareStatement(Unknown Source)

                at org.hibernate.jdbc.AbstractBatcher.getPreparedStatement(AbstractBatcher.java:505)

                at org.hibernate.jdbc.AbstractBatcher.getPreparedStatement(AbstractBatcher.java:423)

                at org.hibernate.jdbc.AbstractBatcher.prepareQueryStatement(AbstractBatcher.java:139)

                at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1547)

                at org.hibernate.loader.Loader.doQuery(Loader.java:673)

                at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)

                at org.hibernate.loader.Loader.doList(Loader.java:2213)

                at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2104)

                at org.hibernate.loader.Loader.list(Loader.java:2099)

                at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:378)

                at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:338)

                at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:172)

                at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1121)

                at org.hibernate.impl.QueryImpl.list(QueryImpl.java:79)

                at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:65)

                at org.jbpm.persistence.JpaProcessPersistenceContext.getProcessInstancesWaitingForEvent(JpaProcessPersistenceContext.java:39)

                at org.jbpm.persistence.processinstance.JPASignalManager.getProcessInstancesForEvent(JPASignalManager.java:40)

                at org.jbpm.persistence.processinstance.JPASignalManager.signalEvent(JPASignalManager.java:23)

                at org.jbpm.process.instance.ProcessRuntimeImpl$3.afterRuleFlowGroupDeactivated(ProcessRuntimeImpl.java:335)

                at org.drools.event.AgendaEventSupport.fireAfterRuleFlowGroupDeactivated(AgendaEventSupport.java:168)

                at org.drools.common.RuleFlowGroupImpl.setActive(RuleFlowGroupImpl.java:148)

                at org.drools.common.RuleFlowGroupImpl$DeactivateCallback.execute(RuleFlowGroupImpl.java:301)

                at org.drools.common.AbstractWorkingMemory.executeQueuedActions(AbstractWorkingMemory.java:994)

                ... 5 more

       

      If I run it with fireAllRules() after starting the process, it works fine, so I think it may be related with the new thead that the reactive mode uses. Do I may have some problems with my session persistence configuration? Here is the code of my test:

      public class ProcessExecutionTest {

       

       

                static {

                          ProcessBuilderFactory

                                              .setProcessBuilderFactoryService(new ProcessBuilderFactoryServiceImpl());

                          ProcessRuntimeFactory

                                              .setProcessRuntimeFactoryService(new ProcessRuntimeFactoryServiceImpl());

                }

                private PoolingDataSource ds1;

                private EntityManagerFactory emf;

       

       

                @Before

                public void setUp() throws Exception {

                          ds1 = new PoolingDataSource();

                          ds1.setUniqueName("jdbc/testDS1");

                          ds1.setClassName("org.h2.jdbcx.JdbcDataSource");

                          ds1.setMaxPoolSize(3);

                          ds1.setAllowLocalTransactions(true);

                          ds1.getDriverProperties().put("user", "sa");

                          ds1.getDriverProperties().put("password", "sasa");

                          ds1.getDriverProperties().put("URL", "jdbc:h2:mem:mydb");

                          ds1.init();

                           ds1.init();

                          emf = Persistence

                                              .createEntityManagerFactory("org.jbpm.persistence.jpa");

       

       

                }

       

       

                private KnowledgeBase createKnowledgeBase() {

                          KnowledgeBuilder kbuilder = KnowledgeBuilderFactory

                                              .newKnowledgeBuilder();

                          kbuilder.add(

                                              new ClassPathResource("myflow.bpmn"),

                                              ResourceType.BPMN2);

                          kbuilder.add(

                                              new ClassPathResource("myrule.drl"),

                                              ResourceType.DRL);

                          KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();

                          kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());

                          if (kbuilder.hasErrors()) {

                                    StringBuilder errorMessage = new StringBuilder();

                                    for (KnowledgeBuilderError error : kbuilder.getErrors()) {

                                              errorMessage.append(error.getMessage());

                                              errorMessage.append(System.getProperty("line.separator"));

                                    }

                                    Assert.fail(errorMessage.toString());

                          }

                          return kbase;

                }

       

       

                @Test

                public void testAccrualProcessExceeded() throws Exception {

                          KnowledgeBase kbase = createKnowledgeBase();

                          EntityManagerFactory emf = Persistence

                                              .createEntityManagerFactory("org.jbpm.persistence.jpa");

                          Environment env = KnowledgeBaseFactory.newEnvironment();

                          env.set(EnvironmentName.ENTITY_MANAGER_FACTORY, emf);

                          env.set(EnvironmentName.TRANSACTION_MANAGER,

                                              TransactionManagerServices.getTransactionManager());

                          final StatefulKnowledgeSession session = JPAKnowledgeService

                                              .newStatefulKnowledgeSession(kbase, null, env);

                          new JPAWorkingMemoryDbLogger(session);

                          KnowledgeRuntimeLoggerFactory.newConsoleLogger(session);

                          JPAProcessInstanceDbLog log = new JPAProcessInstanceDbLog(env);

                          session.getWorkItemManager().registerWorkItemHandler("Human Task",

                                              new WorkItemHandler() {

       

       

                                                        public void executeWorkItem(WorkItem workItem,

                                                                            WorkItemManager manager) {

                                                                  Map<String, Object> results = new HashMap<String, Object>();

                                                                  results.put("Result", "ResultValue");

                                                                  manager.completeWorkItem(workItem.getId(), results);

                                                        }

       

       

                                                        public void abortWorkItem(WorkItem workItem,

                                                                            WorkItemManager manager) {

                                                        }

                                              });

                                              Map<String, Object> parameters = new HashMap<String, Object>();

                          parameters.put("var1", new Long(1));

                          ProcessInstance process = session.createProcessInstance(

                                              "pid", parameters);

                          session.insert(process);

                          long processInstanceId = process.getId();

                          new Thread(new Runnable() {

       

                                    @Override

                                    public void run() {

                                              session.fireUntilHalt();

                                    }

                          }).start();

                          Thread.sleep(5000);

                          session.startProcessInstance(processInstanceId);

      //                    session.fireAllRules();

                          List<NodeInstanceLog> nodes= log.findNodeInstances(processInstanceId);

                          for (Iterator iterator = nodes.iterator(); iterator.hasNext();) {

                                    NodeInstanceLog variableInstanceLog = (NodeInstanceLog) iterator

                                                        .next();

                                    System.out.println(variableInstanceLog);

                          }

       

                          List<VariableInstanceLog> variables = log.findVariableInstances(processInstanceId);

                          for (Iterator iterator = variables.iterator(); iterator.hasNext();) {

                                    VariableInstanceLog variableInstanceLog = (VariableInstanceLog) iterator

                                                        .next();

                                    System.out.println(variableInstanceLog);

                          }

                }

      }