Results 1 to 8 of 8

Thread: JBPM scheduler Integration

Hybrid View

  1. #1
    Join Date
    Nov 2005
    Posts
    8

    Default JBPM scheduler Integration

    Hello,

    I am wondering about the integration of the JBPM DB scheduler service from spring modules.

    I do have the jbpm.cfg.xml file with an entry for the scheduler service as :
    Code:
      	<service name="scheduler" factory="org.jbpm.scheduler.db.DbSchedulerServiceFactory" />
    and I had this understanding that the service will be started as part of the LocalJbpmConfigurationFactoryBean implementation but it just starts the persistence service not the scheduler service.

    Wondering how to go about the integration of this service from Spring world?

    Thanks,
    Arshad

  2. #2
    Join Date
    Nov 2005
    Posts
    8

    Default Update

    A little more info in this regard, we tried SchedulerServlet from JBPM but it starts building its own session factory etc independent of the one we configured through spring.

    This is like having a parallel configuration based on JBPM instead of spring to run the scheduler.

    So, now, i am realising there is huge need to have this JBPM Scheduler (scheduler servlet or the DB Scheduler service) integrated in the spring modules.

    Let me know if you need any further info?

    Thanks,
    Arshad

  3. #3

    Default

    Any Idea how to do that?

    Thanx & regards
    Milan

  4. #4
    Join Date
    Apr 2007
    Posts
    1

    Default integerate timer with spring modules

    hi dears

    i create new class like this write all codes in JbpmThreadsServlet)

    public class TimerBean implements InitializingBean {

    private JbpmConfiguration jbpmConfiguration = null;
    private CommandExecutorThread commandExecutorThread = null;
    private SchedulerThread schedulerThread = null;

    public void afterPropertiesSet() throws Exception {
    // get the jbpm configuration resource
    commandExecutorThread = new CommandExecutorThread(jbpmConfiguration);
    commandExecutorThread.start();

    schedulerThread = new SchedulerThread(jbpmConfiguration);
    schedulerThread.start();
    }

    public JbpmConfiguration getJbpmConfiguration() {
    return jbpmConfiguration;
    }

    public void setJbpmConfiguration(JbpmConfiguration jbpmConfiguration) {
    this.jbpmConfiguration = jbpmConfiguration;
    }

    }

    and add TimerBean to spring like this :

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
    "http://www.springframework.org/dtd/spring-beans.dtd">
    <beans>
    <bean id="timerBean" class="TimerBean">
    <property name="jbpmConfiguration" ref="jbpmConfiguration"/>
    </bean>
    </beans>

    and finish my and your problem.

  5. #5
    Join Date
    May 2007
    Posts
    3

    Default Complete code + update

    Thanks for posting a solution m8 - but you forgot to tell us that any action related to the SchedulerThread/Service should be done when a valid JbpmContext is available e.g. :

    Code:
                    /** remember - t1 WON'T be valid after you get out of the execute() method.... since the context is only valid for the duration you stay inside that method, any jbpm method you execute that requires the context (inside the domain of spring, OR even outside) will have access to it. */
    
    		JbpmContext t1 = (JbpmContext)getJbpmTemplate().execute(new JbpmCallback() {
    		     public Object doInJbpm(JbpmContext context) {
    		      // do something
    		    	 ProcessInstance processInstance = context.getProcessInstance(instanceId);
    		 		log.debug("found process...");
    				processInstance.signal();
    				log.debug("signalled process...");
    				context.save(processInstance);
    				log.debug("saved process...");
    		    	 return JbpmContext.getCurrentJbpmContext(); // statement not really needed - you can return null, or even monkey for all I care.
    		     }
    		  });

    In contrast, if you had something like this:

    Code:
                    // this caused me too much misery with a timer node.... will never work!
    		ProcessInstance processInstance = jbpmTemplate.findProcessInstance(instanceId);
    		log.debug("found process...");
    		processInstance.signal();
    		log.debug("signalled process...");
    		jbpmTemplate.saveProcessInstance(processInstance);
    		log.debug("saved process...");
    It won't work as the context would be closed for some reason when the Scheduler code was reached.... and when that happened, I debugged the code and found out where it was failing and then printing a BIG FAT 'service "scheduler" not available OOHH Exception bla bla blady bla' :

    Code:
     // code from org.jbpm.svc.Services
    
      public static Service getCurrentService(String name) {
       return getCurrentService(name, true); 
      }
      
      public static Service getCurrentService(String name, boolean isRequired) {
        Service service = null;
    
        // this was coming in as null !!!! No context means no service - mommyyyyy!!!
        JbpmContext jbpmContext = JbpmContext.getCurrentJbpmContext();
        if (jbpmContext!=null) {
          service = jbpmContext.getServices().getService(name);
        }
        if (isRequired && (service==null)) {
          throw new JbpmServiceException("service '"+name+"' unavailable");
        }
        return service;
      }
    So everything is working A-OK now. For people who want to integrate the scheduler service, I have attached the full code here:

    Code:
    // applicationContext.xml
    
    <?xml version="1.0" encoding="UTF-8"?>
    
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:aop="http://www.springframework.org/schema/aop"
    	xmlns:tx="http://www.springframework.org/schema/tx"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
               http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
               http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
    
    	<!-- JBPM Datasource -->
    	<bean id="jbpmDataSource"
    		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    		<property name="driverClassName">
    			<value>com.mysql.jdbc.Driver</value>
    		</property>
    		<property name="url">
    			<value>
    				jdbc:mysql://localhost:3306/jbpmtest?useUnicode=true&amp;characterEncoding=UTF-8
    			</value>
    		</property>
    		<property name="username">
    			<value>jbpm</value>
    		</property>
    		<property name="password">
    			<value>jbpm</value>
    		</property>
    	</bean>
    
    	<bean id="mysqlHibernateProperties"
    		class="org.springframework.beans.factory.config.PropertiesFactoryBean">
    		<property name="properties">
    			<props>
    				<prop key="hibernate.dialect">
    					org.hibernate.dialect.MySQLDialect
    				</prop>
    				<prop key="hibernate.cache.provider_class">
    					org.hibernate.cache.HashtableCacheProvider
    				</prop>
    				<prop key="hibernate.default_batch_fetch_size">30</prop>
    				<prop key="hibernate.cache.use_query_cache">false</prop>
    			</props>
    		</property>
    	</bean>
    
    
    	<!-- JBPM Hibernate SessionFactory -->
    	<bean id="sessionFactory"
    		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    		<property name="dataSource" ref="jbpmDataSource" />
    		<property name="hibernateProperties"
    			ref="mysqlHibernateProperties" />
    		<property name="mappingLocations">
    			<value>classpath*:/org/jbpm/**/*.hbm.xml</value>
    		</property>
    	</bean>
    
    	<bean id="txManager"
    		class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    		<property name="sessionFactory" ref="sessionFactory" />
    	</bean>
    
    	<!-- helper for reading jBPM process definitions -->
    	<bean id="simpleWorkflow"
    		class="org.springmodules.workflow.jbpm31.definition.ProcessDefinitionFactoryBean">
    		<property name="definitionLocation"
    			value="classpath:com/arc/jbpmtest/sample/jpdl/simpleWorkflow/processdefinition.xml" />
    	</bean>
    
    
    	<!-- jBPM configuration -->
    	<!-- use this instead in production 
    		<bean id="jbpmConfig" class="arc.jbpmtest.CustomLocalJbpmConfigurationFactoryBean">
    	-->
    	<bean id="jbpmConfiguration"
    		class="org.springmodules.workflow.jbpm31.LocalJbpmConfigurationFactoryBean">
    		<property name="sessionFactory" ref="sessionFactory" />
    		<property name="configuration"
    			value="classpath:jbpm.cfg.xml" />
    		<property name="createSchema" value="false" />
    		<property name="processDefinitions">
    			<list>
    				<ref local="simpleWorkflow" />
    			</list>
    		</property>
    		<!--
    			<property name="processDefinitionsResources">
    			<list>
    			<value>classpath:/org/springmodules/workflow/jbpm31/someOtherWorkflow.xml</value>
    			</list>
    			</property>
    		-->
    	</bean>
    
    	<!-- jBPM template -->
    	<bean id="jbpmTemplate"
    		class="org.springmodules.workflow.jbpm31.JbpmTemplate">
    		<constructor-arg index="0" ref="jbpmConfiguration" />
    		<constructor-arg index="1" ref="simpleWorkflow" />
    	</bean>
    
    	<bean id="workflowServiceTarget"
    		class="com.arc.jbpmtest.sample.base.workflow.WorkflowService"
    		autowire="byName">
    		<property name="jbpmTemplate" ref="jbpmTemplate" />
    	</bean>
    	<bean id="workflowService"
    		class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    		<property name="transactionManager" ref="txManager" />
    		<property name="target" ref="workflowServiceTarget" />
    		<property name="proxyTargetClass" value="true" />
    		<property name="transactionAttributes">
    			<props>
    				<prop key="*">PROPAGATION_NESTED</prop>
    			</props>
    		</property>
    	</bean>
    	<bean id="myMessageActionHandler"
    		class="com.arc.jbpmtest.sample.action.MessageActionHandler">
    		<property name="message"
    			value="This Message is Spring Injected!" />
    	</bean>
    	<bean id="workflowController"
    		class="com.arc.jbpmtest.beans.WorkflowController" scope="session">
    		<property name="workflowService" ref="workflowService" />
    	</bean>
    	<bean id="timerBean" class="com.arc.jbpmtest.servlets.JbpmThreadsServlet$TimerBean">
    		<property name="jbpmConfiguration" ref="jbpmConfiguration" />
    		<property name="jbpmTemplate" ref="jbpmTemplate" />
    	</bean>
    </beans>

  6. #6
    Join Date
    May 2007
    Posts
    3

    Default

    Code:
    // WorkflowService
    package com.arc.jbpmtest.sample.base.workflow;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;
    
    import org.apache.log4j.Logger;
    import org.jbpm.JbpmConfiguration;
    import org.jbpm.JbpmContext;
    import org.jbpm.graph.exe.ProcessInstance;
    import org.jbpm.svc.JbpmServiceException;
    import org.jbpm.svc.Services;
    import org.springmodules.workflow.jbpm31.JbpmCallback;
    import org.springmodules.workflow.jbpm31.JbpmTemplate;
    
    public class WorkflowService {
    
    	/**
    	 * Logger for this class
    	 */
    	private static final Logger log = Logger.getLogger(WorkflowService.class);
    	
    	private JbpmTemplate jbpmTemplate; 
    	
    	public WorkflowService() {
    		log.debug("WorkflowService()");
    	}
    	
    	public List<ProcessInstanceItem> getProcessInstances() {
    		log.debug("Enter getProcessInstances()");
    		
    		log.debug("About to get list of instances");
    		List<ProcessInstance> lst = jbpmTemplate.findProcessInstances();
    		log.debug("Got list - list has " + lst.size() + "elements.." );
    		
    		List<ProcessInstanceItem> processInstanceItems = new ArrayList<ProcessInstanceItem>();
    		
    		for (Iterator iter1 = lst.iterator(); iter1.hasNext();) {
    			log.debug("Entered loop" );
    			ProcessInstance element = (ProcessInstance) iter1.next();
    			log.debug("Got element..." );
    			ProcessInstanceItem item = new ProcessInstanceItem();
    			item.setDefName(element.getProcessDefinition().getName());
    			log.debug("Got name..." );
    			item.setEnd(element.getEnd());
    			log.debug("Got end..." );
    			item.setIdentifier(element.getId());
    			log.debug("Got Id..." );
    			item.setMessage("Dummy Message"/*(String)(element.getContextInstance().getVariables().get("message"))*/);
    			log.debug("Got message..." );
    			item.setNodeName(element.getRootToken().getNode().getName());
    			log.debug("Got Node name..." );
    			item.setStarted(element.getStart());
    			log.debug("Got Start..." );
    			processInstanceItems.add(item);	
    		}
    		
    		
    		return processInstanceItems;
    		
    	} 
    	
    	public ProcessInstance getNewProcessInstance() {
    		
    		log.debug("in getNewProcessInstance()");
    		log.debug("creating processInstance");
    		ProcessInstance processInstance = jbpmTemplate.getProcessDefinition().createProcessInstance();
    		log.debug("after creating processInstance");
    		jbpmTemplate.saveProcessInstance(processInstance);
    		log.debug("saved instance... processInstance");
    		return processInstance;
    		
    	} 
    	
    	public void signalProcessInstance(final Long instanceId) {
    		log.debug("in signalProcessInstance()");
    		
    
    		JbpmContext t1 = (JbpmContext)getJbpmTemplate().execute(new JbpmCallback() {
    		     public Object doInJbpm(JbpmContext context) {
    		      // do something
    		    	 ProcessInstance processInstance = context.getProcessInstance(instanceId);
    		 		log.debug("found process...");
    				processInstance.signal();
    				log.debug("signalled process...");
    				context.save(processInstance);
    				log.debug("saved process...");
    		    	 return JbpmContext.getCurrentJbpmContext();
    		     }
    		  });
    		
    		/*ProcessInstance processInstance = jbpmTemplate.findProcessInstance(instanceId);
    		log.debug("found process...");
    		processInstance.signal();
    		log.debug("signalled process...");
    		jbpmTemplate.saveProcessInstance(processInstance);
    		log.debug("saved process...");*/
    	}
    	
    	public JbpmTemplate getJbpmTemplate() {
    		log.debug("in getJbpmTemplate()");
    
    		return jbpmTemplate;
    	}
    
    	public void setJbpmTemplate(JbpmTemplate jbpmTemplate) {
    		log.debug("in setJbpmTemplate(JbpmTemplate jbpmTemplate)");
    		log.debug("jbpmTemplate is " + jbpmTemplate.getContextName());
    		this.jbpmTemplate = jbpmTemplate;
    	}
    
    	
    }

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •