jBPM issue using Persistence and fireUntilHalt
bezudar Sep 7, 2011 3:16 AMHi,
I am trying to use the jBPM example for persisting the data and trying to use another thread for rule processing using
ksession.fireUntilHalt();
but I am encountering the following exception.
Exception in thread "Thread-4" org.drools.RuntimeDroolsException: Unexpected exception executing action org.jbpm.process.instance.event.DefaultSignalManager$SignalAction@1be20c at org.drools.common.AbstractWorkingMemory.executeQueuedActions(AbstractWorkingMemory.java:996) at org.drools.common.DefaultAgenda.fireUntilHalt(DefaultAgenda.java:1037) 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(Unknown Source) Caused by: java.lang.NullPointerException at org.drools.persistence.jpa.processinstance.JPAWorkItemManager.internalExecuteWorkItem(JPAWorkItemManager.java:43) at org.jbpm.workflow.instance.node.WorkItemNodeInstance.internalTrigger(WorkItemNodeInstance.java:106) at org.jbpm.workflow.instance.impl.NodeInstanceImpl.trigger(NodeInstanceImpl.java:122) at org.jbpm.workflow.instance.impl.NodeInstanceImpl.triggerConnection(NodeInstanceImpl.java:186) at org.jbpm.workflow.instance.impl.NodeInstanceImpl.triggerCompleted(NodeInstanceImpl.java:150) at org.jbpm.workflow.instance.impl.ExtendedNodeInstanceImpl.triggerCompleted(ExtendedNodeInstanceImpl.java:47) at org.jbpm.workflow.instance.node.StateBasedNodeInstance.triggerCompleted(StateBasedNodeInstance.java:162) at org.jbpm.workflow.instance.node.StateBasedNodeInstance.triggerCompleted(StateBasedNodeInstance.java:143) at org.jbpm.workflow.instance.node.RuleSetNodeInstance.signalEvent(RuleSetNodeInstance.java:73) at org.jbpm.workflow.instance.impl.WorkflowProcessInstanceImpl.signalEvent(WorkflowProcessInstanceImpl.java:339) at org.jbpm.process.instance.event.DefaultSignalManager.internalSignalEvent(DefaultSignalManager.java:80) at org.jbpm.process.instance.event.DefaultSignalManager$SignalAction.execute(DefaultSignalManager.java:175) at org.drools.common.AbstractWorkingMemory.executeQueuedActions(AbstractWorkingMemory.java:994) ... 5 more
The same is working fine without persistence and another test is running fine with persistence but there i am calling
kession.fireAllRules();
explicitly. I have made my model classes serializable.
The code used is :
public void reactiveProcessAndRulesTest() throws InterruptedException { KnowledgeBuilder kbuilder = KnowledgeBuilderFactory .newKnowledgeBuilder(); kbuilder.add(new ClassPathResource("EmergencyServiceSimple.bpmn"), ResourceType.BPMN2); kbuilder.add(new ClassPathResource("SelectEmergencyVehicleSimple.drl"), ResourceType.DRL); KnowledgeBuilderErrors errors = kbuilder.getErrors(); if (errors.size() > 0) { for (KnowledgeBuilderError error : errors) { System.out.println(error.getMessage()); } return; } KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(); kbase.addKnowledgePackages(kbuilder.getKnowledgePackages()); EntityManagerFactory emf = Persistence .createEntityManagerFactory("org.jbpm.task"); Environment env = KnowledgeBaseFactory.newEnvironment(); env.set(EnvironmentName.ENTITY_MANAGER_FACTORY, emf); final StatefulKnowledgeSession ksession = JPAKnowledgeService .newStatefulKnowledgeSession(kbase, null, env); // ksession = kbase.newStatefulKnowledgeSession(); // Setting the process engine and the rule engine in reactive mode // This will cause that if a rule is activated, the rule will fire // without waiting // the user to call the fireAllRules() method. MyHumanChangingValuesSimulatorWorkItemHandler humanActivitiesSimHandler = new MyHumanChangingValuesSimulatorWorkItemHandler(); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", humanActivitiesSimHandler); KnowledgeRuntimeLoggerFactory.newConsoleLogger(ksession); Emergency emergency = new Emergency("555-1234"); // Run with Heart Attack and check the output. An Ambulance must appear // in the report // emergency.setType("Heart Attack"); // Run with Fire and check the output. A FireTruck must appear in the // report emergency.setType("Fire"); Map<String, Object> parameters = new HashMap<String, Object>(); parameters.put("emergency", emergency); WorkflowProcessInstance process = (WorkflowProcessInstance) ksession .startProcess( "com.wordpress.salaboy.bpmn2.SimpleEmergencyService", parameters); // My Emergency and My Process are both inserted as Facts / Truths in my // Knowledge Session // Now Emergency and the Process Instance can be used by the inference // engine ksession.insert(emergency); ksession.insert(process); new Thread(new Runnable() { public void run() { ksession.fireUntilHalt(); } }).start(); // Is the Process still Active? Assert.assertEquals(ProcessInstance.STATE_ACTIVE, process.getState()); // Is there a running node instance? Assert.assertEquals(1, process.getNodeInstances().size()); // Is the process stopped in the "Ask for Emergency Information" // activity? Assert.assertEquals("Ask for Emergency Information", process .getNodeInstances().iterator().next().getNodeName()); // Lets check the value of the emergency.getRevision(), it should be 1 Assert.assertEquals(1, ((Emergency) process.getVariable("emergency")).getRevision()); System.out.println("Completing the first Activity"); // Complete the first human activity humanActivitiesSimHandler.completeWorkItem(); // I need to sleep for a little while, because the other thread can be // executing some activated rules Thread.sleep(1000); // Lets check the value of the vehicle variable it should be a Fire // Truck => Fire Assert.assertTrue(((Vehicle) process.getVariable("vehicle")) instanceof FireTruck); // Is the Process still Active? Assert.assertEquals(ProcessInstance.STATE_ACTIVE, process.getState()); // Is there a running node instance? Assert.assertEquals(1, process.getNodeInstances().size()); // Is the process stopped in the "Dispatch Vehicle" activity? Assert.assertEquals("Dispatch Vehicle", process.getNodeInstances() .iterator().next().getNodeName()); // Lets check the value of the emergency.getRevision(), it should be 2 Assert.assertEquals(2, ((Emergency) process.getVariable("emergency")).getRevision()); System.out.println("Completing the second Activity"); // Complete the second human activity humanActivitiesSimHandler.completeWorkItem(); // Is the process completed? Assert.assertEquals(ProcessInstance.STATE_COMPLETED, process.getState()); }
My Full code is in this thread : http://community.jboss.org/message/625081
Any help would be appreciated.
I also see very wierd behaviour happening when running the program in Debug mode in eclipse and run mode.