@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);
  }
示例#4
0
  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();
    }
  }