Author: thomas.diesler(a)jboss.com
Date: 2008-07-24 07:31:32 -0400 (Thu, 24 Jul 2008)
New Revision: 1703
Added:
jbpm3/branches/tdiesler/modules/jpdl/core/src/test/java/org/jbpm/job/executor/TimerOnTimerDbTest.java
jbpm3/branches/tdiesler/modules/jpdl/core/src/test/resources/org/jbpm/job/executor/timerOnTimer.jpdl.xml
Removed:
jbpm3/branches/tdiesler/modules/jpdl/integration/
Modified:
jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/db/JobSession.java
jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/job/ExecuteActionJob.java
jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/job/ExecuteNodeJob.java
jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/job/Timer.java
jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/job/executor/JobExecutorThread.java
jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/msg/db/DbMessageService.java
jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/scheduler/db/DbSchedulerService.java
jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/svc/Services.java
jbpm3/branches/tdiesler/modules/jpdl/core/src/main/resources/org/jbpm/db/hibernate.queries.hbm.xml
jbpm3/branches/tdiesler/modules/jpdl/core/src/test/resources/log4j.xml
jbpm3/branches/tdiesler/modules/jpdl/pom.xml
Log:
Rollback to -r1492. Merge -r1552:1558
Modified:
jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/db/JobSession.java
===================================================================
---
jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/db/JobSession.java 2008-07-24
11:06:45 UTC (rev 1702)
+++
jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/db/JobSession.java 2008-07-24
11:31:32 UTC (rev 1703)
@@ -15,7 +15,6 @@
import org.jbpm.graph.def.Action;
import org.jbpm.graph.exe.ProcessInstance;
import org.jbpm.graph.exe.Token;
-import org.jbpm.job.ExecuteNodeJob;
import org.jbpm.job.Job;
import org.jbpm.job.Timer;
import org.jbpm.svc.save.SaveOperation;
@@ -194,30 +193,18 @@
return;
}
- // the bulk delete was replaced with a query and session.deletes on
- // the retrieved elements to prevent stale object exceptions.
- // With a bulk delete, the hibernate session is not aware and gives a problem
- // if a later session.delete doesn't return 1.
log.debug("deleting timers for process instance "+processInstance);
Session session = jbpmContext.getSession();
- Query query =
session.getNamedQuery("JobSession.getTimersForProcessInstance");
+ Query query =
session.getNamedQuery("JobSession.deleteTimersForProcessInstance");
query.setParameter("processInstance", processInstance);
- List timers = query.list();
- for (Iterator i = timers.iterator(); i.hasNext();) {
- Timer timer = (Timer) i.next();
- session.delete(timer);
- }
- log.debug(timers.size()+" remaining timers for
'"+processInstance+"' were deleted");
+ int entityCount = query.executeUpdate();
+ log.debug(entityCount+" remaining timers for
'"+processInstance+"' were deleted");
log.debug("deleting execute-node-jobs for process instance
"+processInstance);
- query =
session.getNamedQuery("JobSession.getExecuteNodeJobsForProcessInstance");
+ query =
session.getNamedQuery("JobSession.deleteExecuteNodeJobsForProcessInstance");
query.setParameter("processInstance", processInstance);
- List jobs = query.list();
- for (Iterator i = jobs.iterator(); i.hasNext();) {
- ExecuteNodeJob job = (ExecuteNodeJob) i.next();
- session.delete(job);
- }
- log.debug(jobs.size()+" remaining execute-node-jobs for
'"+processInstance+"' are deleted");
+ entityCount = query.executeUpdate();
+ log.debug(entityCount+" remaining execute-node-jobs for
'"+processInstance+"' are deleted");
}
}
Modified:
jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/job/ExecuteActionJob.java
===================================================================
---
jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/job/ExecuteActionJob.java 2008-07-24
11:06:45 UTC (rev 1702)
+++
jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/job/ExecuteActionJob.java 2008-07-24
11:31:32 UTC (rev 1703)
@@ -34,7 +34,7 @@
action.execute(executionContext);
}
- jbpmContext.save(token);
+ jbpmContext.save(processInstance);
return true;
}
Modified:
jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/job/ExecuteNodeJob.java
===================================================================
---
jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/job/ExecuteNodeJob.java 2008-07-24
11:06:45 UTC (rev 1702)
+++
jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/job/ExecuteNodeJob.java 2008-07-24
11:31:32 UTC (rev 1703)
@@ -25,7 +25,7 @@
token.unlock(this.toString());
ExecutionContext executionContext = new ExecutionContext(token);
node.execute(executionContext);
- jbpmContext.save(token);
+ jbpmContext.save(processInstance);
return true;
}
Modified: jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/job/Timer.java
===================================================================
---
jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/job/Timer.java 2008-07-24
11:06:45 UTC (rev 1702)
+++
jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/job/Timer.java 2008-07-24
11:31:32 UTC (rev 1703)
@@ -35,7 +35,10 @@
}
public boolean execute(JbpmContext jbpmContext) throws Exception {
- boolean deleteThisJob = true;
+ if (processInstance.hasEnded()) {
+ // happens when a repeating timer is blocked at the time the process instance ends
+ return true;
+ }
ExecutionContext executionContext = new ExecutionContext(token);
executionContext.setTimer(this);
@@ -52,7 +55,7 @@
// then execute the action if there is one
if (action!=null) {
try {
- log.debug("executing timer '"+this+"'");
+ log.debug("executing '"+this+"'");
if (graphElement!=null) {
graphElement.executeAction(action, executionContext);
} else {
@@ -61,28 +64,19 @@
} catch (Exception actionException) {
// NOTE that Error's are not caught because that might halt the JVM and mask
the original Error.
log.warn("timer action threw exception", actionException);
-
- // we put the exception in t
- Exception t = actionException;
- try {
- // if there is a graphElement connected to this timer...
- if (graphElement != null) {
+ // if there is a graphElement connected to this timer...
+ if (graphElement != null) {
+ try {
// we give that graphElement a chance to catch the exception
graphElement.raiseException(actionException, executionContext);
log.debug("timer exception got handled by
'"+graphElement+"'");
- t = null;
+ } catch (Exception handlerException) {
+ // if the exception handler rethrows or the original exception results in a
DelegationException...
+ throw handlerException;
}
- } catch (Exception rethrowOrDelegationException) {
- // NOTE that Error's are not caught because that might halt the JVM and
mask the original Error.
- // if the exception handler rethrows or the original exception results in a
DelegationException...
- t = rethrowOrDelegationException;
+ } else {
+ throw actionException;
}
-
- if (t!=null) {
- // This is either the original exception wrapped as a delegation exception
- // or an exception that was throws from an exception handler
- throw t;
- }
}
}
@@ -100,20 +94,17 @@
// if repeat is specified, reschedule the job
if (repeat!=null) {
- deleteThisJob = false;
-
// suppose that it took the timer runner thread a
// very long time to execute the timers.
// then the repeat action dueDate could already have passed.
while (dueDate.getTime()<=System.currentTimeMillis()) {
- dueDate = businessCalendar
- .add(dueDate,
- new Duration(repeat));
+ dueDate = businessCalendar.add(dueDate, new Duration(repeat));
}
- log.debug("updated timer for repetition '"+this+"' in
'"+(dueDate.getTime()-System.currentTimeMillis())+"' millis");
- }
+ log.debug("updated '"+this+"' for repetition on
'"+formatDueDate(dueDate)+"'");
+ return false;
+ }
- return deleteThisJob;
+ return true;
}
public String toString() {
Modified:
jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/job/executor/JobExecutorThread.java
===================================================================
---
jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/job/executor/JobExecutorThread.java 2008-07-24
11:06:45 UTC (rev 1702)
+++
jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/job/executor/JobExecutorThread.java 2008-07-24
11:31:32 UTC (rev 1703)
@@ -2,7 +2,6 @@
import java.io.PrintWriter;
import java.io.StringWriter;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
@@ -19,6 +18,7 @@
import org.jbpm.job.Timer;
import org.jbpm.persistence.JbpmPersistenceException;
import org.jbpm.persistence.db.StaleObjectLogConfigurer;
+import org.jbpm.svc.Services;
public class JobExecutorThread extends Thread {
@@ -48,65 +48,59 @@
volatile boolean isActive = true;
public void run() {
- try {
- currentIdleInterval = idleInterval;
- while (isActive) {
- try {
- Collection acquiredJobs = acquireJobs();
+ currentIdleInterval = idleInterval;
+ while (isActive) {
+ try {
+ Collection acquiredJobs = acquireJobs();
- if (! acquiredJobs.isEmpty()) {
- Iterator iter = acquiredJobs.iterator();
- while (iter.hasNext() && isActive) {
- Job job = (Job) iter.next();
- executeJob(job);
- }
+ if (! acquiredJobs.isEmpty()) {
+ Iterator iter = acquiredJobs.iterator();
+ while (iter.hasNext() && isActive) {
+ Job job = (Job) iter.next();
+ executeJob(job);
+ }
- } else { // no jobs acquired
- if (isActive) {
- long waitPeriod = getWaitPeriod();
- if (waitPeriod>0) {
- synchronized(jobExecutor) {
- jobExecutor.wait(waitPeriod);
- }
+ } else { // no jobs acquired
+ if (isActive) {
+ long waitPeriod = getWaitPeriod();
+ if (waitPeriod>0) {
+ synchronized(jobExecutor) {
+ jobExecutor.wait(waitPeriod);
}
}
}
-
- // no exception so resetting the currentIdleInterval
- currentIdleInterval = idleInterval;
+ }
+
+ // no exception so resetting the currentIdleInterval
+ currentIdleInterval = idleInterval;
- } catch (InterruptedException e) {
- log.info((isActive? "active" : "inactive")+" job
executor thread '"+getName()+"' got interrupted");
- } catch (Exception e) {
- log.error("exception in job executor thread. waiting
"+currentIdleInterval+" milliseconds", e);
- try {
- synchronized(jobExecutor) {
- jobExecutor.wait(currentIdleInterval);
- }
- } catch (InterruptedException e2) {
- log.debug("delay after exception got interrupted", e2);
+ } catch (InterruptedException e) {
+ log.info((isActive? "active" : "inactive")+" job
executor thread '"+getName()+"' got interrupted");
+ } catch (Exception e) {
+ log.error("exception in job executor thread. waiting
"+currentIdleInterval+" milliseconds", e);
+ try {
+ synchronized(jobExecutor) {
+ jobExecutor.wait(currentIdleInterval);
}
- // after an exception, the current idle interval is doubled to prevent
- // continuous exception generation when e.g. the db is unreachable
- currentIdleInterval <<= 1;
- if (currentIdleInterval > maxIdleInterval || currentIdleInterval < 0) {
- currentIdleInterval = maxIdleInterval;
- }
+ } catch (InterruptedException e2) {
+ log.debug("delay after exception got interrupted", e2);
}
+ // after an exception, the current idle interval is doubled to prevent
+ // continuous exception generation when e.g. the db is unreachable
+ currentIdleInterval <<= 1;
+ if (currentIdleInterval > maxIdleInterval || currentIdleInterval < 0) {
+ currentIdleInterval = maxIdleInterval;
+ }
}
- } catch (Exception e) {
- // NOTE that Error's are not caught because that might halt the JVM and mask
the original Error.
- log.error("exception in job executor thread", e);
- } finally {
- log.info(getName()+" leaves cyberspace");
}
+ log.info(getName()+" leaves cyberspace");
}
protected Collection acquireJobs() {
Collection acquiredJobs;
synchronized (jobExecutor) {
- Collection jobsToLock = new ArrayList();
log.debug("acquiring jobs for execution...");
+ Collection jobsToLock = Collections.EMPTY_LIST;
JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
try {
JobSession jobSession = jbpmContext.getJobSession();
@@ -116,11 +110,11 @@
if (job.isExclusive()) {
log.debug("exclusive acquirable job found ("+job+"). querying
for other exclusive jobs to lock them all in one tx...");
List otherExclusiveJobs = jobSession.findExclusiveJobs(getName(),
job.getProcessInstance());
- jobsToLock.addAll(otherExclusiveJobs);
+ jobsToLock = otherExclusiveJobs;
log.debug("trying to obtain a process-instance exclusive locks for
'"+otherExclusiveJobs+"'");
} else {
log.debug("trying to obtain a lock for
'"+job+"'");
- jobsToLock.add(job);
+ jobsToLock = Collections.singletonList(job);
}
Iterator iter = jobsToLock.iterator();
@@ -145,17 +139,13 @@
log.debug("obtained lock on jobs: "+acquiredJobs);
}
catch (JbpmPersistenceException e) {
- // if this is a stale object exception, the jbpm configuration has control over
the logging
- if
("org.hibernate.StaleObjectStateException".equals(e.getCause().getClass().getName()))
{
- log.info("problem committing job acquisition transaction: optimistic
locking failed");
- StaleObjectLogConfigurer.staleObjectExceptionsLog.error("problem
committing job acquisition transaction: optimistic locking failed", e);
+ // if this is a stale object exception, keep it quiet
+ if (Services.isCausedByStaleState(e)) {
+ log.debug("optimistic locking failed, couldn't obtain lock on jobs:
"+jobsToLock);
+ acquiredJobs = Collections.EMPTY_LIST;
} else {
- // TODO run() will log this exception, log it here too?
- log.error("problem committing job acquisition transaction", e);
throw e;
}
- acquiredJobs = Collections.EMPTY_LIST;
- log.debug("couldn't obtain lock on jobs: "+jobsToLock);
}
}
}
@@ -173,7 +163,6 @@
if (job.execute(jbpmContext)) {
jobSession.deleteJob(job);
}
-
} catch (Exception e) {
log.debug("exception while executing '"+job+"'", e);
StringWriter sw = new StringWriter();
@@ -187,7 +176,6 @@
if (totalLockTimeInMillis>maxLockTime) {
jbpmContext.setRollbackOnly();
}
-
} finally {
try {
jbpmContext.close();
Modified:
jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/msg/db/DbMessageService.java
===================================================================
---
jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/msg/db/DbMessageService.java 2008-07-24
11:06:45 UTC (rev 1702)
+++
jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/msg/db/DbMessageService.java 2008-07-24
11:31:32 UTC (rev 1703)
@@ -37,9 +37,8 @@
private static final long serialVersionUID = 1L;
- JbpmConfiguration jbpmConfiguration;
JobSession jobSession = null;
- Collection destinations = null;
+ JobExecutor jobExecutor = null;
boolean hasProducedJobs = false;
public DbMessageService() {
@@ -47,8 +46,8 @@
if (jbpmContext==null) {
throw new JbpmException("instantiation of the DbMessageService requires a
current JbpmContext");
}
- this.jbpmConfiguration = jbpmContext.getJbpmConfiguration();
- this.jobSession = jbpmContext.getJobSession();
+ jobSession = jbpmContext.getJobSession();
+ jobExecutor = jbpmContext.getJbpmConfiguration().getJobExecutor();
}
public void send(Job job) {
@@ -58,11 +57,10 @@
}
public void close() {
- JobExecutor jobExecutor = jbpmConfiguration.getJobExecutor();
if ( (hasProducedJobs)
&& (jobExecutor!=null)
) {
- log.debug("messages were produced the jobExecutor will be signalled");
+ log.debug("messages were produced, job executor will be signalled");
synchronized(jobExecutor) {
jobExecutor.notify();
}
Modified:
jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/scheduler/db/DbSchedulerService.java
===================================================================
---
jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/scheduler/db/DbSchedulerService.java 2008-07-24
11:06:45 UTC (rev 1702)
+++
jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/scheduler/db/DbSchedulerService.java 2008-07-24
11:31:32 UTC (rev 1703)
@@ -21,26 +21,39 @@
*/
package org.jbpm.scheduler.db;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.jbpm.JbpmContext;
import org.jbpm.JbpmException;
import org.jbpm.db.JobSession;
import org.jbpm.graph.exe.ProcessInstance;
import org.jbpm.graph.exe.Token;
import org.jbpm.job.Timer;
+import org.jbpm.job.executor.JobExecutor;
import org.jbpm.scheduler.SchedulerService;
public class DbSchedulerService implements SchedulerService {
private static final long serialVersionUID = 1L;
+
+ private static final Log log = LogFactory.getLog(DbSchedulerService.class);
JobSession jobSession = null;
-
+ JobExecutor jobExecutor = null;
+ boolean hasProducedJobs = false;
+
public DbSchedulerService() {
- this.jobSession = JbpmContext.getCurrentJbpmContext().getJobSession();
+ JbpmContext jbpmContext = JbpmContext.getCurrentJbpmContext();
+ if (jbpmContext==null) {
+ throw new JbpmException("instantiation of the DbSchedulerService requires a
current JbpmContext");
+ }
+ this.jobSession = jbpmContext.getJobSession();
+ this.jobExecutor = jbpmContext.getJbpmConfiguration().getJobExecutor();
}
public void createTimer(Timer timerJob) {
jobSession.saveJob(timerJob);
+ hasProducedJobs = true;
}
public void deleteTimersByName(String timerName, Token token) {
@@ -55,5 +68,11 @@
}
public void close() {
+ if (hasProducedJobs && jobExecutor != null) {
+ log.debug("timers were produced, job executor will be signalled");
+ synchronized (jobExecutor) {
+ jobExecutor.notify();
+ }
+ }
}
}
Modified:
jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/svc/Services.java
===================================================================
---
jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/svc/Services.java 2008-07-24
11:06:45 UTC (rev 1702)
+++
jbpm3/branches/tdiesler/modules/jpdl/core/src/main/java/org/jbpm/svc/Services.java 2008-07-24
11:31:32 UTC (rev 1703)
@@ -31,6 +31,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.hibernate.StaleStateException;
import org.jbpm.JbpmContext;
import org.jbpm.JbpmException;
import org.jbpm.graph.exe.ProcessInstance;
@@ -234,8 +235,8 @@
log.debug("closing service '"+serviceName+"':
"+service);
service.close();
} catch (JbpmPersistenceException e) {
- // if this is a stale object exception, the jbpm configuration has control
over the logging
- if
("org.hibernate.StaleObjectStateException".equals(e.getCause().getClass().getName()))
{
+ // if this is a stale state exception, the jbpm configuration has control
over the logging
+ if (isCausedByStaleState(e)) {
log.info("problem closing service '"+serviceName+"':
optimistic locking failed");
StaleObjectLogConfigurer.staleObjectExceptionsLog.error("problem
closing service '"+serviceName+"': optimistic locking failed", e);
} else {
@@ -263,6 +264,14 @@
}
}
+ public static boolean isCausedByStaleState(JbpmPersistenceException
persistenceException) {
+ for (Throwable cause = persistenceException.getCause(); cause != null; cause =
cause.getCause()) {
+ if (cause instanceof StaleStateException)
+ return true;
+ }
+ return false;
+ }
+
public static void assignId(Object object) {
JbpmContext jbpmContext = JbpmContext.getCurrentJbpmContext();
if (jbpmContext!=null) {
Modified:
jbpm3/branches/tdiesler/modules/jpdl/core/src/main/resources/org/jbpm/db/hibernate.queries.hbm.xml
===================================================================
---
jbpm3/branches/tdiesler/modules/jpdl/core/src/main/resources/org/jbpm/db/hibernate.queries.hbm.xml 2008-07-24
11:06:45 UTC (rev 1702)
+++
jbpm3/branches/tdiesler/modules/jpdl/core/src/main/resources/org/jbpm/db/hibernate.queries.hbm.xml 2008-07-24
11:31:32 UTC (rev 1703)
@@ -314,19 +314,19 @@
]]>
</query>
- <query name="JobSession.getTimersForProcessInstance">
+ <query name="JobSession.deleteTimersForProcessInstance">
<![CDATA[
- select timer
- from org.jbpm.job.Timer timer
+ delete from org.jbpm.job.Timer timer
where timer.processInstance = :processInstance
+ and timer.lockOwner is null
]]>
</query>
- <query name="JobSession.getExecuteNodeJobsForProcessInstance">
+ <query name="JobSession.deleteExecuteNodeJobsForProcessInstance">
<![CDATA[
- select job
- from org.jbpm.job.ExecuteNodeJob job
+ delete from org.jbpm.job.ExecuteNodeJob job
where job.processInstance = :processInstance
+ and job.lockOwner is null
]]>
</query>
Copied:
jbpm3/branches/tdiesler/modules/jpdl/core/src/test/java/org/jbpm/job/executor/TimerOnTimerDbTest.java
(from rev 1558,
jbpm3/trunk/modules/jpdl/core/src/test/java/org/jbpm/job/executor/TimerOnTimerDbTest.java)
===================================================================
---
jbpm3/branches/tdiesler/modules/jpdl/core/src/test/java/org/jbpm/job/executor/TimerOnTimerDbTest.java
(rev 0)
+++
jbpm3/branches/tdiesler/modules/jpdl/core/src/test/java/org/jbpm/job/executor/TimerOnTimerDbTest.java 2008-07-24
11:31:32 UTC (rev 1703)
@@ -0,0 +1,105 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jbpm.job.executor;
+
+import java.io.Serializable;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jbpm.db.AbstractDbTestCase;
+import org.jbpm.graph.def.ProcessDefinition;
+import org.jbpm.graph.exe.ProcessInstance;
+
+/**
+ * Test case for JBPM-1135
+ * @author Alejandro Guizar
+ */
+public class TimerOnTimerDbTest extends AbstractDbTestCase {
+
+ private static final Log log = LogFactory.getLog(TimerOnTimerDbTest.class);
+
+ public void testTimerOnTimer() {
+ ProcessDefinition processDefinition =
ProcessDefinition.parseXmlResource("org/jbpm/job/executor/timerOnTimer.jpdl.xml");
+ jbpmContext.deployProcessDefinition(processDefinition);
+
+ ProcessInstance processInstance =
jbpmContext.newProcessInstanceForUpdate("timerTest");
+ processInstance.getContextInstance().setVariable("timerTestWorkflow", new
WorkflowLogger());
+ processInstance.signal();
+ commitAndCloseSession();
+ long tokenId = processInstance.getRootToken().getId();
+
+ startJobExecutor();
+ try {
+ sleep(500);
+ beginSessionTransaction();
+ assertEquals("timerTest",
jbpmContext.loadToken(tokenId).getNode().getName());
+ commitAndCloseSession();
+
+ sleep(1000);
+ beginSessionTransaction();
+ assertEquals("secondTimerTest",
jbpmContext.loadToken(tokenId).getNode().getName());
+ commitAndCloseSession();
+
+ sleep(1000);
+ beginSessionTransaction();
+ assertTrue(jbpmContext.loadToken(tokenId).getProcessInstance().hasEnded());
+ }
+ finally {
+ stopJobExecutor();
+ }
+ }
+
+ private void sleep(long millis) {
+ try {
+ Thread.sleep(millis);
+ }
+ catch (InterruptedException e) {
+ // reassert interruption
+ Thread.currentThread().interrupt();
+ }
+ }
+
+ public static final class WorkflowLogger implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ public void logNodeEnter() {
+ log.info("entered node");
+ }
+
+ public void logNodeLeave() {
+ log.info("left node");
+ }
+
+ public void logTaskCreate() {
+ log.info("created task");
+ }
+
+ public void logTimerCreate() {
+ log.info("created timer");
+ }
+
+ public void logTimerFired() {
+ log.info("fired timer");
+ }
+ }
+}
Modified: jbpm3/branches/tdiesler/modules/jpdl/core/src/test/resources/log4j.xml
===================================================================
--- jbpm3/branches/tdiesler/modules/jpdl/core/src/test/resources/log4j.xml 2008-07-24
11:06:45 UTC (rev 1702)
+++ jbpm3/branches/tdiesler/modules/jpdl/core/src/test/resources/log4j.xml 2008-07-24
11:31:32 UTC (rev 1703)
@@ -12,7 +12,7 @@
<param name="Append" value="false"/>
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
- <param name="ConversionPattern" value="%d %-5p [%c:%L]
%m%n"/>
+ <param name="ConversionPattern" value="%d %-5p [%c]
%m%n"/>
</layout>
</appender>
@@ -24,7 +24,7 @@
<param name="Target" value="System.out" />
<param name="Threshold" value="INFO" />
<layout class="org.apache.log4j.PatternLayout">
- <param name="ConversionPattern" value="%d{HH:mm:ss,SSS} [%t] %-5p
%C{1} : %m%n" />
+ <param name="ConversionPattern" value="%d{HH:mm:ss,SSS} %-5p
[%c{1}] %m%n" />
</layout>
</appender>
@@ -40,11 +40,17 @@
<priority value="INFO" />
</category>
- <!-- hide optimistic locking failures -->
+ <!-- hide optimistic locking failures
<category
name="org.hibernate.event.def.AbstractFlushingEventListener">
<priority value="FATAL" />
</category>
+ -->
+ <!-- hide proxy narrowing warns -->
+ <category
name="org.hibernate.engine.StatefulPersistenceContext.ProxyWarnLog">
+ <priority value="ERROR" />
+ </category>
+
<!-- show SQL DML statements as they are executed -->
<category name="org.hibernate.SQL">
<priority value="DEBUG" />
Copied:
jbpm3/branches/tdiesler/modules/jpdl/core/src/test/resources/org/jbpm/job/executor/timerOnTimer.jpdl.xml
(from rev 1558,
jbpm3/trunk/modules/jpdl/core/src/test/resources/org/jbpm/job/executor/timerOnTimer.jpdl.xml)
===================================================================
---
jbpm3/branches/tdiesler/modules/jpdl/core/src/test/resources/org/jbpm/job/executor/timerOnTimer.jpdl.xml
(rev 0)
+++
jbpm3/branches/tdiesler/modules/jpdl/core/src/test/resources/org/jbpm/job/executor/timerOnTimer.jpdl.xml 2008-07-24
11:31:32 UTC (rev 1703)
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<process-definition name="timerTest"
xmlns="urn:jbpm.org:jpdl-3.2"
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:jbpm.org:jpdl-3.2
http://jbpm.org/xsd/jpdl-3.2.xsd">
+
+ <start-state name="start">
+ <transition name="" to="timerTest" />
+ </start-state>
+
+ <task-node name="timerTest" end-tasks="true">
+ <event type="node-enter">
+ <action expression="#{timerTestWorkflow.logNodeEnter}" />
+ </event>
+ <event type="node-leave">
+ <action expression="#{timerTestWorkflow.logNodeLeave}" />
+ </event>
+ <transition name="doneFirst" to="secondTimerTest" />
+ <task name="timerTestTask" description="TimerTestTask">
+ <assignment actor-id="admin" />
+ <event type="task-create">
+ <action expression="#{timerTestWorkflow.logTaskCreate}" />
+ </event>
+ <event type="timer-create">
+ <action expression="#{timerTestWorkflow.logTimerCreate}" />
+ </event>
+ <timer duedate="1 second" transition="doneFirst">
+ <action expression="#{timerTestWorkflow.logTimerFired}" />
+ </timer>
+ </task>
+ </task-node>
+
+ <task-node name="secondTimerTest">
+ <task name="secondTimerTestTask"
description="SecondTimerTestTask">
+ <assignment actor-id="admin" />
+ <event type="task-create">
+ <action expression="#{timerTestWorkflow.logTaskCreate}" />
+ </event>
+ <event type="timer-create">
+ <action expression="#{timerTestWorkflow.logTimerCreate}" />
+ </event>
+ <timer duedate="1 second" transition="doneSecond">
+ <action expression="#{timerTestWorkflow.logTimerFired}" />
+ </timer>
+ </task>
+ <transition name="doneSecond" to="end" />
+ </task-node>
+
+ <end-state name="end" />
+
+</process-definition>
\ No newline at end of file
Modified: jbpm3/branches/tdiesler/modules/jpdl/pom.xml
===================================================================
--- jbpm3/branches/tdiesler/modules/jpdl/pom.xml 2008-07-24 11:06:45 UTC (rev 1702)
+++ jbpm3/branches/tdiesler/modules/jpdl/pom.xml 2008-07-24 11:31:32 UTC (rev 1703)
@@ -34,7 +34,6 @@
<module>db</module>
<module>examples</module>
<module>identity</module>
- <module>integration</module>
<module>simulation</module>
<module>userguide</module>
<module>ws</module>