Beruflich Dokumente
Kultur Dokumente
com/jbpm/v4/userguide/html_single/#thedistribution
1. Introduction
1.1. License and EULA
1.2. Downloads
1.3. Sources
1.4. What is it
1.5. Contents of this userguide
1.6. Migration from jBPM 3
1.7. Reporting problems
2. Installation
2.1. The distribution
2.2. Required software
2.3. Getting started quickly
2.4. Install scripts
2.5. Library dependencies and configuration files
2.6. JBoss
2.7. Tomcat
2.8. Signavio web based process editor
2.9. User webapp
2.10. Database
2.10.1. Creating or dropping the database schema
2.10.2. Upgrading an existing database
2.11. Graphical Process Designer (GPD)
2.11.1. Get Eclipse
2.11.2. Install the GPD plugin into eclipse
2.11.3. Configuring the jBPM runtime
2.11.4. Define the jBPM User Library
2.11.5. Adding jPDL 4 schema to the catalog
2.11.6. Importing the Examples
2.11.7. Adding deployment with ant
5. Services
5.1. Process definition, process instance and executions
5.2. ProcessEngine
5.3. Deploying a process
5.4. Deleting a deployment
1 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
6. jPDL
6.1. process
6.2. Control flow activities
6.2.1. start
6.2.2. state
6.2.3. decision
6.2.4. concurrency
6.2.5. end
6.2.6. task
6.2.7. sub-process
6.2.8. custom
6.3. Automatic activities
6.3.1. java
6.3.2. script
6.3.3. hql
6.3.4. sql
6.3.5. mail
6.4. Common activity contents
6.5. Events
6.5.1. Event listener example
6.5.2. Event propagation
6.6. Asynchronous continuations
6.6.1. Async activity
6.6.2. Async fork
6.7. User code
6.7.1. User code configuration
6.7.2. User code classloading
7. Variables
7.1. Variable scoping
7.2. Variable types
7.3. Updating serialized process variables
7.4. Declared variables
7.5. Variables history
8. Scripting
9. Configuration
9.1. Business calendar
9.2. Console
9.3. Email
Chapter 1. Introduction
2 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
This documentation is best viewed in firefox. There are some known issues with internet explorer.
1.2. Downloads
The distribution packages can be downloaded from sourceforge
http://sourceforge.net/projects/jbpm/files/
1.3. Sources
The source code for this component can be found in the jBPM SVN repository:
https://anonsvn.jboss.org/repos/jbpm/jbpm4/
1.4. What is it
jBPM is an extensible and flexible process engine that can run as a standalone server or embedded in any
Java application.
This user guide explains the supported way on how to use jBPM. The developers guide explains more
advanced customization options that are not part of the support offerings.
3 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
When reporting a problem in the user forum or in our support portal, please use the following snippet as a
template:
Clever readers will have noticed that some of these questions point to probably causes :-) Especially
tweaking the libs and configuration can easily lead to trouble. That's why we have spend a great deal of
effort to include default installations and a simplified configuration mechanism with imports. Think twice
before you start to customize configurations beyond what is indicated in this userguide. Also think twice
before replacing libs with other versions.
Chapter 2. Installation
2.1. The distribution
2.2. Required software
2.3. Getting started quickly
2.4. Install scripts
2.5. Library dependencies and configuration files
2.6. JBoss
2.7. Tomcat
2.8. Signavio web based process editor
2.9. User webapp
2.10. Database
2.10.1. Creating or dropping the database schema
2.10.2. Upgrading an existing database
2.11. Graphical Process Designer (GPD)
2.11.1. Get Eclipse
2.11.2. Install the GPD plugin into eclipse
2.11.3. Configuring the jBPM runtime
2.11.4. Define the jBPM User Library
2.11.5. Adding jPDL 4 schema to the catalog
2.11.6. Importing the Examples
2.11.7. Adding deployment with ant
4 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
http://java.sun.com/javase/downloads/index.jsp
To execute the ant scripts, you'll need apache ant version 1.7.0 or higher:
http://ant.apache.org/bindownload.cgi
ant demo.setup.jboss
or
ant demo.setup.tomcat
That will
5 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
Start eclipse
After this is done, JBoss (or Tomcat, depending on which demo.setup script you chose) will be running in the
background. Once eclipse has started, you can continue to follow the instructions of Section 2.11, “Graphical
Process Designer (GPD)” to start coding your jBPM business processes.
Or you can start modeling processes through the Signavio web editor.
Or surf to the jBPM console. You can login as one of the following users:
Username Password
alex password
mike password
peter password
mary password
Known console limitation: Currently, the timeout of the console is too tight for the reporting to initialize
on slower machines. So the first time when you access the reporting the request will timeout and the console
crashes. Logging out and login again works around this problem. It's being addressed as issue JBPM-2508
It's best to stick to the installations and jBPM configuration files as done with these installation scripts.
Customizing jBPM configuration files directly, is possible, but not supported.
To invoke the install script, open a command line and go to the ${jbpm.home}/install directory. With
ant -p you can find out what each of these scripts can do. The scripts are parametrized with default values
to get going quickly. The following list gives an overview of the available scripts:
demo.setup.jboss: installs jboss, installs jbpm into jboss, starts jboss, creates the jBPM DB schema,
deploys examples, loads example identities, installs and starts eclipse
demo.setup.tomcat: installs tomcat, installs jbpm into tomcat, starts tomcat, creates the jBPM DB
schema, deploys examples, loads example identities, installs and starts eclipse
clean.cfg.dir: Deletes the ${jbpm.home}/install/generated/cfg folder.
6 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
demo.teardown.tomcat: Stops tomcat and then the hsqldb server (if needed)
get.jboss: Downloads a JBoss AS which was tested against the current jBPM version if it is not available
get.tomcat: Downloads tomcat which was tested against the current jBPM version if it is not available
install.tomcat: Downloads tomcat to ${tomcat.distro.dir} if its not available and then unzips tomcat
load.example.identities: Loads the example users and groups into the database
reinstall.jboss.and.jbpm: Deletes the previous jboss installation and re-installs jboss and installs
jbpm in it
reinstall.tomcat.and.jbpm: Deletes the previous tomcat installation and re-installs tomcat and
installs jbpm in it
start.jboss: Starts jboss and waits till jboss is booted, then lets jboss run in the background
start.tomcat: Starts Tomcat and waits till it is booted, then lets Tomcat run in the background
stop.jboss: signals jboss to stop, but doesn't wait till its finished
stop.tomcat: Signals Tomcat to stop, but doesn't wait till its finished
upgrade.jbpm.schema: Upgrades the jBPM tables in the database to the current version
To specify your jdbc properties that are used in the scripts above (eg.DB schema generation), the easiest is
to update the appropriate properties file in directory ${jbpm.home}/install/jdbc. The appropriate
properties file will be loaded by the scripts that are DB related.
database : Default value is hsqldb. Alternative values are mysql, oracle and postgresql
To customize the values for these properties, just use -D like this
7 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
2.6. JBoss
The target install.jbpm.into.jboss will install jBPM into your JBoss 5 installation. Navigate to the install
directory and run ant -p for more details. This install script will install jBPM as a JBoss-wide service so that
all applications can use the same jBPM ProcessEngine.
2.7. Tomcat
The target install.jbpm.into.tomcat will install jBPM into your JBoss 5 installation.
In case you deploy your app on JBoss or another appserver that has the jta.jar classes, then you need to
delete the ${jbpm.home}/install/generated/user-webapp/WEB-INF/lib/jta.jar
2.10. Database
The install script is also capable of performing database operations such as creating the schema, if you are
installing jBPM for the first time, or upgrading the database used with a previous version to the current
schema. Dropping the schema is an option as well.
The prerrequisite for any database operation is to specify your database connection parameters in
${jbpm.home}/install/jdbc.
8 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
To create the schema, run target create.jbpm.schema in the ${jbpm.home}/install directory. Apart from
creating tables and constraints, the mentioned target will initialize table JBPM4_PROPERTY with the current
engine version (key db.version) and the ID generator base value (key next.dbid).
To drop the schema, simply run target drop.jbpm.schema. Be aware that this operation will destroy any
data present in the jBPM tables.
Upgrading is a two-fold operation. The foremost step is to add any extra tables, columns or constraints that
were introduced in newer versions. Afterwards, seed data is inserted.
Between 4.0 and 4.1, table JBPM4_VARIABLE got a new column CLASSNAME_ used to support setting process
variables to values of custom types mapped with Hibernate. This column is nullable and left uninitialized
since the feature was not operational in 4.0.
The jBPM version is saved in table JBPM4_PROPERTY under key db.version to allow for precise
identification in future releases.
The ID generation strategy is consistent across databases. The next available ID is calculated by querying
all tables having an identifier column, and stored under key next.dbid in the JBPM4_PROPERTY table.
The process language is set to jpdl-4.0 for all existing process definitions under key langid in table
JBPM4_DEPLOYPROP. The jPDL parser employs the langid property to read process documents in a
backwards-compatible manner.
Use the demo setup or download eclipse manually: Eclipse IDE for Java EE Developers (163 MB).
The classic version of eclipse will not be sufficient as it does not have an XML editor. Eclipse for Java
developers should also work.
The installation of the GPD uses the Eclipse Software Update mechanism and is pretty straightforward. There
is an archived update site included in the runtime installation of jBPM when you unzip it at
9 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
install/src/gpd/jbpm-gpd-site.zip
Click Add...
Clicking OK in the Add Site dialog will bring you back to the dialog 'Install'
Click Add...
In the Add Location dialog, enter a name like e.g. jbpm-4.0 and then click Search...
In the Browse For Folder dialog, select your jbpm home directory and click OK
10 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
This section shows how to define a user library for your workspace that is a placeholder for the jBPM library
as well as its dependencies. If you create a new Java project, it will be sufficient to add this user library to
the build path.
Click New...
Click Open
Click Edit
Click Choose
11 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
In case you want to edit the process XML sources directly, it is best to specify your schema in the XML
catalog. This will give you better code completion while editing the process sources.
Click 'Add...'
Click the button with the map-icon next to location and select 'File System...'
In the dialog that opens, select file jpdl-4.0.xsd in the src directory of the jBPM installation root.
12 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
In this section we will import the examples project in the installation in Eclipse
Click Next
Click Finish
After setting the jBPM User Libraries and importing the examples, all the examples can be run as JUnit tests.
Right click on a test and select 'Run As' --> 'JUnit Test'.
You're all set to start playing with the coolest Java process technology!
You can leverage the eclipse ant integration to ease deployment of processes. We'll show you how it works
with the examples. Then you can copy this practice in your own project. First, open up the Ant view.
Select Window --> Show View --> Other... --> Ant --> Ant
Then drag the build file build.xml in the examples project from the package explorer to the Ant view
13 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
This chapter will explain how to work with the Graphical Process Designer. After installing the GPD and
setting up the examples, you'll see that the jPDL process files will get a special icon. Double clicking such a
file in the package view will open up the jPDL process in the GPD.
Select jBPM --> jPDL 4 File. Click 'Next >'. Then the 'New jPDL 4 File' wizard opens.
14 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
Select the parent directory, enter a file name and click 'Finish'. Voila, you've created your first jPDL process
file.
15 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
A business archive is a collection of files assembled in a jar formatted file. The files in a business archive can
be jPDL process files, forms, classes, process image and other process resources.
An example of creating and deploying a business archive can be found in the ant build script (build.xml) in
the examples directory of the distribution. Let's look at the relevant parts. First a path is declared that
includes the jbpm.jar and all its dependencies.
16 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
<path id="jbpm.libs.incl.dependencies">
<pathelement location="${jbpm.home}/examples/target/classes" />
<fileset dir="${jbpm.home}">
<include name="jbpm.jar" />
</fileset>
<fileset dir="${jbpm.home}/lib" />
</path>
The JDBC driver jar(s) for your database should also be included in the path. MySQL, PostgreSQL and
HSQLDB are in the distribution. But the Oracle driver you have to download separately from the oracle site
since we're not allowed to redistribute that file.
When a business archive is deployed, jBPM scans for all the files with the .jpdl.xml extension in the
business archive. All those files will be parsed as jPDL processes and made available to the runtime engine.
All other resources in the business archive will also be stored as resources in that deployment and made
accessible through InputStream getResourceAsStream(long deploymentDbid, String resourceName);
in class RepositoryService
<jar destfile="${jbpm.home}/examples/target/examples.bar">
<fileset dir="${jbpm.home}/examples/src">
<include name="**/*.jpdl.xml" />
...
</fileset>
</jar>
Before the jbpm-deploy task can be used it need to be declared like this:
<taskdef name="jbpm-deploy"
classname="org.jbpm.pvm.internal.ant.JbpmDeployTask"
classpathref="jbpm.libs.incl.dependencies" />
files to be deployed expressed as a plain ant fileset. Files ending with .xml will
fileset 0..* be deployed as process files. Files ending with ar like .bar or .jar will be
deployed as business archives.
17 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
Classes that are referenced from processes must be made available in one of 3 ways:
as .class files in your business archive. Unlike in jBPM 3, now the root of the archive file is used as the
root for searching class resources. So when class com.superdeluxsandwiches.Order is referenced in the
process file, it will be found when it is in the same business archive with entry name
com/superdeluxsandwiches/Order.class Classes are cached (key is a combination of deployment and
context classloader), so it should perform better then in jBPM 3.
as classes available in the web application that calls jBPM. Even when jBPM is deployed server-wide on
jboss or tomcat, jBPM will find the classes in your web application or enterprise application that calls
jBPM. That's because we use the current context classloader when searching for classes during process
execution.
as class files that are available server-wide. E.g. like the jars in the lib directories in tomcat and jboss.
In case of the examples, an examples.jar file is created with all the classes and it is put in the lib directory
of the JBoss server configuration. Similarly for tomcat. See target install.examples.into.tomcat and
install.examples.into.jboss. In one of the future releases we might switch to include the classes in the
business archive itself.
Chapter 5. Services
5.1. Process definition, process instance and executions
5.2. ProcessEngine
5.3. Deploying a process
5.4. Deleting a deployment
5.5. Starting a new process instance
5.5.1. In latest
5.5.2. Specific process version
5.5.3. With a key
5.5.4. With variables
5.6. Signalling a waiting execution
5.7. TaskService
5.8. HistoryService
5.9. ManagementService
5.10. Query API
18 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
One process instance represents one particular run of a process definition. For example, the loan request of
John Doe last Friday to finance his new boat is represented in one process instance of the loan process
definition.
A process instance contains all the runtime state. The most prominent property is the pointer that keeps
track of the current activity.
Suppose that wiring the money and archiving can be done in parallel. Then the main process instance will
have two child executions to keep track of the state like this:
19 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
More general, a process instance is the root of a tree of executions. When a new process instance is started,
the process instance is in fact the root execution scope. Only leaf executions can be active.
The motivation to work with a tree structure like this is that this conceptually remains simple in the case
where there is only one path of execution. The services API doesn't need to make a functional difference
between process instances and executions. Therefore, the API has only one Execution type to refer to both
ProcessInstances and Executions.
5.2. ProcessEngine
Interacting with jBPM occurs through services. The service interfaces can be obtained from the
ProcessEngine which is build from a Configuration.
A ProcessEngine is thread safe and can be stored in a static member field or even better in JNDI or some
other central location. One ProcessEngine object can be used by all requests and threads in an application.
Here's how you can obtain a ProcessEngine
The code snippets in this section and the next section about process deployments are taken from the
example org.jbpm.examples.services.ServicesTest
The previous code snippet shows how to build a ProcessEngine from the default configuration file
jbpm.cfg.xml which is expected in the root of the classpath. If you want to specify another resource
location, use the setResource method like this:
There are other setXxxx methods that allow to specify the configuration content as an InputStream, an
xmlString, InputSource, URL or File.
Process engine objects defined in the configuration can also be retrieved by type
(processEngine.get(Class<T>)) or by name (processEngine.get(String))
20 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
Analogue to the addResourceFromClasspath method above, the source of the processes definitions XML can
be picked up from a file, url, string, input stream or zip input stream.
Each deployment is composed of a set of named resources. The content of each resource is a byte array.
jPDL process files are recognized by their extension .jpdl.xml. Other resource types are task forms and
java classes.
A deployment works with a set of named resources and can potentially contain multiple process descriptions
and multiple other artifact types. The jPDL deployer will recognise process files based on the .jpdl.xml
extension automatically.
During deployment, an id is assigned to the process definitions. The id will have format {key}-{version}
with a dash between key and version
If key is not provided, it is generated automatically based on the name. All non alpha numeric characters in
the name will be replaced by underscores to generate the key.
The same name can only be associated to one key and vice versa.
If version is not provided, a version will be automatically be assigned. For version assignment, the
versions of all deployed process definitions with the same name will be taken into account. The assigned
version will be one higher than the highest version number of deployed process definitions with the same
key. If no process definitions with a similar key have been deployed, version number 1 is assigned.
Let's assume that this is the first time that this process gets deployed. Then it will get the following
properties:
And as a second example, we'll show how you can get shorter ids by specifying a process key:
21 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
repositoryService.deleteDeployment(deploymentId);
That method will throw an exception when there are still active process executions for process definitions in
that deployment.
If you want to cascade deletion of a deployment to all the process instances of all the process definitions, use
deleteDeploymentCascade.
5.5.1. In latest
Simplest and most common way to start a new process instance for a process definition is like this:
In this case, the service method will first look up the latest version of the processes with key ICL. Then a
new process instance is started in that latest process definition.
When a new version of the insurance claim process is deployed, all invocations of
startProcessInstanceByKey will automatically switch to the newly deployed version.
If instead you want to start a new process instance in a very specific version, you can use the id of the
process definition like this:
ProcessInstance processInstance =
executionService.startProcessInstanceById("ICL-1");
A new process instance can optionally be given a key. This key is a user defined reference to the execution
and is sometimes referred to as the 'business key'. A business key must be unique within the scope of all
versions of a process definition. Typically it is easy to find such a key in the domain of the business process.
For example, an order id or an insurance claim number.
22 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
ProcessInstance processInstance =
executionService.startProcessInstanceByKey("ICL", "CL92837");
The key is used to create the id of the process instance. The format used is
{process-key}.{execution-id}. With a dot between process-key and execution-id. So execution created
in the previous code snippet will have id ICL.CL92837.
If no user defined key is provided, the DB primary key is taken as the key. In that case, the id can be
retrieved like this:
ProcessInstance processInstance =
executionService.startProcessInstanceByKey("ICL");
String pid = processInstance.getId();
It is a best practice to use a user defined business key. Typically in your application domain, finding such a
key is not difficult. By providing a user defined key, you can then compose the id of the execution, rather
then performing a query based on the process variables - which is also more costly performance-wise.
A map of named parameter objects can be provided when starting a new process instance. These
parameters will be set as variables on the process instance between creation and start of the process
instance.
ProcessInstance processInstance =
executionService.startProcessInstanceByKey("ICL", variables);
In some cases, the execution that arrives in a state will be the process instance itself. But that is not always
the case. In case of timers or concurrency, a process is the root execution of a tree of executions. So you
have to make sure that you signal the right path of execution.
The preferred way to capture the right execution is by associating an event listener to the state activity like
this:
<state name="wait">
<on event="start">
<event-listener class="org.jbpm.examples.StartExternalWork" />
</on>
...
</state>
In event listener StartExternalWork you can kick off what needs to be done externally. In that event
listener you can also obtain the exact execution id with execution.getId(). It's that executionId that you'll
need to provide with the signal later on when the external work is done:
23 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
executionService.signalExecutionById(executionId);
There is an alternatively (less preferrable) way to obtain the executionId when the execution arrives in the
state activity. It's only possible to obtain the execution id this way if you know after which jBPM API call the
execution will have entered the state activity:
ProcessInstance processInstance =
executionService.startProcessInstanceById(processDefinitionId);
// or ProcessInstance processInstance =
// executionService.signalProcessInstanceById(executionId);
Do note that the above solution couples the application logic (too) closely by using knowledge about the
actual process structure.
5.7. TaskService
The primary purpose of the TaskService is to provide access to task lists. The code sample will show how to
get the task list for the user with id johndoe.
Typically tasks are associated with a form and displayed in some user interface. The form needs to be able to
read and write data related to the task.
taskService.completeTask(taskId);
taskService.completeTask(taskId, variables);
taskService.completeTask(taskId, outcome);
taskService.completeTask(taskId, outcome, variables);
The API allows to provide a map of variables that will be added as process variables before the task is
completed. It is also possible to provide an 'outcome', that will be used to determine which outgoing
transition will be chosen. The logic is as follows:
24 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
taskService.getOutcomes() returns a collection that includes only the name of the transition
taskService.completeTask(taskId) will take the single outgoing transition
taskService.completeTask(taskId, null) will will result in an exception (as there is no transition without a
name)
If a task has multiple outgoing transitions. One transition has no a name and the other transition
have a name:
taskService.getOutcomes() returns a collection that includes a null value and the names of the other
transitions
taskService.completeTask(taskId) will take the transition without a name
If a task has multiple outgoing transitions and all of them are uniquely named, then:
taskService.getOutcomes() returns a collection that includes all the names of all the transitions
Tasks can also be offered to a set of candidates. Candidates can be users or groups. Users can take tasks for
which they are a candidate. Taking a task means that this user will be set as the assignee. After that, other
users will be blocked from taking the task.
People should not work on a task unless they are assigned to that task. The user interface should display
forms and allow users to complete tasks if they are assigned to it. For unassigned tasks for which the user is
a candidate, the only action that should be exposed is 'take'.
5.8. HistoryService
During runtime execution of process instances, events are generated. And from those events, history
information on both running and completed process executions are collected in the history tables. The
HistoryService provides access to that information.
Querying for all process instances for a specific process definition can be done like this:
25 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
Also individual activity executions are stored in the history information as HistoryActivityInstances.
Convenience methods avgDurationPerActivity and choiceDistribution are also available. See javadocs
for more information on those methods.
Sometimes there is a need to get complete list of nodes executed for a given process instance. Following
query can be used to get list of all nodes executed:
Above query is a bit different then querying by execution id. Sometimes execution id is different than process
instance id, for instance when an activity has a timer then execution id will get additional suffix, which makes
that node excluded from a result list while querying by execution id.
5.9. ManagementService
The management service is mostly used to manage the jobs. See javadocs for more information. This
functionality is also exposed through the jBPM web console.
For example:
This example returns all the process instances of the given process definition which are not suspended. The
result is also paged, and the first page of 50 results is given.
This query will give all the tasks for a given process instance assigned to John, paged of course, in a
26 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
Every service has operations of creating such unified queries (eg. querying jobs through the
ManagementService, querying completed process instances through the HistoryService. Do check the
Javadoc of the services to learn everything about the query API.
Chapter 6. jPDL
6.1. process
6.2. Control flow activities
6.2.1. start
6.2.2. state
6.2.3. decision
6.2.4. concurrency
6.2.5. end
6.2.6. task
6.2.7. sub-process
6.2.8. custom
6.3. Automatic activities
6.3.1. java
6.3.2. script
6.3.3. hql
6.3.4. sql
6.3.5. mail
6.4. Common activity contents
6.5. Events
6.5.1. Event listener example
6.5.2. Event propagation
6.6. Asynchronous continuations
6.6.1. Async activity
6.6.2. Async fork
6.7. User code
6.7.1. User code configuration
6.7.2. User code classloading
This chapter will explain the jPDL file format for describing process definitions. jPDL is the prominent process
language of jBPM. The goal of jPDL is to be as concise and developer-friendly as possible, while offering
every feature you'd expect from a BPM process language.
The jPDL schema file contains more attributes and elements then this documentation. This part of the
documentation explains the stable and supported part of jPDL. Experimental/not supported jPDL features can
be found in the developers guide.
27 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
<start>
<transition to="Verify supplier" />
</start>
</process>
6.1. process
The top level element representing one process definition.
28 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
6.2.1. start
Indicates where an execution for this process starts. Typically there is exactly one start activity in a process.
A process has to have at least one start activity. A start activity must have exactly one outgoing transition
and that transition is taken when a process execution starts.
Known limitation: for now, a process can not have more then one start.
6.2.2. state
A wait state. Process execution will wait until an external trigger is provided through the API. Apart from the
common activity content, state doesn't have any extra attributes or elements.
Let's look at an example which shows states connected with transitions as a sequence
29 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
<start>
<transition to="a" />
</start>
<state name="a">
<transition to="b" />
</state>
<state name="b">
<transition to="c" />
</state>
</process>
ProcessInstance processInstance =
executionService.startProcessInstanceByKey("StateSequence");
the created process instance will be positioned in state a. Providing an external trigger can be done with the
signalExecution methods.
processInstance = executionService.signalExecutionById(executionInA.getId());
Execution executionInB = processInstance.findActiveExecutionIn("b");
assertNotNull(executionInB);
processInstance = executionService.signalExecutionById(executionInB.getId());
Execution executionInC = processInstance.findActiveExecutionIn("c");
assertNotNull(executionInC);
In this second example with states, we'll show how you can use a state can be used to feed in an external
choice of the path to take.
30 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
<start>
<transition to="wait for response" />
</start>
</process>
Now, the execution has arrived in the wait for response. The execution will wait there until an external
trigger is given. In case a state has multiple outgoing transitions, the signalName given in the external
trigger will be matched against the name of the outgoing transition to take. So when we provide signalName
accept like this:
assertTrue(processInstance.isActive("submit document"));
Then the execution will continue over the outgoing transition named accept. Analogue, when signalName
reject is given in the signalExecutionXxx methods, the execution will continue over the outgoing transition
named reject.
6.2.3. decision
Takes one path of many alternatives. Also known as a decision. A decision activity has multiple outgoing
transitions and when an execution arrives in a decision activity, an automatic evaluation will decide which
outgoing transition is taken.
A decision with conditions on the transitions evaluates the condition in each transition. The first transition for
which the nested condition expression resolves to true or which does not have a condition is taken.
31 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
Example:
<start>
<transition to="evaluate document" />
</start>
</process>
32 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
assertTrue(processInstance.isActive("submit document"));
Example:
<start >
<transition to="evaluate document"/>
</start>
</process>
When you start an new process instance with good content like this
33 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
A decision handler is a java class that implements the DecisionHandler interface. The decision handler will
be responsible for selecting the name of the outgoing transition.
The handler is specified as a sub element of the decision. The configuration attributes and content of a
decision handler element can be found in Section 6.7, “User code”.
<process name="DecisionHandler">
<start>
<transition to="evaluate document" />
</start>
</process>
Now, when we start a process instance and supply value you're great for variable content, then the
34 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
ContentEvaluation will return String good and the process instance will arrive in activity Submit document.
6.2.4. concurrency
Concurrent paths of executions can be modeled with the fork and join activities. The next table describes
the join attributes; fork has no specific attributes.
The fork activity allows a single path of execution to be split into two or more branches which can execute
activities concurrently.
35 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
<start>
<transition to="fork"/>
</start>
<fork name="fork">
<transition to="send invoice" />
<transition to="load truck"/>
<transition to="print shipping documents" />
</fork>
</process>
6.2.5. end
By default, an end activity will end the complete process instance. In case multiple concurrent executions are
still active within the same process instance, all of them will be ended.
36 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
<start>
<transition to="end" />
</start>
</process>
Only the execution that arrives in the end activity will be ended and other concurrent executions should be
left active. To get this behaviour, set attribute ends="execution"
A process can have multiple end events. This can be handy to indicate different outcomes of a process
instance. For example
37 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
<start>
<transition to="get return code" />
</start>
<end name="ok"/>
<end name="bad request"/>
<end name="internal server error"/>
</process>
Now if we would start an execution and signal it to move out of the get return code wait state with the
following code, the execution would end with the bad request end event.
Likewise, using the value 200 or 500 would cause the execution to end with the ok or with the
internal server error end events respectively.
An execution can also end with different states. It is another way to specify the outcome of a process. It is
indicated by the state attribute of the end event or by the end-cancel and end-error shortcut notations.
38 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
<start>
<transition to="get return code"/>
</start>
</process>
This time, if we would start an execution and signal it to move out of the get return code wait state with
the following code, the execution would end with the cancel state.
Similarly, using the value 200 or 500 would cause the execution to end with the completed or with the error
states respectively.
6.2.6. task
39 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
<process name="TaskAssignee">
<start>
<transition to="review" />
</start>
<task name="review"
assignee="#{order.owner}">
</process>
This process shows 2 aspects of task assignment. First, that the attribute assignee is used to indicate the
user that is responsible for completing the task. The assignee is a String property of a task and refers to a
user.
Secondly, this attribute is by default evaluated as an expression. In this case the task is assigned to
#{order.owner}. Which means that first an object is searched for with name order. One of the places where
this object is looked up is the process variables associated to the task. Then the getOwner() getter will be
used to get the userId that references the user that is responsible for completing this task.
String owner;
Then the task list for johndoe can be obtained like this.
Note that it is also possible to put plain text like assignee="johndoe". In that case the task will be assigned
to johndoe.
40 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
A task that will be offered to a group of users. One of the users should then take the task in order to
complete it.
<process name="TaskCandidates">
<start>
<transition to="review" />
</start>
<task name="review"
candidate-groups="sales-dept">
<state name="wait"/>
</process>
After starting, a task will be created. The task will not show up in anyone's personal task list. Following task
lists will be empty.
taskService.getPersonalTasks("johndoe");
taskService.getPersonalTasks("joesmoe");
But the task will show up in the group task list of all members of the sales-dept group.
The in our example, the sales-dept has two members: johndoe and joesmoe
identityService.createGroup("sales-dept");
41 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
So after the process is created, the task will appear in both the group tasks for users johndoe and joesmoe
taskService.findGroupTasks("johndoe");
taskService.findGroupTasks("joesmoe");
Candidates must take a task before they can work on it. This will prevent that two candides start working on
the same task. The user interface must only offer the action 'Take' for the tasks in the group task list.
taskService.takeTask(task.getDbid(), "johndoe");
When a user takes a task, the assignee of that task will be set to the given user. The task will disappear from
all the candidate's group task list and it will appear in the user's assigned tasks.
Users are only allowed to work on tasks in their personal task list. This should be enforced by the user
interface.
Similarly, the attribute candidate-users can be used that resolves to a comma separated list of userIds.
The candidate-users attribute can be used in combination with other assignment options.
An AssignmentHandler can be used to calculate the assignee and the candidates for a task
programmatically.
/** sets the actorId and candidates for the given assignable. */
void assign(Assignable assignable, OpenExecution execution) throws Exception;
}
Assignable is a common interface for Tasks and Swimlanes. So AssignmentHandlers can be used for tasks
as well as swimlanes (see later).
assignment-handler is a sub element of the task element. It specifies a user code object. So the attributes
and elements of assignment-handler are documented in Section 6.7, “User code”
42 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
<start g="20,20,48,48">
<transition to="review" />
</start>
</process>
String assignee;
Please note that potentially, AssignmentHandler implementations can use the process variables and any
other Java API to access resources like your application database to calculate the assignee and candidate
users and groups.
Starting a new process instance of the TaskAssignmentHandler process will immediately bring the new
execution to the task activity. A new review task is created and at that point, the AssignTask assignment
handler is called. That will set johndoe as the assignee. So John Doe will find the task in his personal task
list.
Multiple tasks in a process should be assigned to the same user or candidates. Multiple tasks in a process can
be associated to a single swimlane. The process instance will remember the candidates and user that
performed the first task in the swimlane. And subsequent tasks in the same swimlane will be assigned to
those user and candidates.
A swimlane can also be considered as a process role. In some cases, this might boil down to authorization
roles in the identity component. But bare in mind that it is not always the same thing.
swimlane swimlane (string) optional refers to a swimlane that is declared in the process
43 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
<start>
<transition to="enter order data" />
</start>
<task
name="calculate quote"
swimlane="sales representative">
</task>
</process>
identityService.createGroup("sales-dept");
After starting a new process instance, user johndoe will be a candidate for task enter order data. Again
like in the previous task candidates example, John Doe can now take this task like this:
taskService.takeTask(taskDbid, "johndoe");
44 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
Taking the task will make Litjohndoe the assignee for the task. And since this task is coupled to the
swimlane sales representative, assignee johndoe will also be propagated as the assignee in the
swimlane.
taskService.completeTask(taskDbid);
Completing the task will bring the process execution to the next task, which is calculate quote. Also this
task is linked to the swimlane. Therefore, the task will be assigned to johndoe. Also the candidate users and
candidate groups of the initial assignment will be copied from the swimlane to the task. This is relevant in
case user johndoe would release the task and offer it back to the other candidates.
Tasks can read and update process variables. Later tasks will have the option to declare task-local process
variables. Task variables are an important part of the task forms. Task forms typically show data that comes
from the task and the process instance. Then input from the user is translated in setting task variables.
taskService.setVariables(taskDbid, variables);
It is possible to provide assignees with notifications when a task is added to their list, as well as reminders at
specific intervals. Every email message is produced from a template. Templates may be specified inline or in
the process-engine-context section of the configuration file.
45 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
<task name="review"
assignee="#{order.owner}"
<notification/>
<reminder duedate="2 days" repeat="1 day"/>
</task>
6.2.7. sub-process
Creates a sub process instance and waits till it is completed. When the sub process instance completes, then
the execution in the sub-process will continue.
46 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
If the outcome matches the value, this transition is taken after the
outcome-value 0..1
sub-process ended. The value is specified with one child element.
47 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
The SubProcessVariables example scenario will show the basic workings of the sub-process activity, how to
feed information in the sub process when it starts and how to extract information out of the subprocess when
it ends.
<start>
<transition to="review" />
</start>
<sub-process name="review"
sub-process-key="SubProcessReview">
<state name="wait"/>
</process>
<start>
<transition to="get approval"/>
</start>
<transition to="end"/>
</task>
</process>
48 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
Then the parent process execution will arrive in the sub process activity. A sub process instance is created
and linked with the super process execution. When the SubProcessReview process instance starts, it arrives
in the task. A task will be created for johndoe.
We can see that the document has been passed from the super process instance to the sub process instance:
Then we set a variable on the task. This is typically done through a form. But here we'll show how it is done
programmatically.
Completing this task, will cause the sub process instance to end.
taskService.completeTask(task.getDbid());
When the sub process ends, the super process execution will get signalled(=notified). First the result
variable from the sub process instance will be copied into the reviewResult variable in the super process
execution. Then the super process execution will continue and leave the review activity.
In the SubProcessOutcomeValueTest example, the value of a sub process variable is used to select the
outgoing transition of the sub-process activity.
49 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
<process name="SubProcessDocument">
<start>
<transition to="review" />
</start>
<sub-process name="review"
sub-process-key="SubProcessReview"
outcome="#{result}">
</process>
Figure 6.17. The subprocess review example process for outcome value
<start>
<transition to="get approval"/>
</start>
<transition to="end"/>
</task>
</process>
50 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
In this scenario, the ok transition is taken in the parent process out of the sub-process review activity. The
example test case also shows other scenarios.
A process can have many end activities. In the SubProcessOutcomeActivityTest example, the resulting
end activity is used to select the outgoing transition of the sub-process activity.
Figure 6.18. The subprocess document example process for outcome activity
<process name="SubProcessDocument">
<start>
<transition to="review" />
</start>
<sub-process name="review"
sub-process-key="SubProcessReview">
</process>
51 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
Figure 6.19. The subprocess review example process for outcome activity
<start>
<transition to="get approval"/>
</start>
</process>
taskService.completeTask(task.getDbid(), "ok");
This will cause the sub process to end in end activity ok. The super process execution will then take outgoing
transition ok to next step.
6.2.8. custom
A custom activity refers to user code. See Section 6.7, “User code” for more details on the specific attributes
and elements. Let's look at the example:
52 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
<start >
<transition to="print dots" />
</start>
</process>
The custom activity behaviour class PrintDots shows that it's possible to control the flow when
implementing custom activity behaviours. In this case the PrintDots acitivity implementation will after
printing dots wait in the activity until a signal is given.
System.out.println(dots);
execution.waitForSignal();
}
6.3.1. java
The Java task. A process execution will execute the method of the class that is configured in this activity.
53 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
54 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
<start >
<transition to="greet" />
</start>
<java name="greet"
class="org.jbpm.examples.java.JohnDoe"
method="hello"
var="answer"
>
<arg><object expr="#{joesmoe.handshakes.force}"/></arg>
<arg><object expr="#{joesmoe.handshakes.duration}"/></arg>
</process>
Classes involved:
String state;
Session session;
55 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
return this;
}
The first java activity greet specifies that during its execution an instance of the class
org.jbpm.examples.java.JohnDoe will be instantiated and the method hello of this class will be invoked
on the resulting object. The variable named answer will contain the result of the invocation.
The class above reveals that it contains two fields named state and session and that the method hello
accepts one argument. During the execution the values specified in the field and arg configuration
elements will be used. The expected result of creating a process instance is that the process variable answer
contains the string I'm fine, thank you..
The second java activity is named shake hand. It will resolve expression #{hand} and capture the resulting
object as the target object. On that object, the method shake will be invoked. The two arguments will be
calculated by resolving the respective expressions #{joesmoe.handshakes.force} and
#{joesmoe.handshakes.duration}. The resulting object is a mofied version of the hand and var="hand"
will cause the modified hand to overwrite the old hand variable value.
6.3.2. script
A script activity evaluates a script. Scripts can be specified in any language for which there is a JSR-223
compliant scripting engine. Configuration of scripting engines is explained below.
The script is provided with the expr attribute. This is for short expressions that are easier expressed in an
attribute then in a text element. If no lang is specified, the default-expression-language is used.
56 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
In the next example, we'll see how a script activity with an expression and how the result is stored in a
variable.
<start>
<transition to="invoke script" />
</start>
<state name="wait"/>
</process>
String address;
When starting a process instance for this process, we supply a person with a given address property as
variable person.
executionService.startProcessInstanceByKey("ScriptText", variables);
After the execution of the script activity, variable text will contain 'Send packet to Honolulu'.
57 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
The second way of specifying a script is with a text element. This is convenient when the script text spans
multiple lines.
For example
<start>
<transition to="invoke script" />
</start>
<state name="wait"/>
</process>
Execution of this process is exactly the same as with the script expression above.
6.3.3. hql
58 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
With the hql activity, a HQL query can be performed on the database and the result is stored in a process
variable.
var variablename required the name of the variable in which the result is stored.
a value of true means that the result from the
hibernate query should be obtained with method
unique {true, false} false optional
uniqueResult(). The default is false and in that case
the list() method will be used to get the result.
For example:
59 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
<start>
<transition to="get process names" />
</start>
<state name="wait"/>
</process>
6.3.4. sql
The sql activity is exactly the same as the hql activity, with the only difference that
session.createSQLQuery(...) is used.
6.3.5. mail
Through the mail activity, process authors are able to specify the content of an email message to be sent to
multiple recipients at once. Every email message is produced from a template. Templates may be specified
inline or in the process-engine-context section of the configuration file.
60 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
Example usage:
61 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
Unless specified otherwise above, all activities also include this content model:
6.5. Events
Events specify points in a process on which a list of event listeners can be registered. When an execution
passes that point in the process, the event listeners are notified. The events and listeners are not shown in
the graphical view of the process, which makes them very interesting for implementing technical details. An
event is fired by an element in the process definition like e.g. the process definition, an activity or a
transition.
To associate a list of event listeners with a process or an activity, use the on element to group the event
listeners and specifiy the event. on can be nested as a subelement of process or any activity.
To associate a list of event listeners with a transition take event, just include the event listeners directly in
the transition element.
event-listener is user code so it can be configured like described in Section 6.7, “User code”.
62 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
Any automatic activities (including event-listener) that are placed on events can specify following additional
attributes:
{enabled |
indicates if the event listener should also be
propagation disabled | true | disabled optional
invoked for propagating events.
false | on | off}
indicates if the execution should be continued
{sync | async | asynchronously right before the event listener
continue sync optional
exclusive} is executed. @see also Section 6.6,
“Asynchronous continuations”
<on event="start">
<event-listener class="org.jbpm.examples.eventlistener.LogListener">
<field name="msg"><string value="start on process definition"/></field>
</event-listener>
</on>
<start>
<transition to="wait"/>
</start>
<state name="wait">
<on event="start">
<event-listener class="org.jbpm.examples.eventlistener.LogListener">
<field name="msg"><string value="start on activity wait"/></field>
</event-listener>
</on>
<on event="end">
<event-listener class="org.jbpm.examples.eventlistener.LogListener">
<field name="msg"><string value="end on activity wait"/></field>
</event-listener>
</on>
<transition to="park">
<event-listener class="org.jbpm.examples.eventlistener.LogListener">
<field name="msg"><string value="take transition"/></field>
</event-listener>
</transition>
</state>
<state name="park"/>
</process>
63 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
logs.add(msg);
execution.setVariable("logs", logs);
}
}
Then the process instance executes up to the wait activity. So we provide a signal and that will cause it to
execute till the end.
Events are propagated from activities and transitions to outer activities and eventually to the process
definition.
By default, event listeners are only invoked for events that are fired on the elements on which the event
listeners are subscribed. But by specifying propagation="enabled", the event listener will also be invoked
for all events that are fired on contained elements.
This default behaviour has a couple of advantages: user application transactions can be easily propagated to
jBPM to that jBPM's DB updates are done in the user's transaction context. Secondly, it's possible for a client
to get an exception in case something goes wrong during execution of the process. Usually, the automatic
work that has to be done as part of the process inbetween two wait states is relatively small. Even if multiple
automatic activities are executed inbetween 2 wait states. So in most situations, it's good to do all that work
64 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
in a single transaction. This explains that the default behaviour of jPDL is to perform all work of the process
synchronously in the thread of client.
For those cases where you don't want the call to jBPM to be blocking until all the automatic work is done,
jPDL allows for very fine grained control over transaction boundaries. On various places in the process,
asynchronous continuations can be introduced. Asynchronous continuations cause the transaction to commit
and the jBPM method invocation will return. jBPM will then start a new transaction in a new thread and
continue the rest of the automatic process work asynchronously. jBPM uses asynchronous messaging
internally to accomplish this.
Upon an asynchronous continuation, an asynchronous message will be sent as part of the currently ongoing
transaction. And then the originally invoked method like e.g. startProcessInstanceById(...) or
signalProcessInstanceById(...) will return. When the asynchronous message is committed and then
processed, it will start a new transaction and resume execution where it left off.
sync (default) keep executing the element as part of the ongoing transaction.
async introduces an asynchronous continuation (aka safe point). The ongoing transaction is committed
and the element is executed in a new transaction. Transactional asynchronous messaging is used by the
jBPM implementation to achieve this.
exclusive introduces a asynchronous continuation (aka safe point). The ongoing transaction is committed
and the element is executed in a new transaction. Transactional asynchronous messaging is used by the
jBPM implementation to achieve this. Exclusive messages will not be processed concurrently. jBPM will
make sure that exclusive jobs for the same process instance are not executed concurrently, even if your
jBPM configuration has multiple asynchronous message processors (like the JobExecutor) running on
different systems. This can be used to prevent optimistic locking failures in case multiple, potentially
conflicting jobs are scheduled in the same transaction.
65 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
<start>
<transition to="generate pdf"/>
</start>
<end name="end"/>
</process>
ProcessInstance processInstance =
executionService.startProcessInstanceByKey("AsyncActivity");
String processInstanceId = processInstance.getId();
Without the asynchronous continuations, this would be an all automatic process and the process would
execute all the way up to the end in method startProcessInstanceByKey
But with continue="async" the execution only goes untill it is about to execute activity generate pdf. Then
an asynchronous continuation message is send and the startProcessInstanceByKey method returns.
In a normal configuration, the job executor will automatically pick up the message and execute it. But for
testing scenarios and for these examples we want to control when messages are executed so the job
executor is not configured. Therefore we have to execute the jobs manually like this:
That will bring the process until it's about to execute activity calculate primes and again an asynchronous
message is send.
Then the message can be looked up again and when that message is executed, that transaction will run the
execution till the end.
66 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
<start >
<transition to="fork"/>
</start>
<fork >
<on event="end" continue="exclusive" />
<transition />
<transition />
</fork>
<join >
<transition to="end"/>
</join>
<end />
</process>
Value exclusive was selected to serialize the executions of the 2 asynchonous continuation jobs resulting
from the fork. The respective transactions that will execute activities ship goods and send bill will both
arrive at the join. At the join, both transactions will synchronize on the same execution (read: update the
same execution row in the DB), resulting in a potential optimistic locking failure.
67 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
assertEquals(2, jobs.size());
job = jobs.get(1);
assertNotNull(endTime);
custom
event-listener
assignment-handler in task
handler in decision
condition in transition
68 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
field and property elements have exactly one child element that represents the value that will be injected.
Table 6.42. Attribute for basic type string, int, long, floatand double:
value text required text value that will be parsed to the respective type
Process definitions are cached. By default, all user code objects are cached as part of those process
definitions. For all objects that are referenced by a class name, will be instantiated during parsing time.
Which implies that the objects aren't allowed to store non-stateless data (ie which can change). This is
typically OK since those objects are in practice almost always immutable. If you do need to use 'dynamic'
data in your user code, you can always fall back to process variables (or Environment.get(xxx) calls).
The devguide also explains an unsupported attribute to prevent that user objects are cached.
Chapter 7. Variables
69 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
Process variables can be accessed from outside the process with methods from the ExecutionService:
And from inside the process with methods from Execution interfaces passed to user code like
ActivityExecution and EventListenerExecution:
void removeVariables();
boolean hasVariables();
Set<String> getVariableKeys();
jBPM doesn't have a mechanism for detecting changes automatically to variable values. So if you get e.g. a
serializable collection from the process variables and add an element, then you need to set the changed
variable value explicitely for the changes to be saved to the DB.
Each execution is a variable scope. Variables declared in a nested execution level will 'see' their own
variables and variables declared in parent executions according to the normal scoping rules. With the
createVariable methods in the execution interfaces ActivityExecution and EventListenerExecution,
execution-local variables can be created.
70 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
In one of the future releases, we might add variable declaration in the jPDL process language.
java.lang.String
java.lang.Long
java.lang.Double
java.util.Date
java.lang.Boolean
java.lang.Character
java.lang.Byte
java.lang.Short
java.lang.Integer
java.lang.Float
serializable
For persistence of these variable, the type of the variable is checked in the order of this list. The first match
will determine how the variable is stored.
In customs, event-handlers and other user code, you can retrieve process variables. In case a process
variable is stored as a serialized object, you can just make updates to your deserialized objects without the
need for an explicit save. jBPM will manage deserialized process variables and update them automatically if
you change. For example (@see examples package org.jbpm.examples.serializedobject), look at this piece
of user code inside a custom's activity behaviour:
When the transaction commits in which this usercode was called, the updated messages set will be updated
in the database automatically.
When reading process variables that are stored in serialized format from the DB jBPM will monitor that
71 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
deserialized object. Right before the commit of the transaction, jBPM will serialize and update the variable
automatically if that is necessary. jBPM will ignore updates to the deserialized object if another object was
set as the value in that scope (which even can be of another type). jBPM will also skip updating of the
variable if the deserialized object has not been changed. The check to see if the object has changed is based
on comparing the byte arrays from serializing the object again and comparing that with the byte array that
was originally loaded from the db.
Variables can be declared directly in process definition (JPDL). These variables will be created at process
instance startup. There can be more than one variable definition.
As shown above variable values can be assigned in two ways: using attribute init-expr or by nesting init
descriptor (element object) within variable tags.
Note: Only one of value assignment can be used for a variable declaration.
72 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
Value for the variable as custom object, either this element or init-expr
object 1
attribute must be specified
Variables can be marked to be persisted as history records. This means that once process instance is ended
and its runtime information is removed, history details are preserved.
on variable declaration
Currently all variables are persisted in history as String values. Variable (regardless of its type) will be
converted to a string value using toString() method. In case of custom objects they should override
toString() method to provide string representation of the variable that will be available as history record.
This will provide an easy way for enabling convienient search capabilities based on variable values.
Chapter 8. Scripting
Only jUEL is configured as the scripting language. jUEL is an implementation of the Unified Expression
Language. For detailed description of how to use UEL, please refer to the JEE 5 Tutorial, section Unified
Expression Language
To configure other scripting languages then jUEL, please refer to the developer's guide (non supported).
Chapter 9. Configuration
9.1. Business calendar
9.2. Console
9.3. Email
73 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
<jbpm-configuration>
<process-engine-context>
<business-calendar>
<monday hours="9:00-18:00"/>
<tuesday hours="9:00-18:00"/>
<wednesday hours="9:00-18:00"/>
<thursday hours="9:00-18:00"/>
<friday hours="9:00-18:00"/>
<holiday period="01/02/2009 - 31/10/2009"/>
</business-calendar>
</process-engine-context>
</jbpm-configuration>
9.2. Console
By default the server host and port of the console web app are respectively localhost and 8080. It is not
hard to imagine situations where it is needed to change those defaults. Hence they are made configurable.
To customize, change the values of the default configuration (e.g. in the file "jbpm.console.cfg.xml") and
replace them with the values you want.
<jbpm-configuration>
<process-engine-context>
<string name="jbpm.console.server.host" value="myNewHost">
<string name="jbpm.console.server.port" value="9191">
</process-engine-context>
</jbpm-configuration>
9.3. Email
The default configuration looks for a jbpm.mail.properties classpath resource containing JavaMail
properties. To send mail through a server other than local host, set the mail.smtp.host property in the mail
properties file.
mail.smtp.host=localhost
mail.smtp.port=25
mail.from=noreply@jbpm.org
If the SMTP server requires authentication, the application can supply a custom authenticator in the
configuration file.
74 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution
<mail-session>
<mail-server>
<session-properties resource="jbpm.mail.properties" />
<authenticator class='BasicAuthenticator'>
<field name='userName'><string value='aguizar'/></field>
<field name='password'><string value='wontsay'/></field>
</authenticator>
</mail-server>
</mail-session>
In Java EE environments it is often the case that a mail session is already configured and bound to JNDI. To
employ such a session, specify its JNDI name in the configuration file.
<mail-session>
<mail-server session-jndi='java:comp/env/mail/smtp' />
</mail-session>
Important
If present, the session JNDI name has precedence over the session properties and the
authenticator. The combined absence of session-properties and session-jndi constitutes an
error.
Refer to the Developer Guide for advanced, yet unsupported, email settings.
75 de 75 08/09/2010 14:51