14 Replies Latest reply on Feb 8, 2013 10:55 PM by Anand Kumar Jha

    Integrating jBPM 5 into web application - architecture

    Pedro Gonçalves Newbie

      Hello,

       

      I've been trying to integrate the jBPM5 into my own web app, but I've some doubts about how to make it.

       

      My processes are mostly composed by Human Actions, which make them long running processes.

      My problem is similar to the one discribed here: https://community.jboss.org/message/636561#636561

       

      I've already configured jBPM to use persistense and I was able to start processes (building kbase, ksession, taskService, etc.). But everytime I start a process, or try to list the started processes I create a new entry on SessionInfo (in the database), and I got a empty list of started processes (I've 2 process instances holding a human action).

      • It is clear to me that I'm not managing the sessions properly, my question is, what is the best way to do it?
      • Does jBPM5.3 brings any improvement on this?
      • What are the best practices regarding the use of the kbase, ksessions, taskServices, etc.

       

      Thanks in advance!

        • 1. Re: Integrating jBPM 5 into web application - architecture
          Jakub Ferschmann Newbie

          Hi,

          any progress about this stuff? Do you invented something? I'm worried about the same thing.

          Best Regards

          • 2. Re: Integrating jBPM 5 into web application - architecture
            Pedro Gonçalves Newbie

            I'm back to jbpm5 just a couple of days ago; I had spent some time searching for alternatives (activiti is infinitely more simple, but i find it not to be very mature).

             

            The solution i had found for managing the kSession is to create a structure in my db that correlates each process instance to a kSession. I'm using one kSession per process instance.

            • 3. Re: Integrating jBPM 5 into web application - architecture
              Jakub Ferschmann Newbie

              How does it work? I mean, how to store kSessionId for every process instance? In web application every user has only httpSession, and I don't want to store something to it.

              • 4. Re: Integrating jBPM 5 into web application - architecture
                Mauricio Salatino Master

                I'm at the moment writing some examples about this topic.

                Depending what the process is doing you can store the process instance ID and or the session in a related entity.

                As you mention you have the User Session, but if the process do things for more than one user, the User entity is not the appropriate one to store the reference.

                one kSession per process instance is one option, I will be sharing examples about different approaches.

                Cheers

                • 5. Re: Integrating jBPM 5 into web application - architecture
                  Pedro Gonçalves Newbie

                  What I do is this:

                   

                  public void startProcess(CoreData coreData, String definitionId) {
                  
                       //build variables.......
                  
                       ProcessInstance processInstance = kSession.startProcess(definitionId, variables);
                  
                       ProcessInfoData processInfoData = new ProcessInfoData(); 
                  
                       processInfoData.setkSessionId(kSession.getId());
                       processInfoData.setProcessInstanceId(processInstance.getId());
                  
                       serviceProcessInfo.create(processInfoData);
                  }
                  

                   

                  So, in my db, I have a table that maps KnowledgeSession <---> ProcessInstance

                  • 6. Re: Integrating jBPM 5 into web application - architecture
                    Mauricio Salatino Master

                    Yes, that's a very valid option.

                    It depends on what your business processes are doing.

                    You can also store more information, like for example the workItemId that is pending to be completed, as well as business information that identifies in an unique way

                    the ksession, processInstance, workItem + any business data relevant for finding out the runtime where that process was running.

                     

                    For some situations running multiple process instances in the same ksession could be required or useful.

                     

                    Cheers

                    • 7. Re: Integrating jBPM 5 into web application - architecture
                      Jakub Ferschmann Newbie

                      Ok,

                      can I use one kSession for all process instance in web application? If kSession will load every request (different thread) from the database, is it thread safe?

                      In jBPM3 I can use one context with default name for every interaction with workflow engine. Context is not stored in the database and it is unlike jBPM5

                       

                      JbpmConfiguration config;

                      ....

                      try {

                          context = config.createJbpmContext(JbpmContext.DEFAULT_JBPM_CONTEXT_NAME);

                       

                         .... // do something with context

                      } finally {

                          if (context != null) {

                              context.close();

                          }

                      }

                      • 8. Re: Integrating jBPM 5 into web application - architecture
                        Pedro Gonçalves Newbie

                        Yes. I saw in other posts that you can use one ksession for every process instance; and it's also in the documentation:

                         

                         

                        Sessions can be created based on a knowledge base and are used to execute processes and interact with the engine. You can create as many independent session as you need and creating a session is considered relatively lightweight. How many sessions you create is up to you. In general, most simple cases start out with creating one session that is then called from various places in your application. You could decide to create multiple sessions if for example you want to have multiple independent processing units (for example, if you want all processes from one customer to be completely independent from processes for another customer, you could create an independent session for each customer) or if you need multiple sessions for scalability reasons. If you don't know what to do, simply start by having one knowledge base that contains all your process definitions and create one session that you then use to execute all your processes.

                         

                        I'm still a bit lost in jbpm architecture, and trying to understand all the concepts. But I thought (or guess ) that in the future I will need one ksession per process instance...

                        • 9. Re: Integrating jBPM 5 into web application - architecture
                          Lisa DeSouza Newbie

                          hi, are any of your examples currently available online? I am new to jBPM and would like to create a prototype of a webapplication(struts framework) integrated with jBPM. I have not yet been able to find any useful example applications. I successfully installed the jBPM demo, but the integration is my issue.

                          • 10. Re: Integrating jBPM 5 into web application - architecture
                            joploya Newbie

                            Hi,

                             

                            I am implementing a jEE web-app that integrate jbpm5 human task (local service).

                             

                            I had used examples of Mauricio Salatino and create a KnowledgeSessionProducer to instanciate the KnowledgeSession, load the database and processes. And a Bean that contains all methods to manage tasks.

                             

                            My users log in, then they choose a form. When they validate the form a process instance is created and a task save in database. Because my processes contains human task nodes, at each step tasks wait being claim. So, next user log in, go to an interface where his tasks are display, then click on take task. This call a method that use the taskManagerBean to claim and start the task and redirect him to the form page. and so one until last validation.

                             

                            The interface to manage tasks is very well explain in the book about jbpm5. I you need I can give my code but I don't know if we have the same architecture and needs.

                             

                            Regards,

                            • 11. Re: Integrating jBPM 5 into web application - architecture
                              Lisa DeSouza Newbie

                              yes, it would be very helpful if you shared your code. I tend to work better if I have working examples in front of me, rather than explanations on how to do the task at hand. how large is your application? would it be able to be sent via. email? or maybe shared via. a cloud storage application like dropbox?

                              • 12. Re: Integrating jBPM 5 into web application - architecture
                                Anand Kumar Jha Newbie

                                hi sandra renaud,

                                I am facing same difficulty as being faced by lisa..

                                If possible, kindly share the code. after that i will be able to understand the architecture and relevent facts..thanks in advance..:)

                                • 13. Re: Integrating jBPM 5 into web application - architecture
                                  joploya Newbie

                                  Hello Lisa and Anand,

                                   

                                  I can't give you my application but this is the relevant code concerning the task management :

                                   

                                  I use maven so I have these dependencies in the POM :

                                  <!-- jbpm -->

                                       <dependency>

                                                 <groupId>org.drools</groupId>

                                                           <artifactId>drools-compiler</artifactId>

                                                           <version>5.4.0.Final</version>

                                                      </dependency>

                                                       <dependency>

                                                                <groupId>org.jbpm</groupId>

                                                                <artifactId>jbpm-bpmn2</artifactId>

                                                                <version>5.4.0.Final</version>

                                                                <exclusions>

                                                      <exclusion>

                                                            <groupId>dom4j</groupId>

                                                            <artifactId>dom4j</artifactId>

                                                      </exclusion>

                                                </exclusions>

                                                      </dependency>

                                                      <dependency>

                                                                <groupId>org.jbpm</groupId>

                                                                <artifactId>jbpm-flow</artifactId>

                                                                <version>5.4.0.Final</version>

                                                                <exclusions>

                                                      <exclusion>

                                                            <groupId>dom4j</groupId>

                                                            <artifactId>dom4j</artifactId>

                                                      </exclusion>

                                                </exclusions>

                                                      </dependency>

                                                      <dependency>

                                                                <groupId>org.jbpm</groupId>

                                                                <artifactId>jbpm-human-task-core</artifactId>

                                                                <version>5.4.0.Final</version>

                                                                <exclusions>

                                                      <exclusion>

                                                            <groupId>dom4j</groupId>

                                                            <artifactId>dom4j</artifactId>

                                                      </exclusion>

                                                </exclusions>

                                                      </dependency>

                                  Then, the two java classes :

                                   

                                  import java.io.InputStream;
                                  import java.io.InputStreamReader;
                                  import java.io.Reader;
                                  import java.io.Serializable;
                                  import java.util.ArrayList;
                                  import java.util.HashMap;
                                  import java.util.List;
                                  import java.util.Map;
                                  import java.util.Properties;
                                  
                                  
                                  import javax.annotation.PostConstruct;
                                  import javax.ejb.LocalBean;
                                  import javax.ejb.Stateless;
                                  import javax.enterprise.context.ApplicationScoped;
                                  import javax.enterprise.inject.Produces;
                                  import javax.persistence.EntityManagerFactory;
                                  import javax.persistence.PersistenceUnit;
                                  
                                  
                                  import org.drools.KnowledgeBase;
                                  import org.drools.SystemEventListenerFactory;
                                  import org.drools.builder.KnowledgeBuilder;
                                  import org.drools.builder.KnowledgeBuilderFactory;
                                  import org.drools.builder.ResourceType;
                                  import org.drools.io.Resource;
                                  import org.drools.io.ResourceFactory;
                                  import org.drools.logger.KnowledgeRuntimeLogger;
                                  import org.drools.logger.KnowledgeRuntimeLoggerFactory;
                                  import org.drools.runtime.EnvironmentName;
                                  import org.drools.runtime.StatefulKnowledgeSession;
                                  import org.jbpm.process.workitem.email.EmailWorkItemHandler;
                                  import org.jbpm.task.Group;
                                  import org.jbpm.task.User;
                                  import org.jbpm.task.identity.UserGroupCallbackManager;
                                  import org.jbpm.task.service.TaskService;
                                  import org.jbpm.task.service.TaskServiceSession;
                                  import org.slf4j.Logger;
                                  import org.slf4j.LoggerFactory;
                                  
                                  
                                  //import static org.junit.Assert.*;
                                  @Stateless
                                  @LocalBean
                                  public class KnowledgeSessionProducer implements Serializable{
                                  
                                  
                                            private static final long serialVersionUID = -4494168896880405667L;
                                            private Logger log = LoggerFactory.getLogger(KnowledgeSessionProducer.class);
                                            private KnowledgeRuntimeLogger logger;
                                  
                                      @PersistenceUnit(unitName = "org.jbpm.task")
                                      private EntityManagerFactory emf;
                                  
                                      public @PostConstruct void init(){
                                                log.debug("init of KnowledgeSessionProducer ...");
                                                TaskService taskService = new TaskService(emf, SystemEventListenerFactory.getSystemEventListener());
                                          TaskServiceSession taskSession = taskService.createSession();
                                          // Add users
                                          @SuppressWarnings("rawtypes")
                                                      Map vars = new HashMap();
                                          InputStream usersin = KnowledgeSessionProducer.class.getResourceAsStream( "/LoadUsers.mvel" );
                                          if(usersin != null) {
                                                    Reader reader = new InputStreamReader( usersin );   
                                                    @SuppressWarnings("unchecked")
                                                    Map<String, User> users = ( Map<String, User> ) TaskService.eval( reader, vars );   
                                                    log.debug("Users to load in db : ...");
                                                    for ( User user : users.values() ) {
                                                              taskSession.addUser( user );
                                                              log.debug(" - "+user);
                                                    }           
                                          }
                                          InputStream groupsin = KnowledgeSessionProducer.class.getResourceAsStream( "/LoadGroups.mvel" );
                                          if(groupsin != null) {
                                                    Reader reader = new InputStreamReader( groupsin );   
                                                    @SuppressWarnings("unchecked")
                                                    Map<String, Group> groups = ( Map<String, Group> ) TaskService.eval( reader, vars );     
                                                    log.debug("Groups to load in db : ...");
                                                    for ( Group group : groups.values() ) {
                                                              taskSession.addGroup( group );
                                                              log.debug(" - "+group);
                                                    }
                                          }
                                          // try to get the usergroup callback properties
                                          InputStream usergroupsin = KnowledgeSessionProducer.class.getResourceAsStream(  "/jbpm.usergroup.callback.properties" );
                                          if(usergroupsin != null) {
                                                    Properties callbackproperties = new Properties();
                                                    try {
                                                        // Properties.load(Reader) is a JDK 6 method
                                                              callbackproperties.load(usergroupsin);
                                                              UserGroupCallbackManager.getInstance().setCallbackFromProperties(callbackproperties);
                                                              System.out.println("Task service registered usergroup callback ...");
                                                    } catch (Exception e) {
                                                              System.out.println("Task service unable to register usergroup callback ...");
                                                    }
                                          }
                                          taskSession.dispose();
                                          System.out.println("Task service started correctly!");
                                          System.out.println("Task service running ...");
                                      }
                                  
                                            @Produces
                                            @ApplicationScoped
                                            public StatefulKnowledgeSession produceKnowledgeSession(){
                                                      log.debug("produce the KnowledgeSession ...");
                                                      //Create the knowledgeBase
                                                      /*This factory is used to build the knowledge base resources that are held collectively in KnowledgePackages.*/
                                                      KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
                                  
                                                      //Add all processes to the knowledgeBuilder
                                                      List<Resource> resources = getProcessDefinitionList();
                                                      for (Resource resource : resources) {
                                                                kbuilder.add(resource, ResourceType.BPMN2);
                                                      }
                                  
                                                      /*Create a new KnowledgeBase from the knowledge packages that have been added to this builder. 
                                                       * An exception is thrown if there are any errors.*/
                                  //                    assertFalse( kbuilder.hasErrors() );
                                                      if ( kbuilder.hasErrors() ) {
                                                           log.error( kbuilder.getErrors().toString() );
                                                       }
                                                      KnowledgeBase kbase = kbuilder.newKnowledgeBase();
                                  
                                                      /*Create a new StatefulKnowledgeSession using the default session configuration. 
                                                       * Don't forget to dispose() session when you are done.
                                                       * 
                                                       * StatefulKnowledgeSession is the most common way to interact with the engine. 
                                                       * A StatefulKnowledgeSession allows the application to establish an iterative conversation with the engine, 
                                                       * where the state of the session is kept across invocations.*/
                                                      StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
                                  
                                          logger = KnowledgeRuntimeLoggerFactory.newThreadedFileLogger(ksession, "loggerFile", 1000);
                                  
                                          /*A work item manager is responsible for finding the right work item handler when a work item should be executed 
                                           * and should be notified when this work item has been completed (or aborted).
                                           * 
                                           * Register the given handler for all work items of the given type of work 
                                           * This part is done in the LocalHumanTaskService*/
                                  
                                  //        ksession.getWorkItemManager().registerWorkItemHandler("Human Task", handler );
                                  
                                          ksession.getEnvironment().set(EnvironmentName.ENTITY_MANAGER_FACTORY, emf);
                                  
                                          /*
                                           * Register WorkItem Handler for Email
                                           */
                                          //EmailWorkItemHandler emailHandler =  new EmailWorkItemHandler();
                                          //ksession.getWorkItemManager().registerWorkItemHandler("Email", emailHandler);
                                  
                                          return ksession;
                                            }
                                  
                                            public KnowledgeRuntimeLogger getLogger(){
                                                      return this.logger;
                                            }
                                  
                                            private List<Resource> getProcessDefinitionList(){
                                                      List<Resource> resourceList = new ArrayList<>();
                                                      resourceList.add(ResourceFactory.newClassPathResource("workflows/MyFlow.bpmn2"));
                                                      /**
                                                       * TODO 
                                                       * add all other process here
                                                       */
                                                      return resourceList;
                                            }
                                  }
                                  

                                   

                                  import javax.annotation.PostConstruct;
                                  import javax.enterprise.context.SessionScoped;
                                  import javax.enterprise.event.Event;
                                  import javax.faces.application.FacesMessage;
                                  import javax.faces.context.FacesContext;
                                  import javax.inject.Inject;
                                  
                                  
                                  import org.drools.runtime.StatefulKnowledgeSession;
                                  import org.jboss.seam.security.Identity;
                                  import org.drools.runtime.process.ProcessInstance;
                                  import org.jbpm.task.Status;
                                  import org.jbpm.task.query.TaskSummary;
                                  import org.jbpm.task.service.local.LocalHumanTaskService;
                                  import org.jbpm.workflow.instance.WorkflowProcessInstance;
                                  
                                  
                                  import com.st.ams.tools.ClaimEventListener;
                                  import com.ste.ws.authentication.seam.api.UserLDAP;
                                  
                                  
                                  /**
                                   * Linked to the task management view
                                   *
                                   */
                                  public @Named @SessionScoped class TaskManager implements Serializable{
                                  
                                  
                                            private static final long serialVersionUID = 7768657778155604411L;
                                  
                                            protected @Inject Identity identity;
                                            private @Inject StatefulKnowledgeSession kSession;
                                            private @Inject Event<ClaimEventListener> event;
                                  
                                            private List<Status> listStatus = new ArrayList<Status>();
                                  
                                            public org.jbpm.task.TaskService getTaskService(){
                                                      return LocalHumanTaskService.getTaskService(kSession);
                                            }
                                  
                                            private List<TaskSummary> userTaskList = new ArrayList<TaskSummary>();
                                            private Map<String, List<TaskSummary>> groupTaskMap = new HashMap<String, List<TaskSummary>>();
                                            private TaskSummary manageTask;
                                            private List<String> groups;
                                  
                                  
                                  
                                            public @PostConstruct void init(){
                                                      System.out.println("init task manager ...");
                                  
                                                      //Load user tasks
                                                      listStatus.clear();
                                                      listStatus.add(Status.Reserved);listStatus.add(Status.InProgress);
                                                      System.out.println("load task list for user : "+((UserLDAP)identity.getUser()).getUser().getLogin());
                                                      userTaskList = new ArrayList<TaskSummary>(getTaskService().getTasksAssignedAsPotentialOwnerByStatus(
                                                                                                                  ((UserLDAP)identity.getUser()).getUser().getLogin(), 
                                                                                                                  listStatus, 
                                                                                                                  "en-UK"));
                                  
                                                      //Load groups and tasks for each group
                                                      groups = new ArrayList<String>();
                                                      for(String grp : ((UserLDAP)identity.getUser()).getUser().getGroups()){
                                                   groups.add(grp);
                                                   groupTaskMap.put(grp, getGroupTasks(grp));
                                                      }
                                            }
                                  
                                  
                                            public List<TaskSummary> getUserTaskList() {
                                                      if((userTaskList == null) || userTaskList.isEmpty()){
                                                                listStatus.clear();
                                                                listStatus.add(Status.Reserved);listStatus.add(Status.InProgress);
                                  
                                                 //Trick because UserGroupCallBackImpl is not properly implemented
                                                 //TODO correction
                                                                Set<TaskSummary> set = new HashSet<TaskSummary>(getTaskService().getTasksAssignedAsPotentialOwnerByStatus(
                                                                                                                                                                                        ((UserLDAP)identity.getUser()).getUser().getLogin(), 
                                                                                                                                                                                        listStatus, 
                                                                                                                                                                                        "en-UK"));
                                                                userTaskList = new ArrayList<TaskSummary>(set);
                                                      }
                                                      return userTaskList;
                                            }
                                  
                                            /**
                                             * In order to refresh the user task list
                                             * This function allow to clear the content of the list
                                             */
                                            public void clearUserTaskList(){
                                                      userTaskList.clear();
                                            }
                                  
                                            /**
                                             * In order to refresh the groups task list
                                             * This function allow to clear the content of all lists
                                             */
                                            public void clearAllGroupTaskList(){
                                                      List<String> keys = new ArrayList<>(groupTaskMap.keySet());
                                                      for(String grp : keys){
                                                                clearGroupTaskList(grp);
                                                      }
                                            }
                                  
                                            /**
                                             * In order to refresh the group task list
                                             * This function allow to clear the content of the list
                                             */
                                            public void clearGroupTaskList(String group){
                                                      groupTaskMap.put(group, null);
                                            }
                                  
                                  
                                            /**
                                             * return all group tasks available for the user
                                             * @return List<TaskSummary>
                                             */
                                            public List<TaskSummary> getAllGroupTaskList() {
                                                      List<TaskSummary> allGroupTask = new ArrayList<TaskSummary>();
                                                      Iterable<List<TaskSummary>> mapValues = groupTaskMap.values();
                                                      for(List<TaskSummary> entry : mapValues){
                                                                allGroupTask.addAll(entry);
                                                      }
                                                      return allGroupTask;
                                            }
                                  
                                            public List<String> getUserGroups(){
                                                      if((groups == null) || groups.isEmpty()){
                                                                groups = new ArrayList<String>();
                                                                for(String grp : ((UserLDAP)identity.getUser()).getUser().getGroups()){
                                                      groups.add(grp);
                                                                }
                                                      }
                                                      return groups;
                                            }
                                  
                                            /**
                                             * return tasks available for the group
                                             * @param group
                                             * @return List<TaskSummary>
                                             */
                                            public List<TaskSummary> getGroupTaskList(String group){
                                                      if((groupTaskMap.get(group) == null) || groupTaskMap.get(group).isEmpty()){
                                                                groupTaskMap.put(group, getGroupTasks(group));
                                                      }
                                                      return groupTaskMap.get(group);
                                            }
                                  
                                            /**
                                             * return tasks available for the group
                                             * @param group
                                             * @return List<TaskSummary>
                                             */
                                            public List<TaskSummary> getGroupTasks(String group){
                                                      listStatus.clear();
                                                      listStatus.add(Status.Ready);
                                  
                                  
                                            //Trick because UserGroupCallBackImpl is not properly implemented
                                            //TODO correction
                                            Set<TaskSummary> set = new HashSet<TaskSummary>(getTaskService().getTasksAssignedAsPotentialOwnerByStatus(group, listStatus, "en-UK"));
                                                      return new ArrayList<TaskSummary>(set);
                                            }
                                  
                                            public void removeGroup(String group){
                                                      groups.remove(group);
                                            }
                                  
                                            public void addGroup(String group){
                                                      if((group != null) && !group.isEmpty())
                                                                groups.add(group);
                                            }
                                  
                                            public void addGroupTask(String group){
                                                      groupTaskMap.put(group, getGroupTasks(group));
                                            }
                                  
                                  
                                            /**
                                             * Start a new processInstance of an existing Process
                                             * and set the variables of this instance
                                             * @param processId, map of variables, id of the requestor
                                             * @return ProcessInstance created
                                             */
                                            public ProcessInstance startProcess(String processId, Map<String, Object> parameters){
                                                      ProcessInstance p = kSession.startProcess(processId,parameters);
                                                      return p;
                                            }
                                  
                                            /**
                                             * Return the WorkflowProcessInstance associated to a Task
                                             * This instance allow to access the map of variables
                                             * @return WorkflowProcessInstance managed
                                             */
                                            public WorkflowProcessInstance getWorkflowProcessInstance(long processInstanceId){
                                                      return (WorkflowProcessInstance)kSession.getProcessInstance(processInstanceId);
                                            }
                                  
                                  
                                            /**
                                             * Start a new processInstance of an existing Process
                                             * @param processId
                                             * @return ProcessInstance created
                                             */
                                            public ProcessInstance startProcess(String processId){
                                                      return kSession.startProcess(processId);
                                            }
                                  
                                  
                                            /**
                                             * When a user claim a task, the task go to RESERVED state
                                             * Then we call start and the task goes to IN_PROGRESS state
                                             * and is not visible for others
                                             * @param task
                                             */
                                            public void claimTask(TaskSummary task){
                                                      addMessage("task "+task.getId()+" claimed");
                                                      setManageTask(task);
                                                      getTaskService().claim(task.getId(), 
                                                                          ((UserLDAP)identity.getUser()).getUser().getLogin());
                                                      getTaskService().start(task.getId(), ((UserLDAP)identity.getUser()).getUser().getLogin());
                                                      event.fire(new ClaimEventListener());
                                            }
                                  
                                            /**
                                             * return a task to group task
                                             * @param task
                                             */
                                            public void revokeTask(TaskSummary task){
                                                      addMessage("task "+task.getId()+" revoked");
                                                      setManageTask(task);
                                                      getTaskService().release(task.getId(), 
                                                                          ((UserLDAP)identity.getUser()).getUser().getLogin());
                                            }
                                  
                                            public void completeTask(TaskSummary task, Object results){
                                                      getTaskService().completeWithResults(task.getId(), 
                                                                          ((UserLDAP)identity.getUser()).getUser().getLogin(), results);
                                            }
                                  
                                            /**
                                             * The current manage task
                                             * @return TaskSummary
                                             */
                                            public TaskSummary getManageTask() {
                                                      return manageTask;
                                            }
                                  
                                  
                                            /**
                                             * Set the currently manage task 
                                             * (save it during the session)
                                             * @param manageTask
                                             */
                                            private void setManageTask(TaskSummary manageTask) {
                                                      this.manageTask = manageTask;
                                            }
                                  
                                  
                                            /**
                                             * faces message rendered
                                             * @param message to display
                                             */
                                            public void addMessage(String summary) {  
                                          FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, summary,  null);  
                                          FacesContext.getCurrentInstance().addMessage(null, message);  
                                      } 
                                  
                                  }
                                  

                                   

                                  The entityManager :

                                  import java.util.logging.Logger;
                                  
                                  
                                  import javax.ejb.LocalBean;
                                  import javax.ejb.Stateless;
                                  import javax.enterprise.context.RequestScoped;
                                  import javax.enterprise.inject.Produces;
                                  import javax.enterprise.inject.spi.InjectionPoint;
                                  import javax.persistence.EntityManager;
                                  import javax.persistence.PersistenceContext;
                                  
                                  
                                  @Stateless
                                  @LocalBean
                                  public class EntityManagerProducer {
                                  
                                  
                                            @PersistenceContext(unitName = "org.jbpm.task")
                                      private EntityManager em;
                                  
                                  
                                      @Produces
                                      public Logger createLogger(InjectionPoint injectionPoint) {
                                          return Logger.getLogger(injectionPoint.getMember()
                                                  .getDeclaringClass().getName());
                                      }
                                      
                                      @Produces @RequestScoped
                                      public EntityManager getEntityManager() {
                                                      return em;
                                            }
                                         
                                  }
                                  

                                   

                                  You have to implement the UserGroupCallBackImpl. (See the doc for that : http://docs.jboss.org/jbpm/v5.4/userguide/ch.human-tasks.html#d0e5419)

                                   

                                  You have to register your implementation of usergroupcallback by creating a file jbpm.usergroup.callback.properties in the folder resources.

                                   

                                  jbpm.usergroup.callback=com.your.package.path.with.dot.MyUserGroupCallbackImpl

                                   

                                  resources.png

                                   

                                   

                                  The persistence.xml must be configured like this :

                                  <?xml version="1.0" encoding="UTF-8"?>
                                  <persistence version="2.0" 
                                            xmlns="http://java.sun.com/xml/ns/persistence" 
                                            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                      xsi:schemaLocation="
                                          http://java.sun.com/xml/ns/persistence
                                          http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
                                          
                                       <persistence-unit name="org.jbpm.task" transaction-type="JTA">
                                                <provider>org.hibernate.ejb.HibernatePersistence</provider>
                                                   <jta-data-source>java:jboss/datasources/jbpmDS</jta-data-source>
                                          <mapping-file>META-INF/Taskorm.xml</mapping-file>
                                      
                                                <!-- jbpm human task classes -->
                                                <class>org.jbpm.task.Attachment</class>
                                                <class>org.jbpm.task.BooleanExpression</class>
                                                <class>org.jbpm.task.Comment</class>
                                                <class>org.jbpm.task.Content</class>
                                                <class>org.jbpm.task.Deadline</class>
                                                <class>org.jbpm.task.Delegation</class>
                                                <class>org.jbpm.task.EmailNotification</class>
                                                <class>org.jbpm.task.EmailNotificationHeader</class>
                                                <class>org.jbpm.task.Escalation</class>
                                                <class>org.jbpm.task.Group</class>
                                                <class>org.jbpm.task.I18NText</class>
                                                <class>org.jbpm.task.Notification</class>
                                                <class>org.jbpm.task.OnAllSubTasksEndParentEndStrategy</class>
                                                <class>org.jbpm.task.OnParentAbortAllSubTasksEndStrategy</class>
                                                <class>org.jbpm.task.PeopleAssignments</class>
                                                <class>org.jbpm.task.Reassignment</class>
                                                <class>org.jbpm.task.Status</class>
                                                <class>org.jbpm.task.SubTasksStrategy</class>
                                                <class>org.jbpm.task.Task</class>
                                                <class>org.jbpm.task.TaskData</class>
                                                <class>org.jbpm.task.User</class>
                                                <!-- My classes -->
                                                <!-- Event Classes -->
                                  <!--               <class>org.jbpm.task.TaskEvent</class> -->
                                      
                                                <exclude-unlisted-classes></exclude-unlisted-classes>
                                          
                                          <properties>
                                                    <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/> 
                                                                  <property name="hibernate.connection.isolation" value="8"/> 
                                                                  <property name="hibernate.hbm2ddl.auto" value="create-drop"/> 
                                                                  <property name="hibernate.show_sql" value="true"/> 
                                                                  <property name="hibernate.format_sql" value="true"/> 
                                                                  <property name="hibernate.jdbc.batch_size" value="40" /> 
                                                                  <property name="hibernate.cache.use_second_level_cache" value="false"/> 
                                                                  <property name="hibernate.cache.use_query_cache" value="false" /> 
                                                                  <property name="hibernate.cache.use_minimal_puts" value="false" />
                                    
                                                                  <!-- needed for JTA testing  -->
                                                            <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.BTMTransactionManagerLookup" /> 
                                         
                                                                  <!-- BZ 841786: AS7/EAP 6/Hib 4 uses new (sequence) generators which seem to cause problems -->      
                                                            <property name="hibernate.id.new_generator_mappings" value="false" />
                                          </properties>
                                      </persistence-unit>
                                      
                                  </persistence>
                                  

                                   

                                  Here it is configured for MySQL. You have to configured Jboss with the correct datasource.

                                   

                                  For the view, I create a composite component to display tasks in general and use it with corresponding parameters :

                                   

                                   

                                  So just with that you can manage simple process from start to end. I have not yet finish my application so the view isn't very good but for test it works fine.

                                   

                                  Hope this will help you start.

                                   

                                  Regards,

                                  • 14. Re: Integrating jBPM 5 into web application - architecture
                                    Anand Kumar Jha Newbie

                                    thanks a lot sandra!...:)

                                    Hope this will help me a lot...:)

                                    here i kickstart///...:)