1 2 Previous Next 15 Replies Latest reply on Oct 17, 2012 4:39 AM by mai.s

    Human task API, how to move forward in the workflow ?

    jcharnet

      I'm finishing my human task, with the taskClient API, calling start and complete on the human task. But my next task, (after the human task) never gets called.

       

      Do I need to do something else in my code ?

       

       

      Thanks a lot.

       

      John

        • 1. Re: Human task API, how to move forward in the workflow ?
          calca

          I have made something similar in a test, it may help you:

           

          https://github.com/calcacuervo/JBPM5-Samples/blob/master/human-tasks/src/test/java/com/test/HumanTaskTest.java

           

          How are you checking that your next task in not getting called?

           

          Demian

          • 2. Re: Human task API, how to move forward in the workflow ?
            tsurdilovic
            • 3. Re: Human task API, how to move forward in the workflow ?
              jcharnet

              Thansk for your reply.

              I took a look at your example Demian, and also I've already had looked at jbpm examples like Tihomir had suggested. Apparently there is not any difference in the way I'm using the Task Client API.

               

              The way I'm checking if the next task is getting called is by debug. Mas next task has a task handler, and I have a breakpoint in this task handler.

              If I create a custom task handler for the human task, and call the completeWorkItem method, my next task does get called. So I know that there is nothing wrong with this next task.

               

              My environment is:

              Spring for the model and transactions ( I do not configure any jbpm in spring )

              JPA - Hibernate for persistence.

               

              I'm also persisting the workflow in the database with JPAKnowledgeService and CommandBasedWSHumanTaskHandler.

               

              Any other ideas I could try ?

               

              Thanks,

               

              John

              • 4. Re: Human task API, how to move forward in the workflow ?
                calca

                Hi John.

                 

                Are you using the Console Logger? What is it logging after you call complete?

                 

                If possible, could you please provide a test that shows this error with you configurations?

                 

                Thanks,

                 

                Demian

                • 5. Re: Human task API, how to move forward in the workflow ?
                  jcharnet

                  Here is the complete log.

                  It has hibernate statements and the jbpm console logger.

                  I can't see through the jbpm console logger, anything related to the complete task. But if you see the hibernate statemens, you will find some updates to the task table, the last update sets the status to Completed.

                   

                  Thanks

                  Hibernate:

                      select

                          task0_.id as col_0_0_,

                          deadline1_.id as col_1_0_,

                          deadline1_.deadline_date as col_2_0_

                      from

                          Task task0_,

                          Deadline deadline1_

                      where

                          (

                              deadline1_.id in (

                                  select

                                      startdeadl2_.id

                                  from

                                      Deadline startdeadl2_

                                  where

                                      task0_.id=startdeadl2_.Deadlines_StartDeadLine_Id

                              )

                              or deadline1_.id in (

                                  select

                                      enddeadlin3_.id

                                  from

                                      Deadline enddeadlin3_

                                  where

                                      task0_.id=enddeadlin3_.Deadlines_EndDeadLine_Id

                              )

                          )

                          and deadline1_.escalated=0

                      order by

                          deadline1_.deadline_date

                  Hibernate:

                      select

                          hibernate_sequence.nextval

                      from

                          dual

                  Hibernate:

                      select

                          hibernate_sequence.nextval

                      from

                          dual

                  BEFORE RULEFLOW VARIABLE CHANGED ator=Joao process:test.b[id=test.bpmn]

                  Hibernate:

                      select

                          hibernate_sequence.nextval

                      from

                          dual

                  AFTER RULEFLOW VARIABLE CHANGED ator=Joao process:test.b[id=test.bpmn]

                  Hibernate:

                      select

                          hibernate_sequence.nextval

                      from

                          dual

                  BEFORE RULEFLOW STARTED process:test.b[id=test.bpmn]

                  Hibernate:

                      select

                          hibernate_sequence.nextval

                      from

                          dual

                  BEFORE PROCESS NODE TRIGGERED node:Start[id=1] process:test.b[id=test.bpmn]

                  Hibernate:

                      select

                          hibernate_sequence.nextval

                      from

                          dual

                  BEFORE PROCESS NODE EXITED node:Start[id=1] process:test.b[id=test.bpmn]

                  Hibernate:

                      select

                          hibernate_sequence.nextval

                      from

                          dual

                  BEFORE PROCESS NODE TRIGGERED node:Hello World[id=2] process:test.b[id=test.bpmn]

                  Hello world!

                  Date: Wed Jul 13 11:31:50 BRT 2011

                  BEFORE RULEFLOW VARIABLE CHANGED action=Hello process:test.b[id=test.bpmn]

                  Hibernate:

                      select

                          hibernate_sequence.nextval

                      from

                          dual

                  AFTER RULEFLOW VARIABLE CHANGED action=Hello process:test.b[id=test.bpmn]

                  Context: org.drools.spi.ProcessContext@d68b39

                  Hibernate:

                      select

                          hibernate_sequence.nextval

                      from

                          dual

                  BEFORE PROCESS NODE EXITED node:Hello World[id=2] process:test.b[id=test.bpmn]

                  Hibernate:

                      select

                          hibernate_sequence.nextval

                      from

                          dual

                  BEFORE PROCESS NODE TRIGGERED node:User Task[id=9] process:test.b[id=test.bpmn]

                  Hibernate:

                      select

                          hibernate_sequence.nextval

                      from

                          dual

                  AFTER PROCESS NODE TRIGGERED node:User Task[id=9] process:test.b[id=test.bpmn]

                  AFTER PROCESS NODE TRIGGERED node:Hello World[id=2] process:test.b[id=test.bpmn]

                  AFTER PROCESS NODE TRIGGERED node:Hello World[id=2] process:test.b[id=test.bpmn]

                  AFTER PROCESS NODE TRIGGERED node:Start[id=1] process:test.b[id=test.bpmn]

                  AFTER PROCESS NODE TRIGGERED node:Start[id=1] process:test.b[id=test.bpmn]

                  AFTER RULEFLOW STARTED process:test.b[id=test.bpmn]

                  Hibernate:

                      select

                          hibernate_sequence.nextval

                      from

                          dual

                  Hibernate:

                      select

                          user_.id

                      from

                          OrganizationalEntity user_

                      where

                          user_.id=?

                  Hibernate:

                      select

                          hibernate_sequence.nextval

                      from

                          dual

                  Hibernate:

                      select

                          hibernate_sequence.nextval

                      from

                          dual

                  Hibernate:

                      select

                          hibernate_sequence.nextval

                      from

                          dual

                  Hibernate:

                      select

                          hibernate_sequence.nextval

                      from

                          dual

                  Hibernate:

                      insert

                      into

                          Task

                          (allowedToDelegate, taskInitiator_id, priority, activationTime, actualOwner_id, createdBy_id, createdOn, documentAccessType, documentContentId, documentType, expirationTime, faultAccessType, faultContentId, faultName, faultType, outputAccessType, outputContentId, outputType, parentId, previousStatus, processInstanceId, skipable, status, workItemId, id)

                      values

                          (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)

                  Hibernate:

                      insert

                      into

                          I18NText

                          (language, text, id)

                      values

                          (?, ?, ?)

                  Hibernate:

                      insert

                      into

                          I18NText

                          (language, text, id)

                      values

                          (?, ?, ?)

                  Hibernate:

                      insert

                      into

                          I18NText

                          (language, text, id)

                      values

                          (?, ?, ?)

                  Hibernate:

                      insert

                      into

                          Content

                          (content, id)

                      values

                          (?, ?)

                  Hibernate:

                      update

                          Task

                      set

                          allowedToDelegate=?,

                          taskInitiator_id=?,

                          priority=?,

                          activationTime=?,

                          actualOwner_id=?,

                          createdBy_id=?,

                          createdOn=?,

                          documentAccessType=?,

                          documentContentId=?,

                          documentType=?,

                          expirationTime=?,

                          faultAccessType=?,

                          faultContentId=?,

                          faultName=?,

                          faultType=?,

                          outputAccessType=?,

                          outputContentId=?,

                          outputType=?,

                          parentId=?,

                          previousStatus=?,

                          processInstanceId=?,

                          skipable=?,

                          status=?,

                          workItemId=?

                      where

                          id=?

                  Hibernate:

                      update

                          I18NText

                      set

                          Task_Descriptions_Id=?

                      where

                          id=?

                  Hibernate:

                      update

                          I18NText

                      set

                          Task_Names_Id=?

                      where

                          id=?

                  Hibernate:

                      insert

                      into

                          PeopleAssignments_BAs

                          (task_id, entity_id)

                      values

                          (?, ?)

                  Hibernate:

                      insert

                      into

                          PeopleAssignments_PotOwners

                          (task_id, entity_id)

                      values

                          (?, ?)

                  Hibernate:

                      update

                          I18NText

                      set

                          Task_Subjects_Id=?

                      where

                          id=?

                  Hibernate:

                      select

                          task0_.id as col_0_0_,

                          task0_.processInstanceId as col_1_0_,

                          i18ntext4_.text as col_2_0_,

                          subjects3_.text as col_3_0_,

                          i18ntext5_.text as col_4_0_,

                          task0_.status as col_5_0_,

                          task0_.priority as col_6_0_,

                          task0_.skipable as col_7_0_,

                          task0_.actualOwner_id as col_8_0_,

                          task0_.createdBy_id as col_9_0_,

                          task0_.createdOn as col_10_0_,

                          task0_.activationTime as col_11_0_,

                          task0_.expirationTime as col_12_0_

                      from

                          Task task0_

                      left outer join

                          OrganizationalEntity user1_

                              on task0_.createdBy_id=user1_.id

                      left outer join

                          OrganizationalEntity user2_

                              on task0_.actualOwner_id=user2_.id

                      left outer join

                          I18NText subjects3_

                              on task0_.id=subjects3_.Task_Subjects_Id,

                          I18NText i18ntext4_,

                          I18NText i18ntext5_,

                          OrganizationalEntity organizati6_

                      where

                          organizati6_.id=?

                          and (

                              organizati6_.id in (

                                  select

                                      potentialo9_.entity_id

                                  from

                                      PeopleAssignments_PotOwners potentialo9_

                                  where

                                      task0_.id=potentialo9_.task_id

                              )

                          )

                          and i18ntext4_.language=?

                          and (

                              i18ntext4_.id in (

                                  select

                                      names10_.id

                                  from

                                      I18NText names10_

                                  where

                                      task0_.id=names10_.Task_Names_Id

                              )

                          )

                          and (

                              subjects3_.language=?

                              or (

                                  select

                                      count(subjects11_.Task_Subjects_Id)

                                  from

                                      I18NText subjects11_

                                  where

                                      task0_.id=subjects11_.Task_Subjects_Id

                              )=0

                          )

                          and (

                              i18ntext5_.language=?

                              and (

                                  i18ntext5_.id in (

                                      select

                                          descriptio12_.id

                                      from

                                          I18NText descriptio12_

                                      where

                                          task0_.id=descriptio12_.Task_Descriptions_Id

                                  )

                              )

                              or (

                                  select

                                      count(descriptio13_.Task_Descriptions_Id)

                                  from

                                      I18NText descriptio13_

                                  where

                                      task0_.id=descriptio13_.Task_Descriptions_Id

                              )=0

                          )

                          and (

                              task0_.status in (

                                  'Created' , 'Ready' , 'Reserved' , 'InProgress' , 'Suspended'

                              )

                          )

                          and (

                              task0_.expirationTime is null

                          )

                  Hibernate:

                      select

                          user0_.id as id10_0_

                      from

                          OrganizationalEntity user0_

                      where

                          user0_.id=?

                          and user0_.DTYPE='User'

                  Hibernate:

                      select

                          task0_.id as id15_3_,

                          task0_.allowedToDelegate as allowedT2_15_3_,

                          task0_.taskInitiator_id as taskIni23_15_3_,

                          task0_.priority as priority15_3_,

                          task0_.activationTime as activati4_15_3_,

                          task0_.actualOwner_id as actualO24_15_3_,

                          task0_.createdBy_id as createdBy25_15_3_,

                          task0_.createdOn as createdOn15_3_,

                          task0_.documentAccessType as document6_15_3_,

                          task0_.documentContentId as document7_15_3_,

                          task0_.documentType as document8_15_3_,

                          task0_.expirationTime as expirati9_15_3_,

                          task0_.faultAccessType as faultAc10_15_3_,

                          task0_.faultContentId as faultCo11_15_3_,

                          task0_.faultName as faultName15_3_,

                          task0_.faultType as faultType15_3_,

                          task0_.outputAccessType as outputA14_15_3_,

                          task0_.outputContentId as outputC15_15_3_,

                          task0_.outputType as outputType15_3_,

                          task0_.parentId as parentId15_3_,

                          task0_.previousStatus as previou18_15_3_,

                          task0_.processInstanceId as process19_15_3_,

                          task0_.skipable as skipable15_3_,

                          task0_.status as status15_3_,

                          task0_.workItemId as workItemId15_3_,

                          user1_.id as id10_0_,

                          user2_.id as id10_1_,

                          user3_.id as id10_2_

                      from

                          Task task0_

                      left outer join

                          OrganizationalEntity user1_

                              on task0_.taskInitiator_id=user1_.id

                      left outer join

                          OrganizationalEntity user2_

                              on task0_.actualOwner_id=user2_.id

                      left outer join

                          OrganizationalEntity user3_

                              on task0_.createdBy_id=user3_.id

                      where

                          task0_.id=?

                  Hibernate:

                      update

                          Task

                      set

                          allowedToDelegate=?,

                          taskInitiator_id=?,

                          priority=?,

                          activationTime=?,

                          actualOwner_id=?,

                          createdBy_id=?,

                          createdOn=?,

                          documentAccessType=?,

                          documentContentId=?,

                          documentType=?,

                          expirationTime=?,

                          faultAccessType=?,

                          faultContentId=?,

                          faultName=?,

                          faultType=?,

                          outputAccessType=?,

                          outputContentId=?,

                          outputType=?,

                          parentId=?,

                          previousStatus=?,

                          processInstanceId=?,

                          skipable=?,

                          status=?,

                          workItemId=?

                      where

                          id=?

                  Hibernate:

                      select

                          task0_.id as id15_3_,

                          task0_.allowedToDelegate as allowedT2_15_3_,

                          task0_.taskInitiator_id as taskIni23_15_3_,

                          task0_.priority as priority15_3_,

                          task0_.activationTime as activati4_15_3_,

                          task0_.actualOwner_id as actualO24_15_3_,

                          task0_.createdBy_id as createdBy25_15_3_,

                          task0_.createdOn as createdOn15_3_,

                          task0_.documentAccessType as document6_15_3_,

                          task0_.documentContentId as document7_15_3_,

                          task0_.documentType as document8_15_3_,

                          task0_.expirationTime as expirati9_15_3_,

                          task0_.faultAccessType as faultAc10_15_3_,

                          task0_.faultContentId as faultCo11_15_3_,

                          task0_.faultName as faultName15_3_,

                          task0_.faultType as faultType15_3_,

                          task0_.outputAccessType as outputA14_15_3_,

                          task0_.outputContentId as outputC15_15_3_,

                          task0_.outputType as outputType15_3_,

                          task0_.parentId as parentId15_3_,

                          task0_.previousStatus as previou18_15_3_,

                          task0_.processInstanceId as process19_15_3_,

                          task0_.skipable as skipable15_3_,

                          task0_.status as status15_3_,

                          task0_.workItemId as workItemId15_3_,

                          user1_.id as id10_0_,

                          user2_.id as id10_1_,

                          user3_.id as id10_2_

                      from

                          Task task0_

                      left outer join

                          OrganizationalEntity user1_

                              on task0_.taskInitiator_id=user1_.id

                      left outer join

                          OrganizationalEntity user2_

                              on task0_.actualOwner_id=user2_.id

                      left outer join

                          OrganizationalEntity user3_

                              on task0_.createdBy_id=user3_.id

                      where

                          task0_.id=?

                  Hibernate:

                      select

                          subtaskstr0_.Task_Id as Task4_1_,

                          subtaskstr0_.id as id1_,

                          subtaskstr0_.id as id16_0_,

                          subtaskstr0_.name as name16_0_,

                          subtaskstr0_.DTYPE as DTYPE16_0_

                      from

                          SubTasksStrategy subtaskstr0_

                      where

                          subtaskstr0_.Task_Id=?

                  Hibernate:

                      update

                          Task

                      set

                          allowedToDelegate=?,

                          taskInitiator_id=?,

                          priority=?,

                          activationTime=?,

                          actualOwner_id=?,

                          createdBy_id=?,

                          createdOn=?,

                          documentAccessType=?,

                          documentContentId=?,

                          documentType=?,

                          expirationTime=?,

                          faultAccessType=?,

                          faultContentId=?,

                          faultName=?,

                          faultType=?,

                          outputAccessType=?,

                          outputContentId=?,

                          outputType=?,

                          parentId=?,

                          previousStatus=?,

                          processInstanceId=?,

                          skipable=?,

                          status=?,

                          workItemId=?

                      where

                          id=?

                  Hibernate:

                      select

                          task0_.id as id15_3_,

                          task0_.allowedToDelegate as allowedT2_15_3_,

                          task0_.taskInitiator_id as taskIni23_15_3_,

                          task0_.priority as priority15_3_,

                          task0_.activationTime as activati4_15_3_,

                          task0_.actualOwner_id as actualO24_15_3_,

                          task0_.createdBy_id as createdBy25_15_3_,

                          task0_.createdOn as createdOn15_3_,

                          task0_.documentAccessType as document6_15_3_,

                          task0_.documentContentId as document7_15_3_,

                          task0_.documentType as document8_15_3_,

                          task0_.expirationTime as expirati9_15_3_,

                          task0_.faultAccessType as faultAc10_15_3_,

                          task0_.faultContentId as faultCo11_15_3_,

                          task0_.faultName as faultName15_3_,

                          task0_.faultType as faultType15_3_,

                          task0_.outputAccessType as outputA14_15_3_,

                          task0_.outputContentId as outputC15_15_3_,

                          task0_.outputType as outputType15_3_,

                          task0_.parentId as parentId15_3_,

                          task0_.previousStatus as previou18_15_3_,

                          task0_.processInstanceId as process19_15_3_,

                          task0_.skipable as skipable15_3_,

                          task0_.status as status15_3_,

                          task0_.workItemId as workItemId15_3_,

                          user1_.id as id10_0_,

                          user2_.id as id10_1_,

                          user3_.id as id10_2_

                      from

                          Task task0_

                      left outer join

                          OrganizationalEntity user1_

                              on task0_.taskInitiator_id=user1_.id

                      left outer join

                          OrganizationalEntity user2_

                              on task0_.actualOwner_id=user2_.id

                      left outer join

                          OrganizationalEntity user3_

                              on task0_.createdBy_id=user3_.id

                      where

                          task0_.id=?

                  Hibernate:

                      select

                          workitemin0_.workItemId as workItemId3_0_,

                          workitemin0_.creationDate as creation2_3_0_,

                          workitemin0_.name as name3_0_,

                          workitemin0_.processInstanceId as processI4_3_0_,

                          workitemin0_.state as state3_0_,

                          workitemin0_.OPTLOCK as OPTLOCK3_0_,

                          workitemin0_.workItemByteArray as workItem7_3_0_

                      from

                          WorkItemInfo workitemin0_

                      where

                          workitemin0_.workItemId=?

                  Hibernate:

                      select

                          names0_.Task_Names_Id as Task5_1_,

                          names0_.id as id1_,

                          names0_.id as id11_0_,

                          names0_.language as language11_0_,

                          names0_.text as text11_0_

                      from

                          I18NText names0_

                      where

                          names0_.Task_Names_Id=?

                  • 6. Re: Human task API, how to move forward in the workflow ?
                    williajd

                    I've had similar problems where I thought tasks were not being created, but they were. Have you checked in the database to see if the next task has been created?

                     

                    Is the next task assigned to a user or a group?

                    • 7. Re: Human task API, how to move forward in the workflow ?
                      jcharnet

                      Hi James.

                      My next task is not a Human Task, it is a <task> ...</task>, that I have attached a Task Handler to it. If I change this task to a script task, and make my script task write a simple System.out, nothing get's printed to the console.

                      So I still presume that my next task is not getting called.

                       

                       

                      thanks

                      • 8. Re: Human task API, how to move forward in the workflow ?
                        williajd

                        Hi John,

                         

                        Have you tried making it a human task and see if it get to that point? At least then you would know that your code moving the process forward is work so there must be something wrong with the script task or configuration.

                         

                        Just a thought.

                        • 9. Re: Human task API, how to move forward in the workflow ?
                          jcharnet

                          Just tried your idea James, but my next task (modified to be a human task), did not get called.

                          It looks like I'm missing some configuration or something.

                          • 10. Re: Human task API, how to move forward in the workflow ?
                            jcharnet

                            I've made some massive debug, and what I found out was that after the task client api complete method is executed, I get to a point where the method completeWorkItem is executing. This method tries to join an existing transaction, and I'm getting the following error:

                             

                            javax.persistence.TransactionRequiredException: No local transaction to join

                                      at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.doJoinTransaction(ExtendedEntityManagerCreator.java:407)

                                      at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:350)

                                      at $Proxy56.joinTransaction(Unknown Source)

                                      at org.drools.persistence.jpa.JpaPersistenceContextManager.beginCommandScopedEntityManager(JpaPersistenceContextManager.java:66)

                                      at org.drools.persistence.SingleSessionCommandService.execute(SingleSessionCommandService.java:287)

                                      at org.drools.command.impl.CommandBasedStatefulKnowledgeSession$1.completeWorkItem(CommandBasedStatefulKnowledgeSession.java:149)

                                      at org.jbpm.process.workitem.wsht.CommandBasedWSHumanTaskHandler$GetCompletedTaskResponseHandler.execute(CommandBasedWSHumanTaskHandler.java:259)

                             

                             

                            Is there any configuration problems with my environment ?

                            Spring is in control of my EntityManagerFactory and in my test unit I'm using bitronix.tm.TransactionManagerServices.getTransactionManager().

                             

                            Any ideas ?

                             

                            Thanks

                            • 11. Re: Human task API, how to move forward in the workflow ?
                              trh3037

                              I've had similar problems .

                              I am looking forward to someone can solve this problem.

                              • 12. Re: Human task API, how to move forward in the workflow ?
                                calca

                                Hi John,

                                 

                                could you please share your configuration, and if possible your test case?

                                 

                                Thanks,

                                 

                                Demian

                                • 13. Re: Human task API, how to move forward in the workflow ?
                                  jcharnet

                                  Hi Demian,

                                  not sure what type of configuration you want me to share.

                                  If you need any other information, please let me know.

                                   

                                  Spring 3.0.1

                                  Jbpm 5.1.0-Final

                                  JPA 1.2

                                  Hibernate 3.3.2.GA

                                  /**
                                   * Todos os direitos reservados para Softway.
                                   *
                                   * Data de criacao: 27/06/2011 16:12:28
                                   */
                                  package br.com.softcomex.components.workflow.service.impl;
                                  
                                  import java.util.ArrayList;
                                  import java.util.List;
                                  import java.util.Map;
                                  import java.util.Properties;
                                  
                                  import javax.persistence.EntityManagerFactory;
                                  import javax.transaction.TransactionManager;
                                  
                                  import org.drools.KnowledgeBase;
                                  import org.drools.KnowledgeBaseFactory;
                                  import org.drools.SystemEventListener;
                                  import org.drools.SystemEventListenerFactory;
                                  import org.drools.builder.KnowledgeBuilder;
                                  import org.drools.builder.KnowledgeBuilderFactory;
                                  import org.drools.builder.ResourceType;
                                  import org.drools.io.ResourceFactory;
                                  import org.drools.logger.KnowledgeRuntimeLogger;
                                  import org.drools.logger.KnowledgeRuntimeLoggerFactory;
                                  import org.drools.persistence.jpa.JPAKnowledgeService;
                                  import org.drools.runtime.Environment;
                                  import org.drools.runtime.EnvironmentName;
                                  import org.drools.runtime.KnowledgeSessionConfiguration;
                                  import org.drools.runtime.StatefulKnowledgeSession;
                                  import org.drools.runtime.process.ProcessInstance;
                                  import org.drools.spi.ProcessContext;
                                  import org.jbpm.process.audit.JPAProcessInstanceDbLog;
                                  import org.jbpm.process.audit.JPAWorkingMemoryDbLogger;
                                  import org.jbpm.process.workitem.wsht.CommandBasedWSHumanTaskHandler;
                                  import org.jbpm.task.Status;
                                  import org.jbpm.task.query.TaskSummary;
                                  import org.jbpm.task.service.TaskClient;
                                  import org.jbpm.task.service.TaskServer;
                                  import org.jbpm.task.service.TaskService;
                                  import org.jbpm.task.service.mina.MinaTaskClientConnector;
                                  import org.jbpm.task.service.mina.MinaTaskClientHandler;
                                  import org.jbpm.task.service.mina.MinaTaskServer;
                                  import org.jbpm.task.service.responsehandlers.BlockingTaskOperationResponseHandler;
                                  import org.jbpm.task.service.responsehandlers.BlockingTaskSummaryResponseHandler;
                                  
                                  import br.com.softcomex.components.log.SfwLogger;
                                  import br.com.softcomex.components.log.SfwLoggerFactory;
                                  import br.com.softcomex.components.workflow.service.SfwJbpmWorkFlow;
                                  
                                  
                                  /**
                                   * 

                                  * Implementação da classe responsável por criar o ambiente do JBPM. *

                                  * @author João Augusto Charnet * */ public class SfwJbpmWorkFlowImpl implements SfwJbpmWorkFlow {     /**      * Log.      */     private SfwLogger sfwLogger = SfwLoggerFactory.getLogger(getClass());         /**      * Entity Manager Factory injetado.      */     private EntityManagerFactory emf;         /**      * Transação.      */     private TransactionManager transactionManager;         /**      * Sessão da base de conhecimento do JBPM.      */     private StatefulKnowledgeSession kSession;         /**      * Thread do servidor de tarefa humana.      */     private TaskServer humanTaskServerThread;         /**      * Porta do sevidor de tarefa humana.      */     private int humanTaskServerPort = -1;         /**      * Endereço do Servidor de tarefa humana.      */     private String humanTaskServerLocalAddress = "127.0.0.1";         /**      * Lista com os jbpm que precisa ser carregado.      */     private List workFlowResourcesList;         /**      * Responsável por se comunicar com o servidor de tarefas humanas.      */     private TaskClient taskClient;         /**      * Contexto do processo.      */         /**      * Construtor padrão.      */     public SfwJbpmWorkFlowImpl() {     }     @Override     public void prepareSession() {         KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();                 for (String resource : this.workFlowResourcesList) {             kbuilder.add(ResourceFactory.newClassPathResource(resource), ResourceType.BPMN2);         }                 KnowledgeBase kbase = kbuilder.newKnowledgeBase();                 Environment env = KnowledgeBaseFactory.newEnvironment();         env.set(EnvironmentName.ENTITY_MANAGER_FACTORY, this.emf);         env.set(EnvironmentName.TRANSACTION_MANAGER,             this.transactionManager);                 // Human Task         SystemEventListener systemEventListener = SystemEventListenerFactory.getSystemEventListener();                 TaskService taskService = new TaskService(this.emf, systemEventListener);                this.startHumanTaskServer(taskService);                 Properties properties = new Properties();         properties.put("drools.processInstanceManagerFactory", "org.jbpm.persistence.processinstance.JPAProcessInstanceManagerFactory");         properties.put("drools.processSignalManagerFactory", "org.jbpm.persistence.processinstance.JPASignalManagerFactory");         KnowledgeSessionConfiguration config = KnowledgeBaseFactory.newKnowledgeSessionConfiguration(properties);                 StatefulKnowledgeSession ksession =             JPAKnowledgeService.newStatefulKnowledgeSession(kbase, config, env);               //this will log in audit tables         JPAWorkingMemoryDbLogger jpaWorkingMemoryLog = new JPAWorkingMemoryDbLogger(ksession);         JPAProcessInstanceDbLog processLog = new JPAProcessInstanceDbLog(ksession.getEnvironment());         KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newConsoleLogger(ksession);                         CommandBasedWSHumanTaskHandler humanTask = new CommandBasedWSHumanTaskHandler(ksession);         humanTask.setConnection(this.humanTaskServerLocalAddress, this.humanTaskServerPort);         ksession.getWorkItemManager().registerWorkItemHandler("Human Task", humanTask);               this.setkSession(ksession);     }     /**      * Inicia o servidor para a tarefa humana.      *      * @param taskService Serviço da tarefa.      */     private void startHumanTaskServer(TaskService taskService) {         if (this.humanTaskServerPort <= 0) {             this.humanTaskServerPort = SfwJbpmWorkFlow.DEFAULT_HUMAN_TASK_SERVER_PORT;         }         this.sfwLogger.debug("Iniciando Human Task Server! ip [ " + this.humanTaskServerLocalAddress + "] port [" + this.humanTaskServerPort +"]");         this.humanTaskServerThread = new MinaTaskServer(taskService, this.humanTaskServerPort);         Thread thread = new Thread(this.humanTaskServerThread);         thread.start();     }     @Override     public void stopHumanTaskServer() throws Exception {        if (this.humanTaskServerThread != null &&            this.humanTaskServerThread.isRunning()) {                       this.taskClient.disconnect();            this.humanTaskServerThread.stop();                       this.sfwLogger.debug("Encerrando Human Task Server!");        }     }     @Override     public void setHumanTaskServerPort(int humanTaskServerPort) {         this.humanTaskServerPort = humanTaskServerPort;     }     @Override     public int getHumanTaskServerPort() {         return humanTaskServerPort;     }         @Override     public EntityManagerFactory getEmf() {             return emf;     }         @Override     public void setEmf(EntityManagerFactory emf) {             this.emf = emf;     }     @Override     public void setkSession(StatefulKnowledgeSession kSession) {         this.kSession = kSession;     }     @Override     public StatefulKnowledgeSession getkSession() {         return kSession;     }     @Override     public void setTransactionManager(TransactionManager transactionManager) {         this.transactionManager = transactionManager;     }     @Override     public TransactionManager getTransactionManager() {         return transactionManager;     }     @Override     public ProcessInstance startProcess(String processId, Map params) {         return this.kSession.startProcess(processId, params);             }     @Override     public void setWorkFlowResourcesList(List workFlowResourcesList) {         this.workFlowResourcesList = workFlowResourcesList;     }     @Override     public List getWorkFlowResourcesList() {         return workFlowResourcesList;     }     @Override     public void addWorkFlowResource(String workFlowResource) {         if (this.workFlowResourcesList == null) {             this.workFlowResourcesList = new ArrayList();         }                 this.workFlowResourcesList.add(workFlowResource);             }     @Override     public String getHumanTaskServerLocalAddress() {             return humanTaskServerLocalAddress;     }         @Override     public void setHumanTaskServerLocalAddress(String humanTaskServerLocalAddress) {             this.humanTaskServerLocalAddress = humanTaskServerLocalAddress;     }     @Override     public ProcessContext getProcessContext() {         ProcessContext procContext = new ProcessContext(this.kSession);         return procContext;     }         /**      * Cria um TaskClient conectando no servido de tarefa humana.      * @return TaskClient TaskClient.      */     private TaskClient createTaskClient() {                 if (this.taskClient == null) {             this.taskClient = new TaskClient(new MinaTaskClientConnector("SfwTaskClient",                                                     new MinaTaskClientHandler(SystemEventListenerFactory.getSystemEventListener())));                         boolean connected = this.taskClient.connect(this.humanTaskServerLocalAddress, this.humanTaskServerPort);             if (!connected) {                 this.sfwLogger.error("Não foi possível conectar no servidor de tarefa humana. Server [" + this.humanTaskServerLocalAddress + "] - Port [" + this.humanTaskServerPort + "]");             }         }         return this.taskClient;     }         @Override     public TaskClient getTaskClient() {             return taskClient;     }         @Override     public void setTaskClient(TaskClient taskClient) {             this.taskClient = taskClient;     }     @Override     public List getTasksByUser(String user) {         this.createTaskClient();                 BlockingTaskSummaryResponseHandler taskSummaryResponseHandler =             new BlockingTaskSummaryResponseHandler();         this.taskClient.getTasksAssignedAsPotentialOwner(user, "en-UK", taskSummaryResponseHandler);         final int oneSec = 1000;         taskSummaryResponseHandler.waitTillDone(oneSec);                 List tasks = taskSummaryResponseHandler.getResults();                 return tasks;     }         /**      * Cria uma TaskClient, caso necessário e retorna um taskResponseHandler      * para se comunicar com o servidor de tarefa humana.      *      * @return BlockingTaskOperationResponseHandler      */     private BlockingTaskOperationResponseHandler createTaskClientAndReturnTaskOperationResponseHandler() {         this.createTaskClient();                 BlockingTaskOperationResponseHandler taskResponseHandler =             new BlockingTaskOperationResponseHandler();         return taskResponseHandler;     }     @Override     public void completeTask(List tasks, String user) {         for (TaskSummary task : tasks) {             this.sfwLogger.debug("Completando tarefa [" + task.getName() + "] do usuário [" + user + "]");             this.completeTask(task, user);         }             }     @Override     public void completeTask(TaskSummary task, String user) {                 BlockingTaskOperationResponseHandler taskResponseHandler =             this.createTaskClientAndReturnTaskOperationResponseHandler();         this.taskClient.complete(task.getId(), user, null, taskResponseHandler);         final int oneSec = 1000;         taskResponseHandler.waitTillDone(oneSec);     }     @Override     public void failTask(TaskSummary task, String user) {         BlockingTaskOperationResponseHandler taskResponseHandler =             this.createTaskClientAndReturnTaskOperationResponseHandler();                 this.taskClient.fail(task.getId(), user, null, taskResponseHandler);         final int oneSec = 1000;         taskResponseHandler.waitTillDone(oneSec);     }     @Override     public void suspendTask(TaskSummary task, String user) {         BlockingTaskOperationResponseHandler taskResponseHandler =             this.createTaskClientAndReturnTaskOperationResponseHandler();                 this.taskClient.suspend(task.getId(), user, taskResponseHandler);     }     @Override     public void startTask(TaskSummary task,         String user) {         BlockingTaskOperationResponseHandler taskResponseHandler =             this.createTaskClientAndReturnTaskOperationResponseHandler();         if (!task.getStatus().equals(Status.InProgress)) {                     this.taskClient.start(task.getId(), user, taskResponseHandler);             final int oneSec = 1000;             taskResponseHandler.waitTillDone(oneSec);         }                     }     @Override     public void stopTask(TaskSummary task,         String user) {         BlockingTaskOperationResponseHandler taskResponseHandler =             this.createTaskClientAndReturnTaskOperationResponseHandler();         this.taskClient.stop(task.getId(), user, taskResponseHandler);         final int oneSec = 1000;         taskResponseHandler.waitTillDone(oneSec);     }     @Override     public void releaseTask(TaskSummary task,         String user) {         BlockingTaskOperationResponseHandler taskResponseHandler =             this.createTaskClientAndReturnTaskOperationResponseHandler();         this.taskClient.release(task.getId(), user, taskResponseHandler);         final int oneSec = 1000;         taskResponseHandler.waitTillDone(oneSec);     }     @Override     public void resumeTask(TaskSummary task,         String user) {         BlockingTaskOperationResponseHandler taskResponseHandler =             this.createTaskClientAndReturnTaskOperationResponseHandler();         this.taskClient.resume(task.getId(), user, taskResponseHandler);         final int oneSec = 1000;         taskResponseHandler.waitTillDone(oneSec);     }     @Override     public void skipTask(TaskSummary task,         String user) {         BlockingTaskOperationResponseHandler taskResponseHandler =             this.createTaskClientAndReturnTaskOperationResponseHandler();         this.taskClient.skip(task.getId(), user, taskResponseHandler);         final int oneSec = 1000;         taskResponseHandler.waitTillDone(oneSec);             }     @Override     public void claimTask(TaskSummary task,         String user) {         BlockingTaskOperationResponseHandler taskResponseHandler =             this.createTaskClientAndReturnTaskOperationResponseHandler();                 this.taskClient.claim(task.getId(), user, taskResponseHandler);         final int oneSec = 1000;         taskResponseHandler.waitTillDone(oneSec);             } }

                                   


                                  Unit Test case

                                  /**
                                   * Todos os direitos reservados para Softway.
                                   *
                                   * Data de criacao: 28/06/2011 15:18:56
                                   */
                                  package br.com.softcomex.components.workflow.service.impl;
                                  
                                  import java.net.ConnectException;
                                  import java.net.Socket;
                                  import java.util.HashMap;
                                  import java.util.List;
                                  import java.util.Map;
                                  import java.util.ResourceBundle;
                                  
                                  import javax.inject.Inject;
                                  import javax.persistence.EntityManager;
                                  import javax.persistence.EntityManagerFactory;
                                  import javax.persistence.Query;
                                  
                                  import junit.framework.Assert;
                                  
                                  import org.drools.runtime.process.ProcessInstance;
                                  import org.drools.runtime.process.WorkItem;
                                  import org.drools.runtime.process.WorkItemHandler;
                                  import org.drools.runtime.process.WorkItemManager;
                                  import org.drools.spi.ProcessContext;
                                  import org.jbpm.task.query.TaskSummary;
                                  import org.junit.BeforeClass;
                                  import org.junit.Test;
                                  
                                  import bitronix.tm.TransactionManagerServices;
                                  import bitronix.tm.resource.jdbc.PoolingDataSource;
                                  import br.com.softcomex.components.workflow.service.SfwJbpmWorkFlow;
                                  import br.com.softcomex.test.serviceeao.SfwBaseServiceTestCase;
                                  
                                  
                                  /**
                                   * Classe de teste do serviço SfwJbmWorkFlowImpl.
                                   * 
                                   * @author João Augusto Charnet *
                                   */
                                  public class SfwJbpmWorkFlowImplTest extends SfwBaseServiceTestCase {
                                  
                                      /**
                                       * Serviço.
                                       */
                                      @Inject
                                      private SfwJbpmWorkFlow sfwWorkFlow;
                                  
                                      
                                      /**
                                       * Prepara o datasource.
                                       */
                                      @BeforeClass
                                      public static void prepareDatasource() {
                                          PoolingDataSource ds = new PoolingDataSource();
                                          ds.setUniqueName("localDataSource");
                                          ds.setClassName("oracle.jdbc.xa.client.OracleXADataSource");
                                          ds.setMaxPoolSize(3);
                                          ds.setAllowLocalTransactions(true);
                                          
                                          ResourceBundle rb = ResourceBundle.getBundle("jdbc");
                                          
                                          ds.getDriverProperties().put("user", rb.getString("jdbc.username"));
                                          ds.getDriverProperties().put("password", rb.getString("jdbc.password"));
                                          ds.getDriverProperties().put("URL", rb.getString("jdbc.url"));
                                          ds.init();
                                      }
                                      
                                      /**
                                       * Teste.
                                       * @throws Exception Exceção.
                                       */
                                      @Test
                                      public void testJbpmWorkFlow() throws Exception {
                                          
                                          this.sfwWorkFlow.setTransactionManager(TransactionManagerServices.getTransactionManager());
                                          this.sfwWorkFlow.getTransactionManager().begin();
                                          this.sfwWorkFlow.addWorkFlowResource("test.bpmn");
                                          this.sfwWorkFlow.addWorkFlowResource("testHumanTask.bpmn");
                                          this.sfwWorkFlow.prepareSession();
                                          
                                          MyAutomaticHumanSimulatorWorkItemHandler workHandler = new MyAutomaticHumanSimulatorWorkItemHandler();
                                          TestWorkItemHandler workItemHandler = new TestWorkItemHandler();
                                  
                                          
                                          Socket socket = new Socket("127.0.0.1", this.sfwWorkFlow.getHumanTaskServerPort());
                                          Assert.assertNotNull(socket);
                                          Map params = new HashMap();
                                          params.put("responsible", "John");
                                          ProcessInstance processInstance = this.sfwWorkFlow.startProcess("testHumanTask", params);
                                          
                                          Thread.currentThread().sleep(3000);
                                          
                                          List tasks = this.sfwWorkFlow.getTasksByUser("John");
                                          
                                          this.sfwWorkFlow.startTask(tasks.get(0), "John");
                                          
                                          this.sfwWorkFlow.completeTask(tasks.get(0), "John");
                                          
                                          Thread.currentThread().sleep(5000);
                                          
                                          Assert.assertEquals(ProcessInstance.STATE_COMPLETED, processInstance.getState());
                                          
                                          this.sfwWorkFlow.stopHumanTaskServer();
                                          
                                          try {
                                              socket = new Socket("127.0.0.1", this.sfwWorkFlow.getHumanTaskServerPort());
                                              Assert.fail("Esperando exceção, por não ter ninguém escutando na porta do sevidor " + this.sfwWorkFlow.getHumanTaskServerPort());
                                          } catch (ConnectException excep) {
                                              Assert.assertTrue(true);
                                          } finally {
                                              this.sfwWorkFlow.getTransactionManager().rollback();
                                          }
                                      }
                                      
                                      
                                  }
                                  
                                  

                                   

                                  testHumanTask.JPG

                                  jbpm xml

                                           <?xml version="1.0" encoding="UTF-8"?>  
                                  <definitions id="Definition"
                                               targetNamespace="http://www.jboss.org/drools"
                                               typeLanguage="http://www.java.com/javaTypes"
                                               expressionLanguage="http://www.mvel.org/2.0"
                                               xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
                                               xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
                                               xs:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd"
                                               xmlns:g="http://www.jboss.org/drools/flow/gpd"
                                               xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
                                               xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
                                               xmlns:di="http://www.omg.org/spec/DD/20100524/DI"
                                               xmlns:tns="http://www.jboss.org/drools"> 
                                  
                                    <itemDefinition id="_responsibleItem" structureRef="String" /> 
                                  
                                    <process processType="Private" isExecutable="true" id="testHumanTask" name="testHumanTask" > 
                                  
                                      <!-- process variables --> 
                                      <property id="responsible" itemSubjectRef="_responsibleItem"/> 
                                  
                                      <!-- nodes --> 
                                      <startEvent id="_1" name="Start" /> 
                                      <userTask id="_2" name="User Task" > 
                                        <ioSpecification> 
                                          <dataInput id="_2_TaskNameInput" name="TaskName" /> 
                                          <inputSet> 
                                            <dataInputRefs> _2_TaskNameInput</dataInputRefs> 
                                          </inputSet> 
                                          <outputSet> 
                                          </outputSet> 
                                        </ioSpecification> 
                                        <dataInputAssociation> 
                                          <targetRef> _2_TaskNameInput</targetRef> 
                                          <assignment> 
                                            <from xs:type="tFormalExpression"> Test Human Task</from> 
                                            <to xs:type="tFormalExpression"> _2_TaskNameInput</to> 
                                          </assignment> 
                                        </dataInputAssociation> 
                                        <potentialOwner> 
                                          <resourceAssignmentExpression> 
                                            <formalExpression> #{responsible}</formalExpression> 
                                          </resourceAssignmentExpression> 
                                        </potentialOwner> 
                                      </userTask> 
                                      <scriptTask id="_3" name="Script" scriptFormat="http://www.java.com/java" > 
                                        <script> System.out.println("Script task :" + new java.util.Date());</script> 
                                      </scriptTask> 
                                      <endEvent id="_4" name="End" > 
                                          <terminateEventDefinition/> 
                                      </endEvent> 
                                  
                                      <!-- connections --> 
                                      <sequenceFlow id="_1-_2" sourceRef="_1" targetRef="_2" /> 
                                      <sequenceFlow id="_2-_3" sourceRef="_2" targetRef="_3" /> 
                                      <sequenceFlow id="_3-_4" sourceRef="_3" targetRef="_4" /> 
                                  
                                    </process> 
                                  
                                    <bpmndi:BPMNDiagram> 
                                      <bpmndi:BPMNPlane bpmnElement="testHumanTask" > 
                                        <bpmndi:BPMNShape bpmnElement="_1" > 
                                          <dc:Bounds x="51" y="34" width="48" height="48" /> 
                                        </bpmndi:BPMNShape> 
                                        <bpmndi:BPMNShape bpmnElement="_2" > 
                                          <dc:Bounds x="165" y="35" width="100" height="48" /> 
                                        </bpmndi:BPMNShape> 
                                        <bpmndi:BPMNShape bpmnElement="_3" > 
                                          <dc:Bounds x="176" y="158" width="80" height="48" /> 
                                        </bpmndi:BPMNShape> 
                                        <bpmndi:BPMNShape bpmnElement="_4" > 
                                          <dc:Bounds x="191" y="301" width="48" height="48" /> 
                                        </bpmndi:BPMNShape> 
                                        <bpmndi:BPMNEdge bpmnElement="_1-_2" > 
                                          <di:waypoint x="75" y="58" /> 
                                          <di:waypoint x="215" y="59" /> 
                                        </bpmndi:BPMNEdge> 
                                        <bpmndi:BPMNEdge bpmnElement="_2-_3" > 
                                          <di:waypoint x="215" y="59" /> 
                                          <di:waypoint x="216" y="182" /> 
                                        </bpmndi:BPMNEdge> 
                                        <bpmndi:BPMNEdge bpmnElement="_3-_4" > 
                                          <di:waypoint x="216" y="182" /> 
                                          <di:waypoint x="215" y="325" /> 
                                        </bpmndi:BPMNEdge> 
                                      </bpmndi:BPMNPlane> 
                                    </bpmndi:BPMNDiagram> 
                                  
                                  </definitions>                                                                                                                                  
                                  
                                  • 14. Re: Human task API, how to move forward in the workflow ?
                                    jcharnet

                                    I got it to work. Not the ideal way though.

                                     

                                    I had to create my EntityManagerFactory in my JUnit test with Persistence.createEntityManagerFactory.

                                    I cannot use my spring configuration to create the entity manager, and to handle the transaction.

                                     

                                    Now this brings me to a new question. When I run my web application, will I get this same error ?

                                     

                                     

                                    Thanks for all the help !

                                     

                                     

                                    John

                                    1 2 Previous Next