-
1. Re: Job Executor and Spring
oravecz Oct 9, 2008 10:13 PM (in response to ssljivic)Funny, but I just wrote this class:
import org.jbpm.JbpmConfiguration; import org.jbpm.job.executor.JobExecutor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Required; /** * */ public class JobExecutorInitializingBean implements InitializingBean, DisposableBean { // Statics ----------------------------------------------------------------- private static final Logger LOG = LoggerFactory.getLogger(JobExecutorInitializingBean.class); // Instances --------------------------------------------------------------- private JbpmConfiguration _jbpmConfiguration; /** * Invoked by a BeanFactory after it has set all bean properties supplied * (and satisfied BeanFactoryAware and ApplicationContextAware). * <p>This method allows the bean instance to perform initialization only * possible when all bean properties have been set and to throw an * exception in the event of misconfiguration. * * @throws Exception in the event of misconfiguration (such * as failure to set an essential property) or if initialization fails. */ public void afterPropertiesSet() throws Exception { JobExecutor jobExecutor = _jbpmConfiguration.getJobExecutor(); if (jobExecutor != null) jobExecutor.start(); else LOG.warn("No JobExecutor was found in the jBPM configuration."); } /** * Invoked by a BeanFactory on destruction of a singleton. * * @throws Exception in case of shutdown errors. * Exceptions will get logged but not rethrown to allow * other beans to release their resources too. */ public void destroy() throws Exception { JobExecutor jobExecutor = _jbpmConfiguration.getJobExecutor(); if (jobExecutor != null) jobExecutor.stop(); } @Required public void setJbpmConfiguration(final JbpmConfiguration jbpmConfiguration) { _jbpmConfiguration = jbpmConfiguration; } }
-
2. Re: Job Executor and Spring
oravecz Oct 9, 2008 10:35 PM (in response to ssljivic)I haven't yet got timers working for me so take that code with a grain of salt. Also note that I use the LocalJbpmConfigurationFactoryBean in my spring config, so I don't want to declare the same config twice. For this reason my spring.xml file looks like this:
<bean id="jbpmConfig" class="org.springmodules.workflow.jbpm31.LocalJbpmConfigurationFactoryBean" p:sessionFactory-ref="sessionFactory" p:configuration="classpath:org/jbpm/default.jbpm.cfg.xml" > <property name="processDefinitionsResources"> <list> <value>classpath:workflow/**/processdefinition.xml</value> </list> </property> </bean> <bean id="jbpmTemplate" class="org.springmodules.workflow.jbpm31.JbpmTemplate"> <constructor-arg index="0" ref="jbpmConfig"/> </bean> <bean class="md.signmeup.workflow.jbpm.JobExecutorInitializingBean" p:jbpmConfiguration-ref="jbpmConfig" />
and I had a problem in my code. This overcomes it:import org.jbpm.JbpmConfiguration; import org.jbpm.job.executor.JobExecutor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Required; /** * */ public class JobExecutorInitializingBean implements InitializingBean, DisposableBean { // Statics ----------------------------------------------------------------- private static final Logger LOG = LoggerFactory.getLogger(JobExecutorInitializingBean.class); // Instances --------------------------------------------------------------- private JbpmConfiguration _jbpmConfiguration; public void afterPropertiesSet() throws Exception { JobExecutor jobExecutor = _jbpmConfiguration.getJobExecutor(); if (jobExecutor != null) { jobExecutor.setJbpmConfiguration(_jbpmConfiguration); jobExecutor.start(); } else { if (LOG.isWarnEnabled()) LOG.warn("No JobExecutor was found in the jBPM configuration."); } } public void destroy() throws Exception { JobExecutor jobExecutor = _jbpmConfiguration.getJobExecutor(); if (jobExecutor != null) jobExecutor.stop(); } @Required public void setJbpmConfiguration(final JbpmConfiguration jbpmConfiguration) { _jbpmConfiguration = jbpmConfiguration; } }
-
3. Re: Job Executor and Spring
ssljivic Oct 10, 2008 6:24 AM (in response to ssljivic)The provided solution worked, but I had to extract all jBPM *.hbm.xml files to the source/classes folder, because Spring was unable to load them from the JAR file.
I have another question. I have Job Executor configured in jbpm.cfg.xml file like this:<bean name="jbpm.job.executor" class="org.jbpm.job.executor.JobExecutor"> <field name="jbpmConfiguration"> <ref bean="jbpmConfiguration" /> </field> <field name="name"><string value="JbpmJobExecutor" /></field> <field name="nbrOfThreads"><int value="1" /></field> <field name="idleInterval"><int value="5000" /></field> <field name="maxIdleInterval"><int value="3600000" /></field> <!-- 1 hour --> <field name="historyMaxSize"><int value="20" /></field> <field name="maxLockTime"><int value="600000" /></field> <!-- 10 minutes --> <field name="lockMonitorInterval"><int value="60000" /></field> <!-- 1 minute --> <field name="lockBufferTime"><int value="5000" /></field> <!-- 5 seconds --> </bean>
How can I move that definition into the Spring XML configuration? Is it possible to entirely ignore jbpm.cfg.xml and move entire jBPM configuration into the Spring XML files?
Thanks -
4. Re: Job Executor and Spring
kukeltje Oct 10, 2008 6:49 AM (in response to ssljivic)Warning: Partly threadjacking although it is related to the question
You know... maybe I missed something in my upbringing, but maybe now is the time to 'learn' that.
I can understand that you want to be able to inject other pojo's at some moment in time or in a speciic situation and use e.g. seam, guice, spring etc for that. What I do not understand is that people also want to move the config's (that are already in xml) for which you can have (or 'inject') different ones for different environments to a new xml file (a spring config).... In seam people do not do this, they just leverage, but spring users most always want this (or is that my impression?). What is the advantage of this? -
5. Re: Job Executor and Spring
ssljivic Oct 10, 2008 7:14 AM (in response to ssljivic)Hi,
The reason for moving the configuration to the Spring XML is in order to be able to use PropertyPlaceholderConfigurer. That way no values would be "hard coded" in the XML, but rather defined in the properties file.
Can I achieve that with jbpm.cfg.xml, so that I can define "idleInterval" in the properties file?
Thanks -
6. Re: Job Executor and Spring
oravecz Oct 12, 2008 1:30 AM (in response to ssljivic)JobExecutor seems to be exposed as a property of the jbpmConfiguration. It is not one of the built-in service factories like authentication, persistence or scheduler.
That said, if you were to externalize the bootstrapping of JobExecutor, you will have to get JbpmConfiguration to be knowledgable about your instance of JobExecutor.
Now, JbpmConfiguration uses the object factory to locate the job executor using a string key value of "jbpm.job.executor". I haven't tried this, but if you are using the spring modules jbpm integration, they replace the default ObjectFactory with one that uses object factory keys as lookups in a spring context. Theoretically, this should mean that you can instantiate the JobExecutor in Spring and all you have to do is make sure the id value is 'jbpm.job.executor'. -
7. Re: Job Executor and Spring
oravecz Oct 12, 2008 2:47 AM (in response to ssljivic)I tried my suggestion and it works, but the JbpmObjectFactory supplied in the spring modules integration is a bit lacking. It isn't wired in as the default object factory out of the gate. You have to do this yourself. Also, it is an all or nothing proposition, meaning if you use this object factory, all of the resources used by jBPM need to be defined in Spring.
Here is a new class that will attempt to find resource names in Spring, and if that fails, it will delegate to the original jBPM mechanism.import org.springmodules.workflow.jbpm31.JbpmObjectFactory; import org.jbpm.configuration.ObjectFactoryImpl; import org.jbpm.configuration.ObjectFactoryParser; import org.jbpm.JbpmConfiguration; import org.springframework.core.io.Resource; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.*; /** * */ public class SpringJbpmObjectFactory extends JbpmObjectFactory implements InitializingBean { // Statics ----------------------------------------------------------------- private static final Logger LOG = LoggerFactory.getLogger(SpringJbpmObjectFactory.class); // Instances --------------------------------------------------------------- protected ObjectFactoryImpl _objectFactory; protected Resource _configuration; // InitializingBean implementation ----------------------------------------- public void afterPropertiesSet() throws Exception { if (_configuration != null) { LOG.info("creating JbpmConfiguration from resource " + _configuration.getDescription()); InputStream stream = _configuration.getInputStream(); _objectFactory = ObjectFactoryParser.parseInputStream(stream); stream.close(); } JbpmConfiguration.Configs.setDefaultObjectFactory(this); } // JbpmObjectFactory overrides --------------------------------------------- @Override public Object createObject(final String name) { Object result = null; try { result = super.createObject(name); } catch (NoSuchBeanDefinitionException e) { result = _objectFactory.createObject(name); } return result; } @Override public boolean hasObject(final String name) { boolean result = false; try { result = super.hasObject(name); } catch (NoSuchBeanDefinitionException e) { result = _objectFactory.hasObject(name); } return result; } // Properties -------------------------------------------------------------- public void setConfiguration(final Resource configuration) { _configuration = configuration; } }
If you are already using spring module for jBPM, you are probably using the LocalJbpmConfigurationFactoryBean class and you are more than likely specifying the path to a jbpm.xml config file. That's a problem, since the presence of a config file causes a fallback to the original object factory even if you specify your own object factory.
Here's how to configure spring to use the new object factory and a JobExecutor defined in the spring config file.<bean id="jbpmObjectFactory" class="com.example.jbpm.SpringJbpmObjectFactory" p:configuration="classpath:META-INF/jbpm.cfg.xml" /> <bean id="jbpmConfig" class="org.springmodules.workflow.jbpm31.LocalJbpmConfigurationFactoryBean" p:sessionFactory-ref="sessionFactory" p:objectFactory-ref="jbpmObjectFactory" > <property name="processDefinitionsResources"> <list> <value>classpath:workflow/**/processdefinition.xml</value> </list> </property> </bean> <bean name="jbpm.job.executor" class="org.jbpm.job.executor.JobExecutor" p:jbpmConfiguration-ref="jbpmConfig" p:nbrOfThreads="1" p:idleInterval="5000" p:maxIdleInterval="3600000" p:historyMaxSize="20" p:maxLockTime="600000" p:lockMonitorInterval="60000" p:lockBufferTime="5000" > <property name="name" value="JbpmJobExecutor" /> </bean>
-
8. Re: Job Executor and Spring
kukeltje Oct 12, 2008 6:21 AM (in response to ssljivic)That way no values would be "hard coded" in the XML, but rather defined in the properties file.
Ahhh cool... "hardcoded" in a properties file instead of an xml file.... -
9. Re: Job Executor and Spring
oravecz Oct 12, 2008 11:26 AM (in response to ssljivic)I don't want to quibble over configuration placement. For those applications that make heavy use of Spring configuration already, doing some or all of this configuration makes sense, especially when it comes to a unified transaction manager. After all, jBPM has an object factory for a reason.
-
10. Re: Job Executor and Spring
lblaauw Oct 24, 2008 2:57 AM (in response to ssljivic)Uhh,
The use case is quite common actually to have one spring configuration xml and have property files for your different environments like test,
production etc to minimize the configuration data and make for easy
deployment of a spring app. So nothing unusual there really...
But to stay on topic we just use the EJB timerservice with our spring
app and jBPM works fine.
Regards,
Leo"kukeltje" wrote:
That way no values would be "hard coded" in the XML, but rather defined in the properties file.
Ahhh cool... "hardcoded" in a properties file instead of an xml file.... -
11. Re: Job Executor and Spring
kukeltje Oct 24, 2008 4:49 AM (in response to ssljivic)Leo, I know the usecase is quite common, but that does not mean it makes sense in all cases (to me)
My initial question was real and serious. But if I talk to people who use spring this way, I always get the answer about the config files and a statement like 'that is the way we do it' (often that is what they were tought/told and have no clue about advantages and mostly have problems like this one because of the way they use it)
Personally I use config files in a different way and do not miss Spring *for this* (not needed it for other things) So maybe I therefore reacted a little sarcasticly, but I am really interested in 'profoundly' discussing this. Can you send me an email on ronald (dot) jbpm (at) org (replace the not so obvious) so we can discuss this out-of-band?