Author: alex.guizar(a)jboss.com
Date: 2010-08-23 23:07:12 -0400 (Mon, 23 Aug 2010)
New Revision: 6622
Added:
jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/extras/jpdl_1.java
Modified:
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/ant/DeployProcessTask.java
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/command/ChangeProcessInstanceVersionCommand.java
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/def/Node.java
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/instantiation/ProcessClassLoader.java
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/resources/org/jbpm/db/hibernate.queries.hbm.xml
jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/command/ChangeProcessInstanceVersionCommandTest.java
jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/jpdl/par/ProcessClassLoaderTest.java
jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/extras/jpdl_1.xmlt
jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/jpdl.xml
Log:
JBPM-2386 update DeployProcessTask description;
improve process instance migration reference and code
Modified:
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/ant/DeployProcessTask.java
===================================================================
---
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/ant/DeployProcessTask.java 2010-08-23
14:14:37 UTC (rev 6621)
+++
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/ant/DeployProcessTask.java 2010-08-24
03:07:12 UTC (rev 6622)
@@ -44,91 +44,98 @@
*/
public class DeployProcessTask extends MatchingTask {
- private String jbpmCfg;
- private File process;
- private List fileSets = new ArrayList();
- private boolean failOnError = true;
+ private String jbpmCfg;
+ private File process;
+ private List fileSets;
+ private boolean failOnError = true;
- public void execute() throws BuildException {
- // get the JbpmConfiguration
- JbpmConfiguration jbpmConfiguration = AntHelper.getJbpmConfiguration(jbpmCfg);
+ public void execute() throws BuildException {
+ // get the JbpmConfiguration
+ JbpmConfiguration jbpmConfiguration = AntHelper.getJbpmConfiguration(jbpmCfg);
- // if attribute process is set, deploy that process file
- if (process != null) {
- handleProcessFile(jbpmConfiguration, process);
- }
+ // if attribute process is set, deploy that process file
+ if (process != null) {
+ handleProcessFile(jbpmConfiguration, process);
+ }
- // iterate over file sets
- for (Iterator iter = fileSets.iterator(); iter.hasNext();) {
- FileSet fileSet = (FileSet) iter.next();
- DirectoryScanner dirScanner = fileSet.getDirectoryScanner(getProject());
- File baseDir = dirScanner.getBasedir();
- String[] includedFiles = dirScanner.getIncludedFiles();
- String[] excludedFiles = dirScanner.getExcludedFiles();
+ // iterate over file sets
+ for (Iterator iter = fileSets.iterator(); iter.hasNext();) {
+ FileSet fileSet = (FileSet) iter.next();
+ DirectoryScanner dirScanner = fileSet.getDirectoryScanner(getProject());
+ File baseDir = dirScanner.getBasedir();
+ String[] includedFiles = dirScanner.getIncludedFiles();
+ String[] excludedFiles = dirScanner.getExcludedFiles();
- for (int i = 0; i < includedFiles.length; i++) {
- String fileName = includedFiles[i];
- if (!ArrayUtil.contains(excludedFiles, fileName)) {
- handleProcessFile(jbpmConfiguration, new File(baseDir, fileName));
- }
- }
- }
- }
+ for (int i = 0; i < includedFiles.length; i++) {
+ String fileName = includedFiles[i];
+ if (!ArrayUtil.contains(excludedFiles, fileName)) {
+ handleProcessFile(jbpmConfiguration, new File(baseDir, fileName));
+ }
+ }
+ }
+ }
- private void handleProcessFile(JbpmConfiguration jbpmConfiguration, File processFile) {
- JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
- try {
- log("parsing process archive: " + processFile);
- ProcessDefinition processDefinition = parseProcessArchive(processFile);
- deployProcessDefinition(processDefinition, jbpmContext);
- }
- catch (IOException e) {
- log("failed to read process archive: " + processFile, e, Project.MSG_ERR);
- if (failOnError) throw new BuildException(e, getLocation());
- }
- finally {
- jbpmContext.close();
- }
- }
+ private void handleProcessFile(JbpmConfiguration jbpmConfiguration, File processFile)
{
+ JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
+ try {
+ ProcessDefinition processDefinition = parseProcessArchive(processFile);
+ deployProcessDefinition(processDefinition, jbpmContext);
+ }
+ catch (IOException e) {
+ if (failOnError) {
+ throw new BuildException("failed to read file " + processFile, e,
getLocation());
+ }
+ else {
+ log("failed to read file " + processFile, e, Project.MSG_ERR);
+ }
+ }
+ finally {
+ jbpmContext.close();
+ }
+ }
- private ProcessDefinition parseProcessArchive(File processFile) throws IOException {
- ZipInputStream processStream = new ZipInputStream(new FileInputStream(processFile));
- try {
- ProcessDefinition processDefinition =
ProcessDefinition.parseParZipInputStream(processStream);
- log("parsed process definition " + processDefinition.getName());
- return processDefinition;
- }
- finally {
- processStream.close();
- }
- }
+ private ProcessDefinition parseProcessArchive(File processFile) throws IOException {
+ log("parsing process archive " + processFile);
+ ZipInputStream processStream = new ZipInputStream(new FileInputStream(processFile));
+ try {
+ return ProcessDefinition.parseParZipInputStream(processStream);
+ }
+ finally {
+ processStream.close();
+ }
+ }
- private void deployProcessDefinition(ProcessDefinition processDefinition,
- JbpmContext jbpmContext) {
- try {
- jbpmContext.deployProcessDefinition(processDefinition);
- log("process definition " + processDefinition.getName() + " deployed
successfully");
- }
- catch (RuntimeException e) {
- jbpmContext.setRollbackOnly();
- log("failed to deploy process " + processDefinition.getName(), e,
Project.MSG_ERR);
- if (failOnError) throw new BuildException(e, getLocation());
- }
- }
+ private void deployProcessDefinition(ProcessDefinition processDefinition,
+ JbpmContext jbpmContext) {
+ log("deploying " + processDefinition);
+ try {
+ jbpmContext.deployProcessDefinition(processDefinition);
+ }
+ catch (RuntimeException e) {
+ jbpmContext.setRollbackOnly();
+ if (failOnError) {
+ throw new BuildException("failed to deploy " + processDefinition, e,
getLocation());
+ }
+ else {
+ log("failed to deploy " + processDefinition, e, Project.MSG_ERR);
+ }
+ }
+ }
- public void addFileset(FileSet fileSet) {
- this.fileSets.add(fileSet);
- }
+ public void addFileset(FileSet fileSet) {
+ if (fileSets == null) fileSets = new ArrayList();
+ fileSets.add(fileSet);
+ }
- public void setJbpmCfg(String jbpmCfg) {
- this.jbpmCfg = jbpmCfg;
- }
+ public void setJbpmCfg(String jbpmCfg) {
+ this.jbpmCfg = jbpmCfg;
+ }
- public void setProcess(File process) {
- this.process = process;
- }
+ public void setProcess(File process) {
+ this.process = process;
+ }
- public void setFailOnError(boolean failOnError) {
- this.failOnError = failOnError;
- }
+ public void setFailOnError(boolean failOnError) {
+ this.failOnError = failOnError;
+ }
}
Modified:
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/command/ChangeProcessInstanceVersionCommand.java
===================================================================
---
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/command/ChangeProcessInstanceVersionCommand.java 2010-08-23
14:14:37 UTC (rev 6621)
+++
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/command/ChangeProcessInstanceVersionCommand.java 2010-08-24
03:07:12 UTC (rev 6622)
@@ -8,12 +8,13 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Query;
-import org.hibernate.Session;
import org.jbpm.JbpmException;
+import org.jbpm.db.GraphSession;
import org.jbpm.graph.def.GraphElement;
import org.jbpm.graph.def.Node;
import org.jbpm.graph.def.ProcessDefinition;
+import org.jbpm.graph.def.Node.NodeType;
import org.jbpm.graph.exe.ProcessInstance;
import org.jbpm.graph.exe.Token;
import org.jbpm.graph.node.ProcessState;
@@ -25,26 +26,25 @@
import org.jbpm.taskmgmt.exe.TaskInstance;
/**
- * <b>THIS COMMAND IS NOT YET STABLE, BUT FEEL FREE TO TEST
:-)</b><br>
- * Status update: Still not complete, but refactored and added simple test
cases.<br>
- * Change the version of a running process instance. This works only, if the current node
is
- * also available in the new version of the process definition or a name mapping has to
be
- * provided.<br>
- * <b>Currently known limitations:</b>
+ * Migrate a process instance to a different version of its process definition.
+ * <p>
+ * Migration works only if the active nodes are also available in the target process
definition
+ * version or a node name mapping is provided.
+ * </p>
+ * <h3>Known limitations</h3>
* <ul>
- * <li> {@link Task}s cannot move "into" another node. If an active
{@link TaskInstance} exists,
- * the {@link Task} definition must exist in the {@link TaskNode} with the same (or
mapped)
- * name. Otherwise the right node cannot be found easily because it may be
ambiguous.</li>
- * <li>Sub processes aren't yet tested. Since the {@link ProcessState} is a
{@link Node} like
+ * <li>{@link Task} definitions cannot move to another node. If an active {@link
TaskInstance}
+ * exists, the {@link Task} definition must exist in the {@link TaskNode} with the same
(or
+ * mapped) name. Otherwise the right node cannot be found easily because it may be
ambiguous.</li>
+ * <li>Subprocesses are not tested yet. Since the {@link ProcessState} is a {@link
Node} like
* any other, it should work anyway.</li>
- * <li>Can have <b>negative impact on referential integrity</b>!
Because one
- * {@link ProcessInstance} can have {@link ProcessLog}s point to old {@link
ProcessDefinition}s.
- * Hence, delete a {@link ProcessDefinition} may not work and throw an Exception
(Integrity
- * constraint violation)</li>
- * <li>In combination with ESB the ESB uses {@link Token}.id <b>and</b>
{@link Node}.id as
- * correlation identifier. After changing the version of a {@link ProcessInstance} the
- * {@link Node} .id has changed, so a signal from ESB will result in an exception and has
to be
- * corrected manually.</li>
+ * <li>Migration can have <b>negative impact on referential
integrity</b> because the
+ * {@link ProcessInstance} may have {@link ProcessLog}s pointing to the old
+ * {@link ProcessDefinition}. Hence, deleting a {@link ProcessDefinition} may not work
and throw
+ * constraint violation exceptions.</li>
+ * <li>The JBoss ESB uses {@link Token}.id <b>and</b> {@link Node}.id
as correlation identifier.
+ * After changing the version of a {@link ProcessInstance} the node identifier has
changed, so a
+ * signal from ESB will result in an exception and has to be corrected
manually.</li>
* </ul>
*
* @author Bernd Ruecker (bernd.ruecker(a)camunda.com)
@@ -52,28 +52,30 @@
public class ChangeProcessInstanceVersionCommand extends
AbstractProcessInstanceBaseCommand {
private static final long serialVersionUID = 2277080393930008224L;
+ private static final Log log =
LogFactory.getLog(ChangeProcessInstanceVersionCommand.class);
/**
- * new version of process, if <=0, the latest process definition is used
+ * new process definition version. if <=0, the latest process definition is used
*/
private int newVersion = -1;
- private static final Log log =
LogFactory.getLog(ChangeProcessInstanceVersionCommand.class);
+ /**
+ * maps node names in the old process definition to node names in the new process
definition.
+ * if there is no entry for a node, the old node name is applied.
+ */
+ private Map nodeNameMapping;
/**
- * the map configures for every node-name in the old process definition (as key) which
- * node-name to use in the new process definition. if a node is not mentioned in this
Map, old
- * node name = new node name is applied
+ * maps task names in the old process definition to tasks names in the new process
definition.
+ * if there is no entry for a task, the old task name is applied.
*/
- private Map nodeNameMapping = new HashMap();
+ private Map taskNameMapping;
- private Map taskNameMapping = new HashMap();
-
public ChangeProcessInstanceVersionCommand() {
}
- public ChangeProcessInstanceVersionCommand(long processId, int newVersion) {
- super.setProcessInstanceId(processId);
+ public ChangeProcessInstanceVersionCommand(long processInstanceId, int newVersion) {
+ super.setProcessInstanceId(processInstanceId);
this.newVersion = newVersion;
}
@@ -81,47 +83,32 @@
return ";newVersion=" + newVersion;
}
- private ProcessDefinition loadNewProcessDefinition(String processName) {
- if (newVersion <= 0)
- return
getJbpmContext().getGraphSession().findLatestProcessDefinition(processName);
- else
- return getJbpmContext().getGraphSession().findProcessDefinition(processName,
newVersion);
+ private ProcessDefinition findNewProcessDefinition(String processName) {
+ GraphSession graphSession = getJbpmContext().getGraphSession();
+ return newVersion <= 0 ? graphSession.findLatestProcessDefinition(processName)
+ : graphSession.findProcessDefinition(processName, newVersion);
}
public ProcessInstance execute(ProcessInstance pi) {
ProcessDefinition oldDef = pi.getProcessDefinition();
- ProcessDefinition newDef = loadNewProcessDefinition(oldDef.getName());
+ ProcessDefinition newDef = findNewProcessDefinition(oldDef.getName());
- if (newDef == null) {
- throw new JbpmException("Process definition " + oldDef.getName() + "
in version "
- + newVersion + " not found.");
- }
-
- if (log.isDebugEnabled()) {
- log.debug("changing " + pi + " from version " +
oldDef.getVersion() + " to new version "
+ boolean debug = log.isDebugEnabled();
+ if (debug) {
+ log.debug("migrating " + pi + " from version " +
oldDef.getVersion() + " to "
+ newDef.getVersion());
}
pi.setProcessDefinition(newDef);
changeTokenVersion(pi.getRootToken());
- if (log.isDebugEnabled()) {
- log.debug(pi + " changed to version " + newDef.getVersion());
- }
+ if (debug) log.debug(pi + " migrated to version " + newDef.getVersion());
return pi;
}
- private ProcessDefinition getNewProcessDefinition(Token t) {
- return t.getProcessInstance().getProcessDefinition();
- }
-
private void changeTokenVersion(Token token) {
- ProcessDefinition newDef = getNewProcessDefinition(token);
- if (log.isDebugEnabled()) {
- log.debug("changing " + token + " to version " +
newDef.getVersion());
- }
-
// change node reference on token (current node)
Node oldNode = token.getNode();
+ ProcessDefinition newDef = token.getProcessInstance().getProcessDefinition();
Node newNode = findReplacementNode(newDef, oldNode);
token.setNode(newNode);
@@ -141,7 +128,7 @@
}
private void adjustTaskInstancesForToken(Token token) {
- ProcessDefinition newDef = getNewProcessDefinition(token);
+ ProcessDefinition newDef = token.getProcessInstance().getProcessDefinition();
boolean debug = log.isDebugEnabled();
for (Iterator i = getTasksForToken(token).iterator(); i.hasNext();) {
@@ -158,7 +145,7 @@
}
private void adjustTimersForToken(Token token) {
- ProcessDefinition newDef = getNewProcessDefinition(token);
+ ProcessDefinition newDef = token.getProcessInstance().getProcessDefinition();
List jobs = getJbpmContext().getJobSession().findJobsByToken(token);
for (Iterator i = jobs.iterator(); i.hasNext();) {
Job job = (Job) i.next();
@@ -166,7 +153,6 @@
// check all timers if connected to a GraphElement
Timer timer = (Timer) job;
if (timer.getGraphElement() != null) {
-
// and change the reference (take name mappings into account!)
if (timer.getGraphElement() instanceof Task) {
// change to new task definition
@@ -177,7 +163,7 @@
else {
// change to new node
GraphElement oldNode = timer.getGraphElement();
- // TODO: What with other GraphElements?
+ // TODO: What about other GraphElements?
timer.setGraphElement(findReplacementNode(newDef, oldNode));
}
}
@@ -189,47 +175,58 @@
String name = getReplacementNodeName(oldNode);
Node newNode = newDef.findNode(name);
if (newNode == null) {
- throw new JbpmException("node with name '" + name
- + "' not found in new process definition");
+ throw new JbpmException("could not find node '" + name + "'
in " + newDef);
}
return newNode;
}
private Task findReplacementTask(ProcessDefinition newDef, Node oldNode, Task oldTask)
{
- String replacementTaskName = getReplacementTaskName(oldTask);
- Node newTaskNode = findReplacementNode(newDef, oldNode);
+ Node newNode = findReplacementNode(newDef, oldNode);
+ if (newNode.getNodeType() != NodeType.Task) {
+ throw new JbpmException("expected" + newNode + " to be a task
node");
+ }
- Session session = getJbpmContext().getSession();
- Long newTaskId = (Long)
session.getNamedQuery("TaskMgmtSession.findTaskForNode")
- .setString("taskName", replacementTaskName)
- .setLong("taskNodeId", newTaskNode.getId())
- .uniqueResult();
+ TaskNode newTaskNode;
+ if (newNode instanceof TaskNode) {
+ newTaskNode = (TaskNode) newNode;
+ }
+ else {
+ // acquire proxy of the proper type
+ newTaskNode = (TaskNode) getJbpmContext().getSession().load(TaskNode.class,
+ new Long(newNode.getId()));
+ }
- if (newTaskId == null) {
- throw new JbpmException("Task '" + replacementTaskName + "'
for node '"
- + newTaskNode.getName() + "' not found in new process
definition");
+ String newTaskName = getReplacementTaskName(oldTask);
+ Task newTask = newTaskNode.getTask(newTaskName);
+
+ if (newTask == null) {
+ throw new JbpmException("could not find task '" + newTaskName +
"' for node '"
+ + newTaskNode.getName() + "' in " + newDef);
}
- return (Task) session.load(Task.class, newTaskId);
+ return newTask;
}
/**
- * @param oldNode
- * @return the name of the new node (given in the map or return default value, which is
the
- * old node name)
+ * @return the name of the replacement node, if one is given in the node name mapping,
or the
+ * old node name
*/
private String getReplacementNodeName(GraphElement oldNode) {
String oldName = oldNode instanceof Node ? ((Node) oldNode).getFullyQualifiedName()
: oldNode.getName();
- if (nodeNameMapping.containsKey(oldName)) {
+ if (nodeNameMapping != null && nodeNameMapping.containsKey(oldName)) {
return (String) nodeNameMapping.get(oldName);
}
// return new node name = old node name as default
return oldName;
}
+ /**
+ * @return the name of the replacement task, if one is given in the task name mapping,
or the
+ * old task name
+ */
private String getReplacementTaskName(Task oldTask) {
String oldName = oldTask.getName();
- if (taskNameMapping.containsKey(oldName)) {
+ if (taskNameMapping != null && taskNameMapping.containsKey(oldName)) {
return (String) taskNameMapping.get(oldName);
}
// return new node name = old node name as default
@@ -237,7 +234,7 @@
}
/**
- * We may still have open tasks, even though their parent tokens have been ended. So
we'll
+ * There may still be open tasks, even though their parent tokens have been ended. So
we'll
* simply get all tasks from this process instance and cancel them if they are still
active.
*/
private List getTasksForToken(Token token) {
@@ -245,7 +242,6 @@
.getNamedQuery("TaskMgmtSession.findTaskInstancesByTokenId");
query.setLong("tokenId", token.getId());
return query.list();
-
}
public Map getNodeNameMapping() {
@@ -253,12 +249,7 @@
}
public void setNodeNameMapping(Map nameMapping) {
- if (nameMapping == null) {
- this.nodeNameMapping = new HashMap();
- }
- else {
- this.nodeNameMapping = nameMapping;
- }
+ nodeNameMapping = nameMapping;
}
public int getNewVersion() {
@@ -274,12 +265,7 @@
}
public void setTaskNameMapping(Map nameMapping) {
- if (nameMapping == null) {
- this.taskNameMapping = new HashMap();
- }
- else {
- this.taskNameMapping = nameMapping;
- }
+ taskNameMapping = nameMapping;
}
/**
@@ -332,21 +318,15 @@
public ChangeProcessInstanceVersionCommand nodeNameMappingAdd(String oldNodeName,
String newNodeName) {
- if (nodeNameMapping == null) {
- this.nodeNameMapping = new HashMap();
- }
-
- this.nodeNameMapping.put(oldNodeName, newNodeName);
+ if (nodeNameMapping == null) nodeNameMapping = new HashMap();
+ nodeNameMapping.put(oldNodeName, newNodeName);
return this;
}
public ChangeProcessInstanceVersionCommand taskNameMappingAdd(String oldTaskName,
String newNodeName) {
- if (taskNameMapping == null) {
- this.taskNameMapping = new HashMap();
- }
-
- this.taskNameMapping.put(oldTaskName, newNodeName);
+ if (taskNameMapping == null) taskNameMapping = new HashMap();
+ taskNameMapping.put(oldTaskName, newNodeName);
return this;
}
}
Modified:
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/def/Node.java
===================================================================
---
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/def/Node.java 2010-08-23
14:14:37 UTC (rev 6621)
+++
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/def/Node.java 2010-08-24
03:07:12 UTC (rev 6622)
@@ -100,9 +100,9 @@
return NodeType.Node;
}
- /** @deprecated not in use */
+ /** @deprecated no use for this method */
public String getNameExt() {
- String name = super.getName();
+ String name = getName();
if (name == null) name = "#anonymous" + getNodeType();
return name;
}
Modified:
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/instantiation/ProcessClassLoader.java
===================================================================
---
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/instantiation/ProcessClassLoader.java 2010-08-23
14:14:37 UTC (rev 6621)
+++
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/instantiation/ProcessClassLoader.java 2010-08-24
03:07:12 UTC (rev 6622)
@@ -22,6 +22,7 @@
package org.jbpm.instantiation;
import java.io.ByteArrayInputStream;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
@@ -38,7 +39,39 @@
private ProcessDefinition processDefinition;
private long processDefinitionId;
+ private final URLStreamHandler urlStreamHandler = new URLStreamHandler() {
+ protected URLConnection openConnection(URL url) throws IOException {
+ return new URLConnection(url) {
+ private FileDefinition fileDefinition;
+
+ public void connect() throws IOException {
+ if (connected) return;
+
+ ProcessDefinition processDefinition = getProcessDefinition();
+ if (processDefinition == null) {
+ throw new IOException("no active jbpm context");
+ }
+ fileDefinition = processDefinition.getFileDefinition();
+
+ connected = true;
+ }
+
+ public InputStream getInputStream() throws IOException {
+ connect();
+
+ String fileName = url.getFile();
+ byte[] fileContent = fileDefinition.getBytes(fileName);
+ if (fileContent == null) {
+ throw new FileNotFoundException(fileName);
+ }
+
+ return new ByteArrayInputStream(fileContent);
+ }
+ };
+ }
+ };
+
public ProcessClassLoader(ClassLoader parent, ProcessDefinition processDefinition) {
super(parent);
// check whether the given process definition is transient
@@ -87,18 +120,17 @@
name = "classes/" + name;
}
- byte[] bytes = fileDefinition.getBytes(name);
- if (bytes == null) return null;
+ if (!fileDefinition.hasFile(name)) return null;
try {
- return new URL("processresource", processDefinition.getName(), -1,
"classes/" + name,
- new BytesUrlStreamHandler(bytes));
+ return new URL("processresource", null, -1, name, urlStreamHandler);
}
catch (MalformedURLException e) {
throw new JbpmException("could not create url", e);
}
}
+ /** @deprecated */
public static class BytesUrlStreamHandler extends URLStreamHandler {
private byte[] bytes;
@@ -112,6 +144,7 @@
}
}
+ /** @deprecated */
public static class BytesUrlConnection extends URLConnection {
private byte[] bytes;
@@ -151,8 +184,14 @@
if (getPackage(packageName) == null) {
Package jbpmPackage = ProcessClassLoader.class.getPackage();
- definePackage(packageName, null, null, null,
jbpmPackage.getImplementationTitle(),
- jbpmPackage.getImplementationVersion(), jbpmPackage.getImplementationVendor(),
null);
+ definePackage(packageName,
+ null,
+ null,
+ null,
+ jbpmPackage.getImplementationTitle(),
+ jbpmPackage.getImplementationVersion(),
+ jbpmPackage.getImplementationVendor(),
+ null);
}
}
return defineClass(className, classBytes, 0, classBytes.length);
Modified:
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/resources/org/jbpm/db/hibernate.queries.hbm.xml
===================================================================
---
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/resources/org/jbpm/db/hibernate.queries.hbm.xml 2010-08-23
14:14:37 UTC (rev 6621)
+++
jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/resources/org/jbpm/db/hibernate.queries.hbm.xml 2010-08-24
03:07:12 UTC (rev 6622)
@@ -462,13 +462,4 @@
]]>
</query>
- <query name="TaskMgmtSession.findTaskForNode">
- <![CDATA[
- select distinct t.id
- from org.jbpm.taskmgmt.def.Task t
- where t.name = :taskName
- and t.taskNode.id = :taskNodeId
- ]]>
- </query>
-
</hibernate-mapping>
Modified:
jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/command/ChangeProcessInstanceVersionCommandTest.java
===================================================================
---
jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/command/ChangeProcessInstanceVersionCommandTest.java 2010-08-23
14:14:37 UTC (rev 6621)
+++
jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/command/ChangeProcessInstanceVersionCommandTest.java 2010-08-24
03:07:12 UTC (rev 6622)
@@ -32,16 +32,17 @@
// ProcessInstance is deleted
// exceptions look like this: could not delete: [org.jbpm.graph.def.Transition#9]
- // Integrity constraint violation FK_LOG_TRANSITION table: JBPM_LOG in statement [/*
delete org.jbpm.graph.def.Transition */ delete from JBPM_TRANSITION where ID_=?]
- // or hibernate batch failed
+ // Integrity constraint violation FK_LOG_TRANSITION table: JBPM_LOG in statement
+ // [delete from JBPM_TRANSITION where ID_=?]
// IMPORTANT: Keep this order of deletions! Otherwise if there is
// more than one ProcessInstance for the ProcessDefinition a HibernateSeassion.flush
- // is called when queriing the seconf ProcessInstance after deleting the first
- // one which may fire a Integrity constraint violation (same problem as described
+ // is called when querying the second ProcessInstance after deleting the first
+ // one which may fire an integrity constraint violation (same problem as described
// above), in this case I got
// could not delete: [org.jbpm.taskmgmt.def.TaskMgmtDefinition#2]
- // Integrity constraint violation FK_TASKMGTINST_TMD table: JBPM_MODULEINSTANCE in
statement [/* delete org.jbpm.taskmgmt.def.TaskMgmtDefinition */ delete from
JBPM_MODULEDEFINITION where ID_=?]
+ // Integrity constraint violation FK_TASKMGTINST_TMD table: JBPM_MODULEINSTANCE in
statement
+ // [delete from JBPM_MODULEDEFINITION where ID_=?]
graphSession.deleteProcessDefinition(pd2.getId());
graphSession.deleteProcessDefinition(pd1.getId());
@@ -95,20 +96,18 @@
// now change all process instances to most current version
try {
- new
ChangeProcessInstanceVersionCommand().processName("TestChangeVersion").execute(
- jbpmContext);
+ new
ChangeProcessInstanceVersionCommand().processName("TestChangeVersion")
+ .execute(jbpmContext);
fail("Exception expected, saying that state2 is missing in new
version");
}
catch (JbpmException ex) {
- assertEquals("node with name 'state2' not found in new process
definition",
- ex.getMessage());
+ assert ex.getMessage().indexOf("state2") != -1 : ex.getMessage();
}
- HashMap nameMap = new HashMap();
- nameMap.put("state2", "state2b");
// now supply a mapping for the missing node
- new ChangeProcessInstanceVersionCommand().nodeNameMapping(nameMap).processName(
- "TestChangeVersion").execute(jbpmContext);
+ new ChangeProcessInstanceVersionCommand().nodeNameMappingAdd("state2",
"state2b")
+ .processName("TestChangeVersion")
+ .execute(jbpmContext);
newTransaction();
pi1 = graphSession.loadProcessInstance(pi1.getId());
@@ -192,20 +191,18 @@
// now change all process instances to most current version
try {
- new ChangeProcessInstanceVersionCommand().processInstanceId(pi1.getId()).execute(
- jbpmContext);
- fail("Exception expected, saying that phase2 is missing in new
version");
+ new ChangeProcessInstanceVersionCommand().processInstanceId(pi1.getId())
+ .execute(jbpmContext);
+ fail("Exception expected, saying that path2 is missing in new version");
}
catch (JbpmException ex) {
- assertEquals("node with name 'path2' not found in new process
definition",
- ex.getMessage());
+ assert ex.getMessage().indexOf("path2") != -1 : ex.getMessage();
}
- HashMap nameMap = new HashMap();
- nameMap.put("path2", "path2b");
// now supply a mapping for the missing node
- new
ChangeProcessInstanceVersionCommand().nodeNameMapping(nameMap).processInstanceId(
- pi1.getId()).execute(jbpmContext);
+ new ChangeProcessInstanceVersionCommand().nodeNameMappingAdd("path2",
"path2b")
+ .processInstanceId(pi1.getId())
+ .execute(jbpmContext);
newTransaction();
@@ -289,8 +286,10 @@
taskNameMap.put("theTask2", "theTask2b");
// now supply a mapping for the missing node
- new
ChangeProcessInstanceVersionCommand().nodeNameMapping(nodeNameMap).taskNameMapping(
- taskNameMap).processInstanceId(pi1.getId()).execute(jbpmContext);
+ new ChangeProcessInstanceVersionCommand().nodeNameMapping(nodeNameMap)
+ .taskNameMapping(taskNameMap)
+ .processInstanceId(pi1.getId())
+ .execute(jbpmContext);
newTransaction();
@@ -390,28 +389,24 @@
jbpmContext.deployProcessDefinition(pd2);
// process instance 1 can be updated, state names haven't changed
- new ChangeProcessInstanceVersionCommand().processInstanceId(pi1.getId()).execute(
- jbpmContext);
+ new ChangeProcessInstanceVersionCommand().processInstanceId(pi1.getId())
+ .execute(jbpmContext);
- HashMap nameMap = new HashMap();
- nameMap.put("task2", "task2b");
-
// now change all process instances to most current version
try {
- new
ChangeProcessInstanceVersionCommand().nodeNameMapping(nameMap).taskNameMapping(
- nameMap).processName("testTaskInstances").execute(jbpmContext);
+ new ChangeProcessInstanceVersionCommand().nodeNameMappingAdd("task2",
"task2b")
+ .processName("testTaskInstances")
+ .execute(jbpmContext);
// fail because task2 is not mapped
- fail("Exception expected, saying that theTask2b is missing in new
version");
+ fail("Exception expected, saying that theTask2 is missing in new
version");
}
catch (JbpmException ex) {
- assertEquals("Task 'theTask2' for node 'task2b' not found in
new process definition",
- ex.getMessage());
+ assert ex.getMessage().indexOf("theTask2") != -1 : ex.getMessage();
}
// now supply a mapping for the missing task
- nameMap.put("theTask2", "theTask2b");
- new ChangeProcessInstanceVersionCommand().nodeNameMapping(nameMap)
- .taskNameMapping(nameMap)
+ new ChangeProcessInstanceVersionCommand().nodeNameMappingAdd("task2",
"task2b")
+ .taskNameMappingAdd("theTask2", "theTask2b")
.processName("testTaskInstances")
.execute(jbpmContext);
@@ -492,8 +487,9 @@
// change version
HashMap nameMap = new HashMap();
nameMap.put("timer1", "timer2");
- new
ChangeProcessInstanceVersionCommand().nodeNameMapping(nameMap).processInstanceId(
- pi1.getId()).execute(jbpmContext);
+ new ChangeProcessInstanceVersionCommand().nodeNameMapping(nameMap)
+ .processInstanceId(pi1.getId())
+ .execute(jbpmContext);
// load changed stuff
newTransaction();
Modified:
jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/jpdl/par/ProcessClassLoaderTest.java
===================================================================
---
jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/jpdl/par/ProcessClassLoaderTest.java 2010-08-23
14:14:37 UTC (rev 6621)
+++
jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/jpdl/par/ProcessClassLoaderTest.java 2010-08-24
03:07:12 UTC (rev 6622)
@@ -21,9 +21,9 @@
*/
public class ProcessClassLoaderTest extends AbstractJbpmTestCase {
- public static class TestContextClassLoader extends ClassLoader {
+ public static class TestClassLoader extends ClassLoader {
- public TestContextClassLoader(ClassLoader parent) {
+ public TestClassLoader(ClassLoader parent) {
super(parent);
}
}
@@ -85,10 +85,10 @@
ClassLoader processClassLoader = Thread.currentThread().getContextClassLoader();
assertSame(ProcessClassLoader.class, processClassLoader.getClass());
- ClassLoader testContextClassLoader = processClassLoader.getParent();
- assertSame(TestContextClassLoader.class, testContextClassLoader.getClass());
+ ClassLoader testClassLoader = processClassLoader.getParent();
+ assertSame(TestClassLoader.class, testClassLoader.getClass());
- assertSame(originalClassLoader, testContextClassLoader.getParent());
+ assertSame(originalClassLoader, testClassLoader.getParent());
contextLoadedActionInvocations++;
}
}
@@ -105,9 +105,8 @@
JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
try {
- TestContextClassLoader testContextClassLoader = new TestContextClassLoader(
- originalClassLoader);
- Thread.currentThread().setContextClassLoader(testContextClassLoader);
+ ClassLoader testClassLoader = new TestClassLoader(originalClassLoader);
+ Thread.currentThread().setContextClassLoader(testClassLoader);
ProcessDefinition processDefinition =
ProcessDefinition.parseXmlString("<process-definition>"
+ " <start-state name='start'>"
@@ -127,8 +126,7 @@
processInstance.signal();
assertEquals(1, contextLoadedActionInvocations);
- assertSame(testContextClassLoader,
Thread.currentThread().getContextClassLoader());
-
+ assertSame(testClassLoader, Thread.currentThread().getContextClassLoader());
}
finally {
Thread.currentThread().setContextClassLoader(originalClassLoader);
@@ -150,10 +148,10 @@
ClassLoader processClassLoader = Thread.currentThread().getContextClassLoader();
assertSame(ProcessClassLoader.class, processClassLoader.getClass());
- ClassLoader testContextClassLoader = processClassLoader.getParent();
- assertSame(TestContextClassLoader.class, testContextClassLoader.getClass());
+ ClassLoader testClassLoader = processClassLoader.getParent();
+ assertSame(TestClassLoader.class, testClassLoader.getClass());
- assertSame(originalClassLoader, testContextClassLoader.getParent());
+ assertSame(originalClassLoader, testClassLoader.getParent());
contextLoadedActionInvocations++;
throw new JbpmException("simulate exception");
@@ -166,10 +164,9 @@
+ "</jbpm-configuration>");
JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
- TestContextClassLoader testContextClassLoader = new TestContextClassLoader(
- originalClassLoader);
+ ClassLoader testClassLoader = new TestClassLoader(originalClassLoader);
try {
- Thread.currentThread().setContextClassLoader(testContextClassLoader);
+ Thread.currentThread().setContextClassLoader(testClassLoader);
ProcessDefinition processDefinition =
ProcessDefinition.parseXmlString("<process-definition>"
+ " <start-state name='start'>"
@@ -191,7 +188,7 @@
catch (JbpmException ex) {
assertEquals(1, contextLoadedActionInvocations);
assertEquals("simulate exception", ex.getMessage());
- assertSame(testContextClassLoader,
Thread.currentThread().getContextClassLoader());
+ assertSame(testClassLoader, Thread.currentThread().getContextClassLoader());
}
finally {
Thread.currentThread().setContextClassLoader(originalClassLoader);
Added:
jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/extras/jpdl_1.java
===================================================================
---
jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/extras/jpdl_1.java
(rev 0)
+++
jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/extras/jpdl_1.java 2010-08-24
03:07:12 UTC (rev 6622)
@@ -0,0 +1,4 @@
+new ChangeProcessInstanceVersionCommand()
+ .processName("commute")
+ .nodeNameMappingAdd("drive to destination", "ride bike to
destination")
+ .execute(jbpmContext);
\ No newline at end of file
Property changes on:
jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/extras/jpdl_1.java
___________________________________________________________________
Name: svn:eol-style
+ native
Modified:
jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/extras/jpdl_1.xmlt
===================================================================
---
jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/extras/jpdl_1.xmlt 2010-08-23
14:14:37 UTC (rev 6621)
+++
jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/extras/jpdl_1.xmlt 2010-08-24
03:07:12 UTC (rev 6622)
@@ -1,6 +1,6 @@
-<target name="deploy.par">
- <taskdef name="deploypar"
classname="org.jbpm.ant.DeployProcessTask">
- <classpath --make sure the jbpm-[version].jar is in this classpath--/>
+<target name="deploy-process">
+ <taskdef name="deployproc"
classname="org.jbpm.ant.DeployProcessTask">
+ <classpath location="jbpm-jpdl.jar" />
</taskdef>
- <deploypar par="build/myprocess.par" />
+ <deployproc process="build/myprocess.par" />
</target>
\ No newline at end of file
Modified: jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/jpdl.xml
===================================================================
---
jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/jpdl.xml 2010-08-23
14:14:37 UTC (rev 6621)
+++
jbpm3/branches/jbpm-3.2-soa/modules/userguide/src/main/docbook/en-US/jpdl.xml 2010-08-24
03:07:12 UTC (rev 6622)
@@ -6,28 +6,31 @@
<chapter id="jpdl">
<title>
- The jBPM Process Definition Language
+ jBPM Process Definition Language
</title>
<para>
- The <firstterm>jBPM Process Definition Language</firstterm> (JPDL)
- specifies both an XML schema and the mechanism through which to
- package all of the process definition-related files into a
- <firstterm>process archive</firstterm>.
+ The <firstterm>jBPM Process Definition Language</firstterm> (jPDL)
+ is the notation to define business processes recognized by the
+ jBPM framework and expressed as an XML schema.
+ Process definitions often require support files in addition to the
+ jPDL document. All these files are packaged into a
+ <firstterm>process archive</firstterm> for deployment.
</para>
- <section id="theprocessarchive">
+ <section id="processarchive">
<title>
- The Process Archive
+ Process Archive
</title>
<para>
- A process archive is a ZIP archive. The central file it contains is
- called <filename>processdefinition.xml</filename>. The main thing
- held within this file is the process graph. (It also contains
- information about actions and tasks.) A process archive can also
- contain other process-related files, such as classes and the user
- interface forms needed by tasks.
+ The process archive is just a ZIP archive with a specific content
+ layout. The central file in the process archive is
+ called <filename>processdefinition.xml</filename> This file defines
+ the business process in the jPDL notation and provides
+ information about automated actions and human tasks.
+ The process archive also contains other files related to the process,
+ such as action handler classes and user interface task forms.
</para>
<section id="deployingaprocessarchive">
@@ -53,7 +56,6 @@
</para>
</listitem>
-
<listitem>
<para>
programatically
@@ -62,108 +64,83 @@
</itemizedlist>
-
-
<para>
- To deploying a process archive with the <application>Process
- Designer Tool</application>, follow this step. (This process is
- supported in the <systemitem>starter's kit</systemitem>.)
+ To deploy a process archive with the <application>Process
+ Designer Tool</application>, right-click on the process
+ archive folder and select the <guimenuitem>Deploy process
+ archive</guimenuitem> option.
</para>
- <orderedlist>
- <listitem>
- <para>
- Right-click on the process archive folder and select
- the <guimenuitem>Deploy process archive</guimenuitem>
- option.
- </para>
-
- <para>
- The <systemitem>starter's kit</systemitem>
- server contains the <application>jBPM</application>
- application, which has a servlet to upload process
- archives, called
- <systemitem>ProcessUploadServlet</systemitem>. This
- servlet is capable of uploading process archives and
- deploying them to the default
- <application>jBPM</application> instance.
- </para>
- </listitem>
-
- </orderedlist>
+ <para>
+ The jBPM application server integration modules
+ include the <application>gpd-deployer</application>
+ web application, which has a servlet to upload process
+ archives, called
+ <systemitem>GPD Deployer Servlet</systemitem>. This
+ servlet is capable of receiving process archives and
+ deploying them to the configured database.
+ </para>
<para>
To deploy a process archive with an <command>ant</command>
- task, use this code:
+ task, define and call the task as follows.
</para>
<programlisting language="XML"><xi:include
href="extras/jpdl_1.xmlt" parse="text"
xmlns:xi="http://www.w3.org/2001/XInclude" /></programlisting>
<para>
- To deploy more process archives at once, use the nested
- <property>fileset</property> elements. The process attribute
- itself is optional. Here are some of the <command>ant</command>
- task's other attributes:
+ To deploy more process archives at once, use nested
+ <property>fileset</property> elements.
+ Here are the <classname>DeployProcessTask</classname>
attributes.
</para>
<table>
- <title>ant Attributes</title>
+ <title><classname>DeployProcessTask</classname>
Attributes</title>
<tgroup cols="3" colsep="1" rowsep="1">
- <colspec colwidth="2*"/>
- <colspec colwidth="5*"/>
- <colspec colwidth="2*"/>
+ <colspec colwidth="*"/>
+ <colspec colwidth="3*"/>
+ <colspec colwidth="*"/>
<thead>
<row><entry>Attribute</entry><entry>Description</entry><entry>Required?</entry></row>
</thead>
<tbody>
<row>
+ <entry><property>process</property></entry>
+ <entry><para>Path to process archive.</para></entry>
+ <entry><para>Yes, unless a nested resource collection element is
used.</para></entry>
+ </row>
+ <row>
<entry>
<property>jbpmcfg</property>
</entry>
<entry>
<para>
- The default value is <filename>jbpm.cfg.xml</filename>.
The JBPM
- configuration file can specify the location of the Hibernate
configuration file
- (default value is <filename>hibernate.cfg.xml</filename>)
that contains the
- JDBC connection properties for the database and the mapping files.
+ jBPM configuration resource to load during deployment.
</para>
</entry>
- <entry>No</entry>
+ <entry><para>No; defaults to
<filename>jbpm.cfg.xml</filename></para></entry>
</row>
<row>
<entry>
- <property>properties</property>
+ <property>failonerror</property>
</entry>
<entry>
<para>
- Overwrites all. Hibernate properties as found in
- the <filename>hibernate.cfg.xml</filename> file.
+ If false, log a warning message, but do not stop the build,
+ when the process definition fails to deploy.
</para>
</entry>
- <entry>No</entry>
+ <entry>No; defaults to true</entry>
</row>
-
- <row>
- <entry>
- <property>createschema</property>
- </entry>
- <entry>
- <para>
- When set to <code>true</code>, the jBPM database
- schema is created before any processes are deployed.
- </para>
- </entry>
- <entry>No</entry>
- </row>
</tbody></tgroup>
</table>
<para>
- To deploy process archives programmatically, use the
- <classname>org.jbpm.jpdl.par.ProcessArchiveDeployer</classname>
- class.
+ To deploy process archives programmatically, call the
+ <classname>org.jbpm.JbpmContext</classname>
+ class' <methodname>deployProcessDefinition</methodname>
method.
</para>
</section>
@@ -210,9 +187,8 @@
<para>
To do so, put the delegation
- classes in a <filename>.JAR</filename> file "next
to" the
- <filename>jbpm-[version].jar</filename> so
- that
+ classes in a <filename>.jar</filename> file "next
to"
+ <filename>jbpm-jpdl.jar</filename> so that
all of the process definitions will see that class
file. The Java classes can also be included in the
process archive. When you include your delegation
@@ -252,31 +228,35 @@
<warning>
<para>
- It is dangerous to change process definitions after they are
- deployed. Red Hat discourages this process. It is better to
- migrate process instances to new definitions.
+ Changing process definitions after they are deployed is not
+ a recommended practice. It is better to migrate process instances
+ to a new version of the process definition.
</para>
</warning>
-
-
<para>
- Consider these factors before undertaking this process:
+ Consider these factors before undertaking this process:
</para>
<itemizedlist>
<listitem>
<para>
- one can simply load a process definition, change it and save it
- with the <application>Hibernate</application> session. (Access
- the <application>Hibernate</application> session via the
- <methodname>JbpmContext.getSession()</methodname> method.)
+ There is no restriction on updating a process definition
+ loaded through the
<classname>org.jbpm.db.GraphSession</classname>
+ methods <methodname>loadProcessDefinition</methodname>,
+ <methodname>findProcessDefinition</methodname> or reached
+ through association traversal. Nonetheless, it is
+ <emphasis>very</emphasis> easy to mess up the process
+ with a few calls such as <code>setStartState(null)</code>!
</para>
</listitem>
<listitem>
<para>
- one must remove a process definition from the second level
- cache after having updated the existing definition.
+ Because processs definitions are not supposed to change,
+ the shipped Hibernate configuration specifies the
+ <code>nonstrict-read-write</code> caching strategy for
+ definition classes and collections. This strategy can make
+ uncommitted updates visible to other transactions.
</para>
</listitem>
</itemizedlist>
@@ -289,33 +269,39 @@
</title>
<para>
- An alternative approach is to convert the executions to a new process
definition.
- Please take into account that this is not trivial due to the
+ An alternative approach to changing a process definition
+ is to migrate each process instance to a new version.
+ Please consider that migration is not trivial due to the
long-lived nature of business processes.
</para>
<note>
<para>
- Currently, this is an experimental feature and is not supported
- "out-of-the-box."
+ This is an experimental feature.
</para>
</note>
<para>
- There is a clear distinction between process definition
- data, process instance (run-time) data and logging data.
- Because of this distinction, one creates a separate process
- definition in the jBPM database (by, for example, deploying
- a new version of the same process) and then the run-time
- information is transformed into the new process definition.
- (This will involve a translation if tokens in the old
- process point to nodes that have been removed in the new
- version.) Hence, only new data is added to the database.
- Note, though, that one execution of a process is spread over
- two process instance objects. This can present challenges
- when developing tools and making statistics calculations.
- When resources permit, Red Hat will add support for this.
+ There is a clear distinction between definition data,
+ execution data and logging data.
+ Because of this distinction, a new version of the process
+ has to be deployed first, and then process instances
+ are migrated to the new version.
+ Migration involves a translation if tokens or task instances
+ point to nodes or task definitions that have been removed
+ in the target process definition.
+ Be aware that logging data ends up spread over two
+ process definitions. This can present challenges
+ when developing tools and making statistics calculations.
</para>
+
+ <para>
+ To migrate a process instance to a new version, execute the
+ <classname>ChangeProcessInstanceVersionCommand</classname>
+ as shown below.
+ </para>
+
+ <programlisting><xi:include href="extras/jpdl_1.java"
parse="text"
xmlns:xi="http://www.w3.org/2001/XInclude"
/></programlisting>
</section>
</section>
@@ -328,35 +314,34 @@
custom code in process executions.
</para>
- <section id="thejbpmclassloader">
+ <section id="jbpmclassloader">
<title>
- The jBPM Class Loader
+ jBPM Class Loader
</title>
<para>
- The jBPM class loader is that which loads the jBPM classes. It
- can do so as it has the <filename>jbpm-3.x.jar</filename>
- filename in its class-path. To make classes visible to the jBPM
- class loader, place them in a JAR file and put that JAR file
- "besides" the <filename>jbpm-3.x.jar</filename> (in
the
- <filename>WEB-INF/lib</filename> directory, for instance, in
- the case of web applications.)
+ The jBPM class loader is the one that loads the jBPM classes.
+ To make classes visible to the jBPM class loader, pack them
+ in a JAR file and co-locate the JAR with
<filename>jbpm-jpdl.jar</filename>.
+ In the case of web applications, one would place the
+ custom JAR file in <filename>WEB-INF/lib</filename> alongside
+ <filename>jbpm-jpdl.jar</filename>.
</para>
</section>
- <section id="theprocessclassloader">
+ <section id="processclassloader">
<title>
- The Process Class Loader
+ Process Class Loader
</title>
<para>
- Delegation classes are loaded with their respective process
- definitions' <firstterm>process class loader</firstterm>.
(The
- process class loader is a class loader that has the jBPM class
- loader as a parent. It adds all of the classes of one
- particular process definition.) Add classes to a process
- definition by putting them in the process archive's
- <filename>/classes</filename> directory. Note that this is only
+ Delegation classes are loaded through their respective
+ <firstterm>process class loader</firstterm>. The
+ process class loader has the jBPM class loader as its parent.
+ It adds the classes deployed with one
+ particular process definition. To add classes to a process
+ definition, put them in the <filename>classes</filename>
+ directory of the process archive. Note that this is only
useful when one wishes to version the classes that have been
added to the process definition. If versioning is not required,
make the classes available to the jBPM class loader instead.
@@ -365,20 +350,16 @@
<para>
If the resource name does not start with a slash, resources are
also loaded from the process archive's
- <filename>/classes</filename> directory. To load resources that
+ <filename>classes</filename> directory. To load resources that
reside outside this directory, start the path with a double
- forward slash (<code>//</code>). (For example, to load
- <filename>data.xml</filename> which is located "next
to" the
- <filename>processdefinition.xml</filename> on the root of the
- process archive file, use
-
<methodname>class.getResource("//data.xml")</methodname> or
-
<methodname>classLoader.getResourceAsStream("//data.xml")</methodname>
- or any variant of these.)
+ forward slash (<code>//</code>). For example, to load
+ <filename>data.xml</filename>, located in the process archive
root,
+ call
<methodname>class.getResource("//data.xml")</methodname>.
</para>
</section>
- <section id="configurationofdelegations">
+ <section id="configuringdelegations">
<title>
Configuring Delegations
</title>
@@ -389,8 +370,8 @@
<firstterm>action</firstterm>. In the case of action, an
implementation of the
<interfacename>ActionHandler</interfacename> interface can be
- called on an event in the process. (Delegations are specified
- in the <filename>processdefinition.xml</filename> file.) One
+ called on an event in the process. Delegations are specified
+ in the <filename>processdefinition.xml</filename> file. One
can supply any of these three pieces of data when specifying a
delegation:
</para>