Menu

Jbpm error, works with prev processinstance_

Help
Javi
2008-10-10
2013-04-29
  • Javi

    Javi - 2008-10-10

    Hi,
    We are working with prms project and first version of nexopen.
    The project includes jbpm.

    While processing several tokens related to diferent service orders,
    first one works ok, but following tokens are pointing to first token processinstance_ id, so they are not able to find corresponding node.

    Seems first item in session is ok, and next requests have mistaken context.

    We cannot debug nexopen classes to see what happens with context and with its corresponding scope.

    some help?

     
    • Francesc Xavier

      Francesc Xavier - 2008-10-10

      hey,

      i am sorry but i need more info and detailed explanation, have you got problems with contexts? have yopu got problems in moving in the state diagram??.
      One question, why can not you debug into classes? you have got the sources haven't you? I am sorry but versions 0.2.x we do not have the sources in our repository (in fact package is not the official one of nexopen).

      NexOpen Team

       
    • Marc

      Marc - 2008-10-10

      I remember having this kind of issue in versions 0.2x of NexOpen, when in a single request we tried to create several processes.

      But I think we managed to solve it by code, by reseting the contexts explicitely, between each creation call. Something like this should be in that project code.

      hope it helps,

      Marc

       
    • Javi

      Javi - 2008-10-13

      Hi,

      likes me the idea that you propose to have to reseting the contexts explicitely. I think that the solution can to be near of this, but, how can i do reset the context from my app code? Is this possible out of NexOpen code?

      I have a text explaining a full detail of the error, i cut&paste it here, sorry but it’s in spanish. If somebody dont understand it, i translate the text to english:

      Tenemos una serie de estados definidos (en el processdefinition.xml) cada uno con sus transiciones posibles correspondientes y con los eventos a lanzar cuando se entra en el estado.
      Hay dos problemas diferentes:

      1. Cuando realizamos una acción de baja de servicio y se hace el cambio de estado de WAITINGFORROUTEASSIGNMENT al estado CANCELLED debería lanzar un evento que se encarga de informar a otra aplicación mediante un Web Service. Esta llamada no se realiza. Ésto sólo pasa en producción, en cambio en desarrollo, con el mismo código, no hay este problema por lo que me imagino que el fallo apunta a las tablas de jBPM de la base de datos de producción ¿?¿

      2. Al pasar del estado WAITINGFORROUTEASSIGNMENT al estado WAITINGFORAPPROVAL mediante la transición routeAssigned que está definida en el estado WAITINGFORROUTEASSINGMENT, salta la excepción de abajo, esta transición se lanza al asignar ruta a un servicio y llamar al método marksRequestAsRouteAssigned de la clase RequestFixedServiceAppService.java que incluyo más abajo. Aquí la excepción:

      2008-10-08 16:35:56,187 DEBUG [org.nextret.openfrwk.deployment.context.ClassPathXmlApplicationContext] Publishing event in context [org.nextret.openfrwk.deployment.context.ClassPathXmlApplicationContext;hashCode=13254846]: org.nextret.openfrwk.engine.exception.EngineExceptionEvent[source=org.nextret.openfrwk.workflow.NoSuchTransitionException: Workflow exception related with process 38785<> and entity class class es.bcn.emt.pmrs.model.requestservices.fixed.RequestFixedService<>Module :: Workflow
      Type :: Unchecked, unrecoverable or system exception
      Message :: Transition routeAssigned could not be signaled in the current process instance node [WAITINGFORAPPROVAL]]
      2008-10-08 16:35:56,187 ERROR [es.bcn.emt.pmrs.services.requestservices.fixed.RequestFixedServiceAppService] Raised an exception in RequestFixedServiceAppService in method public void es.bcn.emt.pmrs.services.requestservices.fixed.RequestFixedServiceAppService.marksRequestAsRouteAssigned(es.bcn.emt.pmrs.model.requestservices.fixed.RequestFixedService).
      Request transactional ID :: -1485099762396214231.
      Time :: Wed Oct 08 16:35:56 CEST 2008
      org.nextret.openfrwk.workflow.NoSuchTransitionException: Workflow exception related with process 38785<> and entity class class es.bcn.emt.pmrs.model.requestservices.fixed.RequestFixedService<>Module :: Workflow
      Type :: Unchecked, unrecoverable or system exception
      Message :: Transition routeAssigned could not be signaled in the current process instance node [WAITINGFORAPPROVAL]
          at org.nextret.openfrwk.workflow.providers.jbpm31.JbpmService$4.doInJbpm(JbpmService.java:256)
          at org.springmodules.workflow.jbpm31.JbpmTemplate$1.doInHibernate(JbpmTemplate.java:86)
          at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:362)
          at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:328)
          at org.springmodules.workflow.jbpm31.JbpmTemplate.execute(JbpmTemplate.java:79)
          at org.nextret.openfrwk.workflow.providers.jbpm31.JbpmService.handleTransition(JbpmService.java:230)
          at org.nextret.openfrwk.workflow.ProcessManager.handleTransition(ProcessManager.java:160)
          at org.nextret.openfrwk.workflow.intercept.ProcessManagerInterceptor.afterInvocation(ProcessManagerInterceptor.java:178)
          at org.nextret.openfrwk.workflow.intercept.ProcessManagerInterceptor.invoke(ProcessManagerInterceptor.java:145)
          at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:176)
          at org.nextret.openfrwk.engine.support.AopMethodInvocation.invoke(AopMethodInvocation.java:81)
          at org.nextret.openfrwk.engine.impl.BusinessServiceEngine.processInvokeWithTxInternal(BusinessServiceEngine.java:48)
          at org.nextret.openfrwk.engine.impl.AbstractServiceComponentEngine.processInvokeWithTx(AbstractServiceComponentEngine.java:188)
          at org.nextret.openfrwk.engine.support.ServiceComponentEngineInterceptor.invoke(ServiceComponentEngineInterceptor.java:107)
          at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:176)
          at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:615)
          at es.bcn.emt.pmrs.services.requestservices.fixed.RequestFixedServiceAppService$$EnhancerByCGLIB$$706a79a.marksRequestAsRouteAssigned(<generated>)
          at es.bcn.emt.pmrs.facades.RequestServiceFacadeImpl.assignRoute(RequestServiceFacadeImpl.java:265)
          at es.bcn.emt.pmrs.facades.RequestServiceFacadeImpl$$FastClassByCGLIB$$747d7aa2.invoke(<generated>)
          at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
      …….

      Éste es el trozo de código que lanza la excepción, pertenece al framework de nexOpen:

      if (transition==null || transition.length()==0) {
      //just signal
          processInstance.signal();
      } else {
          //assert if could be signaled
          Token token = processInstance.getRootToken();
          //must exist in order to be executed
          Transition _transition = token.getNode().getLeavingTransition(transition);
          if (_transition==null) {
              if (logger.isInfoEnabled()) {
      logger.info("Transition "+transition+" could not be signaled in the current process instance");
              }
      NoSuchTransitionException e = new NoSuchTransitionException ( "Transition "+transition+" could not be signaled " + "in the current process instance node ["+  token.getNode().getName()+ "]"  );
                  //the current process
              e.setProcessId(context.getProcessId());
              e.setEntity(context.getEntity());
              throw e;
          }
          //signal
          processInstance.signal(_transition);
      }

      En este código se ve que devuelve la transición (_transition) a null, porque la busca en la lista de transiciones de WAITINGFORAPPROVAL, pero ahí no existe.

      Lo curioso es que ésto sólo pasa cuando ya se ha hecho esa transición dos o tres veces seguidas con diferentes servicios. La primera o segunda vez funciona correctamente. Este error se da por igual en producción como en desarrollo.
      Parece cómo si intentara realizar la transición con el primer servicio lanzado, ya que el número de process que sale en la excepción siempre corresponde a un cambio de estado anterior que haya funcionado correctamente.

      Quizás otra cosa significativa es que en algunas de éstas excepciones el id del process es el mismo para dos rfs diferentes.

      Aquí el código del método marksRequestAsRouteAssigned de la clase RequestFixedServiceAppService.java:

      @Transition(name = "routeAssigned")
      public void marksRequestAsRouteAssigned ( RequestFixedService rfs )
      {
      {
              Assert.notNull(rfs);       
      }
      //    Change the State for the current Service
          this.changeState(rfs,
              StateType.WAITINGFORAPPROVAL);
      }

      Y del método changeState:

      private void changeState(RequestFixedService requestFixedService,
          StateType newStateType)
      {
          {
              Assert.notNull(newStateType);
          }
          // Get the current State
          RequestFixedServiceState currState = requestFixedService.getState();

          // Ensure the new State is different from the current state
          if ( currState != null ){
              {
                  // if there's a currState must hace a StateType
                  Assert.notNull(currState.getStateType());               
              }
              if ( newStateType.equals(currState.getStateType())) {
                  return;
              }   
          }

          Date currDate = this.timeService.getDate();
          if (currState != null) {
              // If a current state was present, move it to the history
              currState.setLeaveStateDate(currDate);
              requestFixedService.addStateHistoric(currState);
              // historyState.add(currState);
          }

          // Add the new Request Fixed Service state
          RequestFixedServiceState newState = new RequestFixedServiceState();
          newState.setStateType(newStateType);
          newState.setEntryStateDate(currDate);
          this.pm.persist(newState);

          requestFixedService.setState(newState);
          this.pm.merge(requestFixedService);
      }

      Y por último, los estados y transiciones involucradas del processdefinition.xml:

      <process-definition    name="request-fixed-service">
      ...
         <state name="WAITINGFORROUTEASSIGNMENT">
                <event type="node-enter">
                  <action expression="${requestFixedServiceProcessEventDispatcher.registerStateChangeEvent}" />
             </event>     
                 <!-- That transition must be fired by AOP -->
            <transition name="routeAssigned" to="NOTIFY_ROUTEASSIGNMENT"></transition>
            <transition name="cancel" to="NOTIFY_CANCELLATION"></transition>
         </state>
         <state name="WAITINGFORAPPROVAL">
                <!-- event type="node-enter">
                  <action expression="${requestFixedServiceProcessEventDispatcher.registerStateChangeEvent}" />
             </event -->
            <transition name="notAproved" to="NOTIFY_PREAUTHORIZATION"/>
            <transition name="deny" to="WAITINGTONOTIFYDENY"/>
            <transition name="authorizeAssignment" to="WAITINGTOCOMMUNICATEAUTHORIZATION"/>
            <transition name="cancel" to="NOTIFY_CANCELLATION"></transition>
         </state>
      ...
         <node name="NOTIFY_ROUTEASSIGNMENT">
                 <event type="node-enter">
                     <action expression="${requestFixedServiceProcessEventDispatcher.notifyRouteAssignment}"/>
                 </event>
            <transition name="next" to="WAITINGFORAPPROVAL"></transition>
         </node>
      ...
         <end-state name="CANCELLED">
                 <event type="node-enter">
                    <action expression="${requestFixedServiceProcessEventDispatcher.notifyCancellation}" />
                     <action expression="${requestFixedServiceProcessEventDispatcher.registerStateChangeEvent}" />
              </event>
         </end-state>
         <node name="NOTIFY_CANCELLATION">
             <event type="node-enter">
                    <action expression="${requestFixedServiceProcessEventDispatcher.notifyCancellation}" />
              </event>
            <transition name="next" to="CANCELLED"></transition>
         </node>
      ...
      </process-definition>

      This is the end of text. Very thanks for your help and your replies.

       
      • Toni López

        Toni López - 2008-10-13

        Do you know if the process_definition has been changed?
        It's necessary to end all the started process before update to a new process_definition.
        It's seems that the old process are working with the old process-definition.

        If that assumption is correct the only way, as i know, is to modify the information on the database.

         
    • Javi

      Javi - 2008-10-13

      I think that the processdefinition hasnt been changed, anyway, until a process finish, dont starts the next.

      What is this information that i would have to change on the database?

       
      • Toni López

        Toni López - 2008-10-13

        I'm not Sure...
        take a look at
        http://docs.jboss.com/jbpm/v3.1/userguide/en/html_single/#processversioning
        http://docs.jboss.com/jbpm/v3.1/userguide/en/html_single/#migratingprocessinstances

        At early versions of NexOpen, everytime you deploy your application, a new version of Process Definition has been created. When you create a new Process Instance, that process-instance is binded to a version of a Process-Definition.
        If you design a new Process-Definition those process-instance that had been created before this version are still binded to the old Process-definition.

         
        • Francesc Xavier

          Francesc Xavier - 2008-10-13

          As far as i Know, Toni is right, every time you deploy every time you create a new process definition. Please, check the URLs provided by Toni and use the trick to remove context using Contexts class (jbpm integration is difficult to manage specially in complex state diagrams).

          This error was corrected in 0.3.x versions and higher (Toni is correct?). of course, We do not recommend to upgrade to thsi version for several incompatibilities.

          Hope this info could help you, if you find a way to solve this issue,please report us and we will introduce in higher releases.

          Many thanks

          NexOpen Team

          P.D Please, notice that official NexOpen versions starts with 0.3.0 and higher, previous one are considered not part of the project and we have not the source code.

           
    • Javi

      Javi - 2008-10-13

      Ok, ill check this urls, i think that this way can to be interesting to resolve my problem.

      Very thanks for your help. ill take a look and if i get a solution ill post it here.

       
      • Francesc Xavier

        Francesc Xavier - 2008-10-13

        Hope you will find the solution. Please, if you find the solution please post here.
        Thanks to your contribution and for sharing your experiences, we can create a more robust and reliable framework.

        Francesc

         
    • Javi

      Javi - 2008-10-29

      Hi!

      I find the solution in context, how Marc said.

      jBPM took the processinstance of the previus node that it was in waitingforapproval state.
      Reseting de context explicitely before of transition, the problem is solved.

      Thanks to all for your help!

       

Log in to post a comment.