@Test public void create2ProcessInstances() throws Exception { long[] processId = new long[2]; StatefulKnowledgeSession ksession = reloadKnowledgeSession(); processId[0] = ksession.createProcessInstance("org.jbpm.processinstance.helloworld", null).getId(); processId[1] = ksession.createProcessInstance("org.jbpm.processinstance.helloworld", null).getId(); ksession.dispose(); assertProcessInstancesExist(processId); }
@Test public void create2ProcessInstancesInsideTransaction() throws Exception { long[] processId = new long[2]; UserTransaction ut = (UserTransaction) new InitialContext().lookup("java:comp/UserTransaction"); ut.begin(); StatefulKnowledgeSession ksession = reloadKnowledgeSession(); processId[0] = ksession.createProcessInstance("org.jbpm.processinstance.helloworld", null).getId(); processId[1] = ksession.createProcessInstance("org.jbpm.processinstance.helloworld", null).getId(); assertEquals(2, ksession.getProcessInstances().size()); // process instance manager cache flushed on tx ut.commit(); assertEquals(0, ksession.getProcessInstances().size()); ksession = reloadKnowledgeSession(ksession); assertEquals(0, ksession.getProcessInstances().size()); ksession.dispose(); assertProcessInstancesExist(processId); }
@Test public void noProcessInstancesLeftWithPreTxKSessionAndRollback() throws Exception { long[] notProcess = new long[4]; StatefulKnowledgeSession ksession = reloadKnowledgeSession(); UserTransaction ut = (UserTransaction) new InitialContext().lookup("java:comp/UserTransaction"); ut.begin(); notProcess[0] = ksession.createProcessInstance("org.jbpm.processinstance.helloworld", null).getId(); notProcess[1] = ksession.createProcessInstance("org.jbpm.processinstance.helloworld", null).getId(); ut.rollback(); // Validate that proc inst mgr cache is also flushed on rollback assertEquals(0, ksession.getProcessInstances().size()); ksession = reloadKnowledgeSession(ksession); assertEquals(0, ksession.getProcessInstances().size()); ksession.dispose(); assertProcessInstancesNotExist(notProcess); }
private void createKnowledgeSessionStartProcessEtc(KieBase kbase) { logger.info("session count=" + kbase.getKieSessions().size()); StatefulKnowledgeSession ksession = JPAKnowledgeService.newStatefulKnowledgeSession( kbase, getKnowledgeSessionConfiguration(), env); addEventListenersToSession(ksession); /** * The following log line caused the memory leak. The specific (reverse-ordered) stack trace is * the following: * * <p>MemoryLeakTest.createKnowledgeSessionStartProcessEtc(KnowledgeBase) calls * kbase.getKieSessions() .. KnowledgeBaseImpl.getStatefulKnowledgeSessions() line: 186 * StatefulKnowledgeSessionImpl.<init>(ReteooWorkingMemory, KnowledgeBase) line: 121 * ReteooStatefulSession(AbstractWorkingMemory).setKnowledgeRuntime(InternalKnowledgeRuntime) * line: 1268 ReteooStatefulSession(AbstractWorkingMemory).createProcessRuntime() line: 342 * ProcessRuntimeFactory.newProcessRuntime(AbstractWorkingMemory) line: 12 * ProcessRuntimeFactoryServiceImpl.newProcessRuntime(AbstractWorkingMemory) line: 1 * ProcessRuntimeFactoryServiceImpl.newProcessRuntime(AbstractWorkingMemory) line: 10 * ProcessRuntimeImpl.<init>(AbstractWorkingMemory) line: 84 * ProcessRuntimeImpl.initProcessEventListeners() line: 215 * * <p>And ProcessRuntimeImpl.initProcessEventListeners() is what adds a new listener to * AbstractRuleBase.eventSupport.listeners via this line (235): * kruntime.getKnowledgeBase().addEventListener(knowledgeBaseListener); * * <p>The StatefulKnowledgeSessionImpl instance created in this .getStatefulKnowledgeSessions() * method is obviously never disposed, which means that the listener is never removed. The * listener then contains a link to a field (signalManager) of the ProcessRuntimeImpl, which * contains a link to the StatefulKnowledgeSessionImpl instance created here. etc.. */ logger.info("session count=" + kbase.getKieSessions().size()); TestWorkItemHandler handler = new TestWorkItemHandler(); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", handler); try { // create process instance, insert into session and start process Map<String, Object> processParams = new HashMap<String, Object>(); String[] fireballVarHolder = new String[1]; processParams.put("fireball", fireballVarHolder); ProcessInstance processInstance = ksession.createProcessInstance(PROCESS_NAME, processParams); ksession.insert(processInstance); ksession.startProcessInstance(processInstance.getId()); // after the log line has been added, the DefaultProcessEventListener registered // in the addEventListenersToSession() method no longer works?!? ksession.fireAllRules(); // test process variables String[] procVar = (String[]) ((WorkflowProcessInstance) processInstance).getVariable("fireball"); assertEquals("Rule task did NOT fire or complete.", "boom!", procVar[0]); // complete task and process Map<String, Object> results = new HashMap<String, Object>(); results.put("chaerg", new SerializableResult("zhrini", 302l, "F", "A", "T")); ksession.getWorkItemManager().completeWorkItem(handler.getWorkItem().getId(), results); assertNull(ksession.getProcessInstance(processInstance.getId())); } finally { // This should clean up all listeners, but doesn't -> see docs above ksession.dispose(); } }