9 Replies Latest reply on May 30, 2009 7:03 AM by freak182

    Fork/Join Problem

      Hello,

      I've stuck with this for more than a week. here is my process def:

      <?xml version="1.0" encoding="UTF-8"?>
      <process-definition xmlns="" name="forktest">
       <description>
       a test for fork/join workflow
       </description>
       <start-state name="Start">
       <transition to="fork"></transition>
       </start-state>
      
       <fork name="fork">
       <transition to="approver A" name="fk1"></transition>
       <transition to="approver B" name="fk2"></transition>
       </fork>
       <task-node name="approver A">
       <task name="FORKAPPRVA">
       <description>
       Please approve A
       </description>
       <assignment class="com.ccti.los.WfAssignment">
       <pooledactors>
       CORBANK
       </pooledactors>
       </assignment>
       </task>
       <transition to="join" name="jn1"></transition>
       </task-node>
       <task-node name="approver B">
       <task name="FORKAPPRVB">
       <description>
       Please approve B
       </description>
       <assignment class="com.ccti.los.WfAssignment">
       <pooledactors>
       APPROVERS
       </pooledactors>
       </assignment>
       </task>
       <transition to="join" name="jn2"></transition>
       </task-node>
       <join name="join">
       <event type="node-enter">
       <script name="joinscript">
       System.out.println("join: node enter events");
       </script>
       </event>
       <event type="node-leave">
       <script name="nodeleavescript">
       System.out.println("join: leaving join");
       </script>
       </event>
       <transition to="Review Document"></transition>
       </join>
       <task-node name="Review Document">
       <task name="FORKREVDOC">
       <description>
       Document for review
       </description>
       <assignment class="com.ccti.los.WfAssignment">
       <pooledactors>
       CORBANK
       </pooledactors>
       </assignment>
       </task>
       <event type="node-enter">
       <script name="revscript">
       System.out.println("Entering review doc task");
       </script>
       </event>
       <transition to="End"></transition>
       </task-node>
       <end-state name="End"></end-state>
      
      </process-definition>
      


      and here some trace:

      taskInstanceId = 30
      path Id = 16-@fk1
      13:28:21,718 DEBUG - JbpmContextInfo - creating jbpm context with service factories '[message, tx, scheduler, authentication, persistence, logging]'
      13:28:21,718 DEBUG - JbpmContext - creating org.jbpm.JbpmContext@1bdffcb
      13:28:21,718 DEBUG - bPersistenceServiceFactory - creating persistence service
      13:28:21,718 DEBUG - DbPersistenceService - injecting a session disables transaction
      13:28:21,734 DEBUG - GraphElement - event 'before-signal' on 'TaskNode(approver A)' for 'Token(/fk1)'
      13:28:21,750 DEBUG - GraphElement - event 'node-leave' on 'TaskNode(approver A)' for 'Token(/fk1)'
      13:28:21,750 DEBUG - GraphElement - event 'transition' on 'Transition(jn1)' for 'Token(/fk1)'
      13:28:21,750 DEBUG - GraphElement - event 'node-enter' on 'Join(join)' for 'Token(/fk1)'
      13:28:21,750 WARN - ProxyWarnLog - Narrowing proxy to class org.jbpm.graph.node.Join - this operation breaks ==
      13:28:21,765 DEBUG - GraphElement - executing action 'action[joinscript]'
      13:28:21,765 DEBUG - Token - token[38] is locked by token[38]
      13:28:21,781 DEBUG - Script - script input: {node=Join(join), token=Token(/fk1), task=null, executionContext=ExecutionContext[Token(/fk1)], taskInstance=null}
      join: node enter events
      13:28:21,875 DEBUG - Script - script output: {}
      13:28:21,875 DEBUG - Token - token[38] is unlocked by token[38]
      13:28:21,875 DEBUG - Join - acquiring FORCE lock on Token(/)
      13:28:21,890 DEBUG - Join - join will not yet reactivate parent: found concurrent token 'Token(/fk2)'
      13:28:21,890 DEBUG - GraphElement - event 'after-signal' on 'TaskNode(approver A)' for 'Token(/fk1)'
      13:28:21,890 DEBUG - Services - executing default save operations
      13:28:21,890 DEBUG - HibernateSaveOperation - saving process instance
      13:28:21,890 DEBUG - SaveLogsOperation - flushing logs to logging service.
      13:28:21,937 DEBUG - CascadeSaveOperation - cascading save of 'ProcessInstance(c8853452-9330-490c-91d6-ac42f8a40a96)'
      13:28:21,937 DEBUG - JbpmContext - closing jbpmContext org.jbpm.JbpmContext@1bdffcb
      13:28:21,937 DEBUG - Services - closing service 'logging': org.jbpm.logging.db.DbLoggingService@800a9e
      13:28:21,937 DEBUG - Services - closing service 'persistence': org.jbpm.persistence.db.DbPersistenceService@392c27
      13:28:21,937 DEBUG - Services - closing service 'tx': org.jbpm.tx.TxService@181bfd7
      
      taskInstanceId = 29
      path Id = 16-@fk2
      13:29:41,484 DEBUG - JbpmContextInfo - creating jbpm context with service factories '[message, tx, scheduler, authentication, persistence, logging]'
      13:29:41,484 DEBUG - JbpmContext - creating org.jbpm.JbpmContext@1f4bcdb
      13:29:41,484 DEBUG - bPersistenceServiceFactory - creating persistence service
      13:29:41,484 DEBUG - DbPersistenceService - injecting a session disables transaction
      13:29:41,500 DEBUG - GraphElement - event 'before-signal' on 'TaskNode(approver B)' for 'Token(/fk2)'
      13:29:41,515 DEBUG - GraphElement - event 'node-leave' on 'TaskNode(approver B)' for 'Token(/fk2)'
      13:29:41,515 DEBUG - GraphElement - event 'transition' on 'Transition(jn2)' for 'Token(/fk2)'
      13:29:41,515 DEBUG - GraphElement - event 'node-enter' on 'Join(join)' for 'Token(/fk2)'
      13:29:41,515 WARN - ProxyWarnLog - Narrowing proxy to class org.jbpm.graph.node.Join - this operation breaks ==
      13:29:41,515 DEBUG - GraphElement - executing action 'action[joinscript]'
      13:29:41,515 DEBUG - Token - token[37] is locked by token[37]
      13:29:41,515 DEBUG - Script - script input: {node=Join(join), token=Token(/fk2), task=null, executionContext=ExecutionContext[Token(/fk2)], taskInstance=null}
      join: node enter events
      13:29:41,531 DEBUG - Script - script output: {}
      13:29:41,531 DEBUG - Token - token[37] is unlocked by token[37]
      13:29:41,531 DEBUG - Join - acquiring FORCE lock on Token(/)
      13:29:41,546 DEBUG - Join - join will not yet reactivate parent: found concurrent token 'Token(/fk1)'
      13:29:41,546 DEBUG - GraphElement - event 'after-signal' on 'TaskNode(approver B)' for 'Token(/fk2)'
      13:29:41,546 DEBUG - Services - executing default save operations
      13:29:41,546 DEBUG - HibernateSaveOperation - saving process instance
      13:29:41,546 DEBUG - SaveLogsOperation - flushing logs to logging service.
      13:29:41,562 DEBUG - CascadeSaveOperation - cascading save of 'ProcessInstance(c8853452-9330-490c-91d6-ac42f8a40a96)'
      13:29:41,562 DEBUG - JbpmContext - closing jbpmContext org.jbpm.JbpmContext@1f4bcdb
      13:29:41,562 DEBUG - Services - closing service 'logging': org.jbpm.logging.db.DbLoggingService@7ad4d5
      13:29:41,562 DEBUG - Services - closing service 'persistence': org.jbpm.persistence.db.DbPersistenceService@2aee3f
      13:29:41,562 DEBUG - Services - closing service 'tx': org.jbpm.tx.TxService@7f788b
      
      


      I already read some related topics here in forum but no luck to solve my problem. And seems that how much i try modify my definition still it wont work. Still stuck on join and the task before join is not ended.

      Thanks a lot.
      Cheers.

        • 1. Re: Fork/Join Problem
          jbarrez

          What is your problem exactly?
          How are you ending your tasks?

          • 2. Re: Fork/Join Problem

            Hello,

            I end my task like this:

            wfEngine.signal(wfTask.path.id, null);
            wfEngine.endTask(taskInstanceId, null);

            but i already solve my problem. What happened is this:

            7.7. Combining your hibernate classes

            In your project, you might use hibernate for your persistence. Combining your persistent classes with the jBPM persistent classes is optional. There are two major benefits when combining your hibernate persistence with jBPM's hibernate persistence:

            First, session, connection and transaction management become easier. By combining jBPM and your persistence into one hibernate session factory, there is one hibernate session, one jdbc connection that handles both yours and jBPM's persistence. So automatically the jBPM updates are in the same transaction as the updates to your own domain model. This can eliminates the need for using a transaction manager.

            Secondly, this enable you to drop your hibernatable persistent object in to the process variables without any further hassle.

            The easiest way to integrate your persistent classes with the jBPM persistent classes is by creating one central hibernate.cfg.xml. You can take the jBPM src/config.files/hibernate.cfg.xml as a starting point and add references to your own hibernate mapping files in there.


            I perform an update to the persistence class in my domain model before it work fine. Now my question is, do i have always perform an update or any transaction in my domain model before committing the jbpm transaction? Is there a way that i dont have to perform transaction in my domain model but still jbpm will work just fine?

            Thanks a lot.
            Cheers.


            • 3. Re: Fork/Join Problem
              jbarrez

              This is completely depending on your transaction configuration. But updating your domain to make jbpm work doesn't seems right to me.

              Can u post your config?

              • 4. Re: Fork/Join Problem

                Yah, It doesn't seems right.

                I guess you are talking of jbpm.cfg.xml, right? Unfortuantely, It is in my office pc, gonna post tomorrow asap.

                Thanks a lot.
                Cheers.

                • 5. Re: Fork/Join Problem

                  As promised here is my jbpm.cfg.xml

                  <jbpm-configuration>
                  
                   <!--
                   This configuration is used when there is no jbpm.cfg.xml file found in the
                   root of the classpath. It is a very basic configuration without persistence
                   and message services. Only the authorization service installed.
                   You can parse and create processes, but when you try to use one of the
                   unavailable services, you'll get an exception.
                   -->
                  
                   <jbpm-context>
                   <service name="persistence">
                   <factory>
                   <bean class="org.jbpm.persistence.db.DbPersistenceServiceFactory">
                   <field name="isCurrentSessionEnabled"><true/></field>
                   <field name="isTransactionEnabled"><true/></field>
                   </bean>
                   </factory>
                   </service>
                   <service name="authentication" factory="org.jbpm.security.authentication.DefaultAuthenticationServiceFactory" />
                   <service name="logging" factory="org.jbpm.logging.db.DbLoggingServiceFactory" />
                   <service name="message" factory="org.jbpm.msg.db.DbMessageServiceFactory" />
                   <service name="scheduler" factory="org.jbpm.scheduler.db.DbSchedulerServiceFactory" />
                   <service name="tx" factory="org.jbpm.tx.TxServiceFactory" />
                   </jbpm-context>
                  
                   <!-- configuration property used by persistence service impl org.jbpm.persistence.db.DbPersistenceServiceFactory
                   <string name="resource.hibernate.cfg.xml" value="hibernate.cfg.xml" />
                   -->
                   <!-- configuration resource files pointing to default configuration files in jbpm-{version}.jar -->
                   <string name="resource.business.calendar" value="org/jbpm/calendar/jbpm.business.calendar.properties" />
                   <string name="resource.default.modules" value="org/jbpm/graph/def/jbpm.default.modules.properties" />
                   <string name="resource.converter" value="org/jbpm/db/hibernate/jbpm.converter.properties" />
                   <string name="resource.action.types" value="org/jbpm/graph/action/action.types.xml" />
                   <string name="resource.node.types" value="org/jbpm/graph/node/node.types.xml" />
                   <string name="resource.parsers" value="org/jbpm/jpdl/par/jbpm.parsers.xml" />
                   <string name="resource.varmapping" value="org/jbpm/context/exe/jbpm.varmapping.xml" />
                   <string name="resource.mail.templates" value="jbpm.mail.templates.xml" />
                  
                   <!-- class loading -->
                   <!-- <string name="jbpm.classLoader" value="jbpm" />
                   <string name="jbpm.customClassLoader.className" value="com...MyClassLoaderUtil" />
                   <bean name="jbpm.processClassLoader" class="org.jbpm.instantiation.DefaultProcessClassLoaderFactory" singelton="true" />-->
                  
                   <!-- make sure the block size matches the length in ByteArray.hbm.xml -->
                   <int name="jbpm.byte.block.size" value="1024" singleton="true" />
                   <bean name="jbpm.task.instance.factory" class="org.jbpm.taskmgmt.impl.DefaultTaskInstanceFactoryImpl" singleton="true" />
                   <bean name="jbpm.variable.resolver" class="org.jbpm.jpdl.el.impl.JbpmVariableResolver" singleton="true" />
                   <string name="jbpm.mail.smtp.host" value="192.168.1.1" />
                   <bean name="jbpm.mail.address.resolver" class="org.jbpm.identity.mail.IdentityAddressResolver" singleton="true" />
                   <string name="jbpm.mail.from.address" value="test@test.com.ph" />
                  
                   <bean name="jbpm.job.executor" class="org.jbpm.job.executor.JobExecutor">
                   <field name="jbpmConfiguration"><ref bean="jbpmConfiguration" /></field>
                   <field name="name"><string value="JbpmJobExecutor" /></field>
                   <field name="nbrOfThreads"><int value="2" /></field>
                   <field name="idleInterval"><int value="5000" /></field>
                   <field name="maxIdleInterval"><int value="3600000" /></field> <!-- 1 hour -->
                   <field name="historyMaxSize"><int value="20" /></field>
                   <field name="maxLockTime"><int value="600000" /></field> <!-- 10 minutes -->
                   <field name="lockMonitorInterval"><int value="60000" /></field> <!-- 1 minute -->
                   <field name="lockBufferTime"><int value="5000" /></field> <!-- 5 seconds -->
                   </bean>
                  
                  </jbpm-configuration>
                  


                  Thanks a lot.
                  Cheers.


                  • 6. Re: Fork/Join Problem
                    jbarrez

                    You configure jBPM to handle the transactions:

                    <field name="isTransactionEnabled"><true/></field>


                    but you comment out

                    <!-- configuration property used by persistence service impl org.jbpm.persistence.db.DbPersistenceSer
                    viceFactory
                     <string name="resource.hibernate.cfg.xml" value="hibernate.cfg.xml" />
                     -->


                    (check the comment). So my wild guess is that you need a hibernate config to make it work.



                    • 7. Re: Fork/Join Problem

                      I uncomment that line but i did not seem to work. I think that will be use if you not integrate jbpm in an application (that's my guess).

                      I try to put the WfEngine in spring-transaction of application and it work as expected.

                      • 8. Re: Fork/Join Problem
                        jbarrez

                        Yes, it works in Spring. Spring binds the transaction to the current thread, which you configure in your jbpm.cfg.xml:

                        <field name="isCurrentSessionEnabled"><true/></field>
                        


                        But you hadn't told me you were working in Spring and I assumed a traditional jBPM config ;-)

                        • 9. Re: Fork/Join Problem

                          Sorry, my bad. btw, what if im working with traditional jBPM and what could be the configuration.

                          Thanks a lot.
                          Cheers.