[JBoss jBPM] - Action not executing in timer
by oravecz
I am having some trouble getting a workflow to function the way I want it to. I have stripped it down to a very simple example.
I have a node that will attempt to process a credit card. If it fails to communicate to the server I would like it to pause for a couple minutes, then try again. This example is bare bones and node1 represents the initial attempt anf state1 represents a delay. After the delay, the next node will eventually be a node that retries the communication, but for now it simply ends.
| <process-definition xmlns="" name="examplePause">
| <start-state name="startPauseExample">
| <transition to="node1"></transition>
| </start-state>
|
| <node name="node1">
| <script>
| System.out.println("Node: " + node);
| token.signal();
| </script>
| <transition to="state1"></transition>
| </node>
|
| <state name="state1">
| <script>
| System.out.println("Node: " + node);
| </script>
| <timer name="timer1" duedate="10 seconds" transition="end" cancel-event="node-left">
| <script>
| System.out.println("Timer executed.");
| token.signal();
| </script>
| </timer>
| <transition to="endPauseExample" name="end"></transition>
| </state>
|
|
| <end-state name="endPauseExample"></end-state>
| </process-definition>
|
My unit test executes the workflow by calling getRootToken.signal(). It then sleeps for 15 seconds. At the end of 15 seconds, I was hoping that the timer would of fired and I would transition to the next node (the end state). But when the 15 seconds ends, the token is still in 'state1'.
I'm not sure if the following logs show the appropriate steps, but the major players seem to be there:
| [org.jbpm.graph.def.GraphElement] - event 'process-start' on 'ProcessDefinition(examplePause)' for
| 'Token(/)'
| [org.jbpm.graph.def.GraphElement] - event 'before-signal' on 'StartState(startPauseExample)' for
| 'Token(/)'
| [org.jbpm.graph.def.GraphElement] - event 'node-leave' on 'StartState(startPauseExample)' for
| 'Token(/)'
| [org.jbpm.graph.def.GraphElement] - event 'transition' on 'Transition(7857a5)' for 'Token(/)'
| [org.jbpm.graph.def.GraphElement] - event 'node-enter' on 'Node(node1)' for 'Token(/)'
| [org.jbpm.graph.def.GraphElement] - executing action 'Script(19deddb)'
| [org.jbpm.graph.def.GraphElement] - event 'before-signal' on 'Node(node1)' for 'Token(/)'
| [org.jbpm.graph.def.GraphElement] - event 'node-leave' on 'Node(node1)' for 'Token(/)'
| [org.jbpm.graph.def.GraphElement] - event 'transition' on 'Transition(3744bc)' for 'Token(/)'
| [org.jbpm.graph.def.GraphElement] - event 'node-enter' on 'State(state1)' for 'Token(/)'
| [org.jbpm.graph.def.GraphElement] - executing action 'CreateTimerAction(8032df)'
| [org.jbpm.graph.def.GraphElement] - event 'timer-create' on 'State(state1)' for 'Token(/)'
| I see the database insert statement...
| [org.jbpm.graph.def.GraphElement] - event 'after-signal' on 'Node(node1)' for 'Token(/)'
| [ org.jbpm.graph.action.Script] - script output: {}
| [org.jbpm.graph.def.GraphElement] - event 'after-signal' on 'StartState(startPauseExample)' for
| 'Token(/)'
| I see the job being pulled from the database by the JobExecutor...
| [ org.hibernate.pretty.Printer] - org.jbpm.job.Timer{isExclusive=false, lockTime=null,
| isSuspended=false, exception=null,
| graphElement=org.jbpm.graph.node.State#18,
| processInstance=org.jbpm.graph.exe.ProcessInstance#1,
| repeat=null, version=0, id=1, lockOwner=null,
| token=org.jbpm.graph.exe.Token#1, name=timer1,
| action=org.jbpm.graph.def.Action#20, retries=1,
| dueDate=2008-10-12 02:56:25, transitionName=end,
| taskInstance=null}
|
The database record references the correct action in the database (System.out.println("Timer executed...) but the action is never initiated.
Any ideas what I might try? Is the jpdl correct for what I intend to do?
Thanks.
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4181669#4181669
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4181669
17 years, 6 months
[JBoss jBPM] - Re: Job Executor and Spring
by oravecz
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>
|
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4181668#4181668
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4181668
17 years, 6 months
[JBoss jBPM] - Re: Job Executor and Spring
by oravecz
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'.
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4181666#4181666
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4181666
17 years, 6 months
[JBoss jBPM] - Re: Problem with java.sql.Date as Variable
by roberto
I found the problem (I believe....) but I don't know how to fix it.
I believe it is a problem related to hibernate.
The JBPM_VARIABLEINSTANCE table contains a column DATEVALUE_ of type "timestamp" and the hibernate mapping use that column for every java.util.Date (or extends) classes.
So java.sql.Date will be a java.sql.Timestamp when read it back.
So, I believe it is necessary to change this behaviours.
I believe there are only 2 way:
1) add 2 new columns to JBPM_VARIABLEINSTANCE in order to add a Date and a Time column.
add mapping for this 2 new column
2) change the org.jbpm.context.exe.variableinstance.DateInstance (...create a new class estending from it) that analize data and return back a java.sql.Date or a java.sql.Time or a java.sql.Timestamp according column value.
but.. I don't know hibernate .. so I believe this is not the right way and/or how to do it
Can someone help me ?
thanks
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4181649#4181649
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4181649
17 years, 6 months