2 Replies Latest reply on Jul 5, 2011 9:05 AM by brucecui

    NullPointerException problem when console tried to start new sub process, triggered by signal sent from async task

    brucecui

      I know the subject is not quite clear. But problem itself does look that complex to me.

       

      Here is a background brief:

      I tried to use jBPM to drive some backend batch processes, which basically requires multi-threading. After struggling with various problems, asking around in the forum, changing and rebuilding source codes, I finally came to this stage: the console can now pass ksession(actually kruntime) to my self-defined work item handlers, and I can trigger the event by calling ksession's signal method with return value to the processInstance.

       

      This was suppose to be a maybe not perfect, but at least a working solution. But problems just come after another. Now I found that once the process contains sub process, it would throw out NullPointerException at the point when trying to add the sub process to persistance: "org.jbpm.persistence.processinstance.JPAProcessInstanceManager.addProcessInstance(JPAProcessInstanceManager.java:37)".

       

      Another question is, I found that when I called the signalEvent method of the ksession, it actually took over the process and run the rest in this thread. So, say if I have a infinite loop, and an async task runs every round, and an signal event starts after it waiting for return event. If the task calls the signalEvent method every time, once a new thread takes over the process, will the old thread end? Or it will keep accumulating?

       

       

      Below is the log output of the first problem:

       

      2011-07-04 19:13:01,092 INFO  [STDOUT] (Thread-107) kruntime: org.drools.impl.StatefulKnowledgeSessionImpl@7b2b39
      2011-07-04 19:13:01,092 INFO  [STDOUT] (Thread-107) process: WorkflowProcessInstance8 [processId=com.xxxx.CustomerLoader,state=1]
      2011-07-04 19:13:01,092 INFO  [STDOUT] (Thread-107) process instance id: 8
      2011-07-04 19:13:01,092 INFO  [STDOUT] (Thread-107) File collector done. Signal out
      2011-07-04 19:13:01,107 INFO  [STDOUT] (Thread-107) Collector Event Received
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107) Exception in thread "Thread-107" 
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107) org.drools.RuntimeDroolsException: Unexpected exception executing action org.jbpm.process.instance.event.DefaultSignalManager$SignalProcessInstanceAction@c5ab84
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.drools.common.AbstractWorkingMemory.executeQueuedActions(AbstractWorkingMemory.java:996)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.drools.impl.StatefulKnowledgeSessionImpl.executeQueuedActions(StatefulKnowledgeSessionImpl.java:845)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.process.instance.event.DefaultSignalManager.signalEvent(DefaultSignalManager.java:89)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.process.instance.ProcessRuntimeImpl.signalEvent(ProcessRuntimeImpl.java:359)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.drools.impl.StatefulKnowledgeSessionImpl.signalEvent(StatefulKnowledgeSessionImpl.java:327)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at com.sample.FileCollector.run(FileCollector.java:74)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107) Caused by: java.lang.NullPointerException
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.persistence.processinstance.JPAProcessInstanceManager.addProcessInstance(JPAProcessInstanceManager.java:37)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.process.instance.AbstractProcessInstanceFactory.createProcessInstance(AbstractProcessInstanceFactory.java:36)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.process.instance.ProcessRuntimeImpl.startProcess(ProcessRuntimeImpl.java:168)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.process.instance.ProcessRuntimeImpl.createProcessInstance(ProcessRuntimeImpl.java:140)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.process.instance.ProcessRuntimeImpl.startProcess(ProcessRuntimeImpl.java:121)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.drools.common.AbstractWorkingMemory.startProcess(AbstractWorkingMemory.java:1095)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.drools.impl.StatefulKnowledgeSessionImpl.startProcess(StatefulKnowledgeSessionImpl.java:306)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.workflow.instance.node.SubProcessNodeInstance.internalTrigger(SubProcessNodeInstance.java:121)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.workflow.instance.impl.NodeInstanceImpl.trigger(NodeInstanceImpl.java:122)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.workflow.instance.impl.NodeInstanceImpl.triggerConnection(NodeInstanceImpl.java:185)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.workflow.instance.node.SplitInstance.internalTrigger(SplitInstance.java:129)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.workflow.instance.impl.NodeInstanceImpl.trigger(NodeInstanceImpl.java:122)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.workflow.instance.impl.NodeInstanceImpl.triggerConnection(NodeInstanceImpl.java:185)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.workflow.instance.impl.NodeInstanceImpl.triggerCompleted(NodeInstanceImpl.java:150)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.workflow.instance.node.JoinInstance.triggerCompleted(JoinInstance.java:152)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.workflow.instance.node.JoinInstance.internalTrigger(JoinInstance.java:52)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.workflow.instance.impl.NodeInstanceImpl.trigger(NodeInstanceImpl.java:122)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.workflow.instance.impl.NodeInstanceImpl.triggerConnection(NodeInstanceImpl.java:185)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.workflow.instance.node.SplitInstance.internalTrigger(SplitInstance.java:129)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.workflow.instance.impl.NodeInstanceImpl.trigger(NodeInstanceImpl.java:122)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.workflow.instance.impl.NodeInstanceImpl.triggerConnection(NodeInstanceImpl.java:185)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.workflow.instance.impl.NodeInstanceImpl.triggerCompleted(NodeInstanceImpl.java:150)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.workflow.instance.node.JoinInstance.triggerCompleted(JoinInstance.java:152)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.workflow.instance.node.JoinInstance.internalTrigger(JoinInstance.java:52)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.workflow.instance.impl.NodeInstanceImpl.trigger(NodeInstanceImpl.java:122)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.workflow.instance.impl.NodeInstanceImpl.triggerConnection(NodeInstanceImpl.java:185)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.workflow.instance.impl.NodeInstanceImpl.triggerCompleted(NodeInstanceImpl.java:150)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.workflow.instance.node.ActionNodeInstance.triggerCompleted(ActionNodeInstance.java:55)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.workflow.instance.node.ActionNodeInstance.internalTrigger(ActionNodeInstance.java:51)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.workflow.instance.impl.NodeInstanceImpl.trigger(NodeInstanceImpl.java:122)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.workflow.instance.impl.NodeInstanceImpl.triggerConnection(NodeInstanceImpl.java:185)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.workflow.instance.impl.NodeInstanceImpl.triggerCompleted(NodeInstanceImpl.java:150)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.workflow.instance.node.ActionNodeInstance.triggerCompleted(ActionNodeInstance.java:55)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.workflow.instance.node.ActionNodeInstance.internalTrigger(ActionNodeInstance.java:51)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.workflow.instance.impl.NodeInstanceImpl.trigger(NodeInstanceImpl.java:122)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.workflow.instance.impl.NodeInstanceImpl.triggerConnection(NodeInstanceImpl.java:185)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.workflow.instance.impl.NodeInstanceImpl.triggerCompleted(NodeInstanceImpl.java:150)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.workflow.instance.node.EventNodeInstance.triggerCompleted(EventNodeInstance.java:66)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.workflow.instance.node.EventNodeInstance.signalEvent(EventNodeInstance.java:50)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.workflow.instance.impl.WorkflowProcessInstanceImpl.signalEvent(WorkflowProcessInstanceImpl.java:353)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.jbpm.process.instance.event.DefaultSignalManager$SignalProcessInstanceAction.execute(DefaultSignalManager.java:117)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           at org.drools.common.AbstractWorkingMemory.executeQueuedActions(AbstractWorkingMemory.java:994)
      2011-07-04 19:13:01,138 ERROR [STDERR] (Thread-107)           ... 5 more
      
      
        • 1. Re: NullPointerException problem when console tried to start new sub process, triggered by signal sent from async task
          krisverlaenen

          Hi,

           

          It seems your FileCollector is directly accessing the internal session.  Note however, when using persistence, we actually wrap this internal session with a command service (SingleSessionCommandService) that takes care of persistence etc.  This seems to be an issue where you're getting issues by directly accessing the internal session, bypassing persistence setup etc.

           

          You should not talk to the internal session directly, your client calls should always go through the command service, using the ksession you get when using the JPAKnowledgeService to construct the session.

           

          Not sure if I understand your second issue.  The engine typically uses the calling thread to execute.  So if you call signalEvent, that thread will be used to send the event and execute the any process instance that is triggered because of this.  But this thread will return as soon as processing is done.  So this is either immediate (when there is no-one interested in the event) or after the process instance has reached a wait state (which again is almost instantaneous, as anything that is not should be modeled as an async task anyway).

           

          Kris

          • 2. Re: NullPointerException problem when console tried to start new sub process, triggered by signal sent from async task
            brucecui

            Hi Kris,

             

            Thanks a lot for the clarification. I am using the ksession which is injected when the WorkItemManager registers the handler. I'll keep digging on the direction you showed me. But last change took me almost a whole weekend. If you could help with the code change this time that would be great. Plz let me know if I need to open a JIRA for that. Or, as long as the console could keep functioning, if there is a way to turn off JPA that would be a secondary option for me, since for now persistence is not a necessary feature for my needs.

             

            And for the second question, I think you've answered it even with my poor expression. So if I undersatnd right, even the process is defined as an infinite loop, if in the loop it calls an async task first and then comes to a wait state by a signal event node, the thread will return, and the rest of the loops will be handed to the next signalEvent caller thread, and so goes on. The reason I asked this was becasue I worried about if the old threads didn't return, there would be more and more threads accumulated in similar scenario and finally ate up all resources. But if it works in the way you explained, there should be no problem.

             

             

             

            Bruce

             

             

            -----------------------------------------------------------------------------------

            Added:

             

            Hi Kris,

             

            I think I got some clue about how to send signal from async tasks by SingleSessionCommandService. Plz kindly correct me and advise if any misunderstanding in my below findings:

             

            SingleSessionCommandService requires 4 paramters to get exiting service for given session, which are sessionId, kbase, sessionConfig, and env. All the last 3 can be retrieved from kruntime, which I currently pass to the work item handler. But sessionId needs possession of the ksession reference. I may need to cast the kruntime to ksession in the handler code, but not sure if it's a safe action.

             

            Anyway with the 4 paramters I can have the corresponding SingleSessionCommandService. Then I pass a SignalEventCommand to it with processInstanceId, eventType and returnValue. And execute it.

             

            I'm going to have a try later. Hope it work.

             

             

            Bruce

             

             

            ------------------------------------------------------------------------------------

            Added again:

             

            Hi Kris,

             

            One good news and one not that good:

             

            The good news is, that it worked as expected. Initial test shows that no more JPA exceptions threw out when used SingleSessionCommandService to execute the SignalEventCommand. And the return vaule was reflected correctly.

             

            A new problem is, that even log shows the process actually ended, the console still shows the process existence (diagram shows it stops at a timer event which should be a wait state). When I tried to terminate them from console, it threw out exception said the process instance did not exist.

             

            I'll keep digging. Meanwhile could you kindly advise on this?

             

             

            Bruce

             

             

             

            ------------------------------------------------------------------------------------

            Added again and again:

             

            After trying with some more complex processes, I met various exceptions related to hibernate persistence, such like statement close, connection closed, lock timeout etc.. I noticed in the SingleSessionCommandService example, there is one dispose() method. But if I call this method after executing SignalEventCommand, I always got jdbc connection problem.

             

            I'm not sure if it is possible to turn off persistence and keep the console function just in memory?