1 2 Previous Next 20 Replies Latest reply on Feb 1, 2013 6:01 AM by Gareth Edwards

    jbpm 5.3 - kSession.dispose() - Error: Session was previously disposed

    Pedro Gonçalves Newbie

      I'm using jbpm5.3, with spring and hibernate.

       

      In the method I use to start a process instance, if I use the kSession.dispose() it will give me the error below, but if not, it will work well! (The application was just started, so no kSessions used before, and the database was clean)

      It is not supposed to call dispose() when kSession will not be used anymore? (I have one kSession per process instance)

       

       

      When I call kSession.dispose() for the first time, I got the error:

      java.lang.IllegalStateException: Illegal method call. This session was previously disposed.
                at org.drools.reteoo.DisposedReteooWorkingMemory.getProcessRuntime(DisposedReteooWorkingMemory.java:270)
                at org.drools.impl.StatefulKnowledgeSessionImpl.getProcessRuntime(StatefulKnowledgeSessionImpl.java:874)
                at org.drools.persistence.SingleSessionCommandService$SynchronizationImpl.afterCompletion(SingleSessionCommandService.java:448)
                at org.drools.persistence.jta.JtaTransactionSynchronizationAdapter.afterCompletion(JtaTransactionSynchronizationAdapter.java:25)
                at bitronix.tm.BitronixTransaction.fireAfterCompletionEvent(BitronixTransaction.java:497)
                at bitronix.tm.BitronixTransaction.rollback(BitronixTransaction.java:283)
                at bitronix.tm.BitronixTransactionManager.rollback(BitronixTransactionManager.java:129)
                at org.springframework.transaction.jta.JtaTransactionManager.doRollback(JtaTransactionManager.java:1037)
      (......)
      

       

      How I start the process instance:

       

      public void startProcess(CoreData coreData, String definitionId) {
      
       //Creating variables ...
      (...)
           //taskService is a spring bean
           LocalTaskService localTaskService = new LocalTaskService(taskService);
      
      //GetKSession with null will create a new kSession
           StatefulKnowledgeSession kSession = getKSession(null, localTaskService);
           JPAWorkingMemoryDbLogger jbpmLogger = new JPAWorkingMemoryDbLogger(kSession);
      
           ProcessInstance processInstance = kSession.startProcess(definitionId, variables);
      
           jbpmLogger.dispose();
      //If I remove this kSession.dispose() it will work well, but will give a optimistic lock error later....
           kSession.dispose();
      }
      

       

      How I create the kSession:

       

      public StatefulKnowledgeSession getKSession(Integer kSessionId, LocalTaskService localTaskService) {
      
           StatefulKnowledgeSession kSession;
      
           Environment env = KnowledgeBaseFactory.newEnvironment();
           env.set(EnvironmentName.ENTITY_MANAGER_FACTORY, entityManagerWorkflow.getEntityManagerFactory());
           env.set(EnvironmentName.TRANSACTION_MANAGER, TransactionManagerServices.getTransactionManager());
      
           if (kSessionId == null) {
                kSession = JPAKnowledgeService.newStatefulKnowledgeSession(knowledgeBaseProvider.getKbase(), null, env);
           } else {
                kSession = JPAKnowledgeService.loadStatefulKnowledgeSession(kSessionId, knowledgeBaseProvider.getKbase(), null, env);
           }
      /*
      * Adding Listner
      * */
           CustomProcessEventListener customProcessEventListener = new CustomProcessEventListener();
           kSession.addEventListener(customProcessEventListener);
      
      /*
      * Register WorkItemHandler
      * */
           GenericHTWorkItemHandler handler = new GenericHTWorkItemHandler(kSession);
           handler.setClient(localTaskService);
           handler.setLocal(true);
           handler.setIpAddress("127.0.0.1");
           handler.setPort(9123);
           handler.connect();
           kSession.getWorkItemManager().registerWorkItemHandler("Human Task", handler);
      
           return kSession;
      }
      
      

       

      Thanks

        • 1. Re: jbpm 5.3 - kSession.dispose() - Error: Session was previously disposed
          Maciej Swiderski Master

          the issue is that you dispose the session before transaction is completed which cause the mentioned error. Make sure that the dispose will happen after transaction completion.

           

          HTH

          • 3. Re: jbpm 5.3 - kSession.dispose() - Error: Session was previously disposed
            Miloud Haimoune Newbie

            Hi,

             

            I'm facing the same issue :  java.lang.IllegalStateException: Illegal method call. This session was previously disposed. when I call session.dispose ().

             

            How did you manage to solve it ?

             

            in my case I have one running ksession where I have all my process instances.

             

            In my application I have I button where I call the dispose  methode, this same methode was working with JBPM 5.2.

             

            Cheers

            • 4. Re: jbpm 5.3 - kSession.dispose() - Error: Session was previously disposed
              Miloud Haimoune Newbie

              here the  exception trace :

               

              Caused by: java.lang.IllegalStateException: Illegal method call. This session was previously disposed.
                  at org.drools.reteoo.DisposedReteooWorkingMemory.getSessionClock(DisposedReteooWorkingMemory.java:398)
                  at org.drools.impl.StatefulKnowledgeSessionImpl.getSessionClock(StatefulKnowledgeSessionImpl.java:256)
                  at org.drools.marshalling.impl.ProtobufMarshaller.marshall(ProtobufMarshaller.java:151)
                  at org.drools.persistence.SessionMarshallingHelper.getSnapshot(SessionMarshallingHelper.java:72)
                  at org.drools.persistence.info.SessionInfo.update(SessionInfo.java:85)
                  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 org.hibernate.ejb.event.BeanCallback.invoke(BeanCallback.java:23)
                  at org.hibernate.ejb.event.EntityCallbackHandler.callback(EntityCallbackHandler.java:80)
                  at org.hibernate.ejb.event.EntityCallbackHandler.preUpdate(EntityCallbackHandler.java:65)
                  at org.hibernate.ejb.event.EJB3FlushEntityEventListener.invokeInterceptor(EJB3FlushEntityEventListener.java:41)
                  at org.hibernate.event.def.DefaultFlushEntityEventListener.handleInterception(DefaultFlushEntityEventListener.java:330)
                  at org.hibernate.event.def.DefaultFlushEntityEventListener.scheduleUpdate(DefaultFlushEntityEventListener.java:270)
                  at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:151)
                  at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:219)
                  at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:99)
                  at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:49)
                  at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027)
              
              • 5. Re: jbpm 5.3 - kSession.dispose() - Error: Session was previously disposed
                Pedro Gonçalves Newbie

                I can't say that I resolved the problem... I've just realized that I just postpone the error. But I'm still trying to understand it.

                 

                The solution for that problem is what Maciej said: the dispose is being done before the transaction end. Try to do it after the transaction end.

                 

                I've never worked with jbpm 5.2, but I'm thinking in give it a try, as I'm having some strange problems in 5.3 (which I'm currently investigating if the problem is my app or the jbpm5.3).

                • 6. Re: jbpm 5.3 - kSession.dispose() - Error: Session was previously disposed
                  Chris Johnson Newbie

                  We need a response for this problem. I am having the same issue and it is delaying UAT testing.

                  • 7. Re: jbpm 5.3 - kSession.dispose() - Error: Session was previously disposed
                    Maciej Swiderski Master

                    Guys, this really depends on how you use jbpm so there can't be single answer that fits all. So if you provide bit more details about your application design maybe we could help out.

                     

                    Cheers

                    • 8. Re: jbpm 5.3 - kSession.dispose() - Error: Session was previously disposed
                      Chris Johnson Newbie

                      I am using the LocalTaskService and here is the sequence of events that causes the problem.

                       

                      1) My client starts a process then disposes the session.

                      2) My client loads the session that was disposed in step 1 and  claims the first task in the process.

                      3) My client loads the session that was disposed in step 1 and  starts the first task in the process.

                      4) My client loads the session that was disposed in step 1 and  completes the first task in the process and JBPM throws the following exception:

                       

                      Caused by: java.lang.IllegalStateException: Illegal method call. This session was previously disposed.
                          at org.drools.reteoo.DisposedReteooWorkingMemory.getSessionClock(DisposedReteooWorkingMemory.java:398)
                          at org.drools.impl.StatefulKnowledgeSessionImpl.getSessionClock(StatefulKnowledgeSessionImpl.java:256)
                          at org.drools.marshalling.impl.ProtobufMarshaller.marshall(ProtobufMarshaller.java:151)
                          at org.drools.persistence.SessionMarshallingHelper.getSnapshot(SessionMarshallingHelper.java:72)
                          at org.drools.persistence.info.SessionInfo.update(SessionInfo.java:85)
                          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 org.hibernate.ejb.event.BeanCallback.invoke(BeanCallback.java:23)
                          at org.hibernate.ejb.event.EntityCallbackHandler.callback(EntityCallbackHandler.java:80)
                          at org.hibernate.ejb.event.EntityCallbackHandler.preUpdate(EntityCallbackHandler.java:65)
                          at org.hibernate.ejb.event.EJB3FlushEntityEventListener.invokeInterceptor(EJB3FlushEntityEventListener.java:41)
                          at org.hibernate.event.def.DefaultFlushEntityEventListener.handleInterception(DefaultFlushEntityEventListener.java:330)
                          at org.hibernate.event.def.DefaultFlushEntityEventListener.scheduleUpdate(DefaultFlushEntityEventListener.java:270)
                          at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:151)
                          at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:219)
                          at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:99)
                          at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:49)
                          at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027)

                      • 9. Re: jbpm 5.3 - kSession.dispose() - Error: Session was previously disposed
                        Brian Wallis Master

                        I have the same problem where I am getting a session from within an onMessage() method of an Message Driven Bean. The transactions are container controlled so I cannot call the ksession dispose after the transaction ends since the container ends the transaction not me.

                         

                        This was working with JBPM 5.1.

                         

                        {code}

                        @TransactionAttribute(value = TransactionAttributeType.REQUIRED)

                            public void onMessage(Message message)

                            {

                                try

                                {

                                    DocumentCreated inbound = MessageBusUtility.unmarshallMessage(message);

                                    LOGGER.info("Message body: " + inbound);

                         

                         

                                    ksession = jbpmLauncher.getSession();

                         

                         

                                    // start a new process instance

                                    Map<String, Object> params = buildParams(inbound);

                                    ksession.startProcess("au.com.infomedix.harvey." + inbound.getDocumentGroup().getWorkflowName().toLowerCase(), params);

                                    Audit.newWorkflow((String) params.get(EReferralFields.PATIENT_URNO.getKey()), (String) params.get(EReferralFields.PATIENT_DOMAIN.getKey()),

                                            (String) params.get(EReferralFields.PATIENT_FIRSTNAME.getKey()), (String) params.get(EReferralFields.PATIENT_LASTNAME.getKey()));

                                    ksession.fireAllRules();

                         

                         

                                    // TODO This should be disposed but this fails within the transaction boundary.

                        //             ksession.dispose(); //dispose after use.

                                }

                                catch (Exception e)

                                {

                                    throw new RuntimeException("Exception occurred.", e);

                                }

                            }

                        {code}

                         

                        where the getSession method is

                         

                        {code}

                        public StatefulKnowledgeSession getSession(int sessionId)

                            {

                                initialize();

                         

                         

                                StatefulKnowledgeSession ksession = JPAKnowledgeService.loadStatefulKnowledgeSession(sessionId, kbase, kconfig, kenvironment);

                                registerWorkItemHandlers(ksession);

                         

                         

                                return ksession;

                            }

                        {code}

                         

                        Not sure how to proceed with this. Seems I need to get the container to dispose of the session after the transaction but that isn't possible with an MDB as far as I know.

                         

                        thanks.

                        • 10. Re: jbpm 5.3 - kSession.dispose() - Error: Session was previously disposed
                          Maciej Swiderski Master

                          Chris, could you prepare simple test case that illustrates that? That would give me a quick start to investigate the case and try to come up with some solutions for you.

                           

                          Cheers

                          • 11. Re: jbpm 5.3 - kSession.dispose() - Error: Session was previously disposed
                            Amin Mohammed-Coleman Newbie

                            You could register a transaction synchronisation to dispose of the session.  If you are using Spring you can use one of it's Transaction Synchronisation utility class to register the sync.

                            • 12. Re: jbpm 5.3 - kSession.dispose() - Error: Session was previously disposed
                              Brian Wallis Master

                              In our case the session is loaded inside the onMessage() method of a JEE Message Driven Bean. The JEE SessionSynchronization interface or the @AfterCompletion annotations are not available on MDBs. I'm not using spring.

                               

                              It seems that there isn't a JEE6 way to run something after the transaction is committed for a MDB.

                               

                              I think the only option with the MDB is to configure the bean for transactions NOT_SUPPORTED, start and commit my own transaction around the interaction with the workflow session and client mode message acknowledgement post the commit. I will also have to deal with the small chance of duplicate message delivery.

                               

                              Somewhat more complex than I'd hoped for. Quite a major change required for an update from jbpm 5.1 to 5.3!

                              • 13. Re: jbpm 5.3 - kSession.dispose() - Error: Session was previously disposed
                                Amin Mohammed-Coleman Newbie

                                Haven't done any MDBs but don't you need to implement SessionSynchronisation interface?  Just wondering whether in the afterBegin(..) you create the session and the in the afterCompletion(..) dispose?

                                • 14. Re: jbpm 5.3 - kSession.dispose() - Error: Session was previously disposed
                                  Brian Wallis Master

                                  the session synchronisation and related annotations only apply to stateful session beans so out of luck with the MDBs.

                                  1 2 Previous Next