Sie sind auf Seite 1von 75

jBPM User Guide http://docs.jboss.

com/jbpm/v4/userguide/html_single/#thedistribution

jBPM User Guide

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

3. Graphical Process Designer (GPD)


3.1. Creating a new process file
3.2. Editing the process source
4. Deploying business archives
4.1. Deploying process files and process resources
4.2. Deploying classes

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

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

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

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

This documentation is best viewed in firefox. There are some known issues with internet explorer.

1.1. License and EULA


jBPM is distributed under the terms of the GNU Lesser General Public License (LGPL) and the JBoss End User
License Agreement (EULA). See the full LGPL license text and the full End User License Agreement.

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.

1.5. Contents of this userguide


In this user guide, we'll describe the jPDL process language in persistent execution mode. Persistent
execution mode means that process definitions, process executions and process history is stored in a
relational DB. This is the common way of how jBPM is used in practice.

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.

1.6. Migration from jBPM 3


Migration from jBPM 3 to jBPM 4 is not supported. Check out the developers guide for hints on how to
perform the migration.

1.7. Reporting problems

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:

=== Environment ==============================


- jBPM Version : which version of jBPM are you using?
- Database : which database and which version of that database
- JDK : which Java version are you using? use 'java -version' to find out
- Container : which container are you using? (JBoss, Tomcat, etc.)
- Configuration : is your jbpm.cfg.xml only using imports from the jbpm.jar
lib itself? or did you create a custom config file?
- Libraries : are you using the exact versions of the libs from inside the jbpm
distribution of the version that you're using? or did you change some of the libs?

=== Process ==================================


paste jPDL process here

=== API ===================================


paste the relevant code snippet that you use to invoke jBPM

=== Stacktrace ==============================


paste full stack trace here

=== Debug logs ==============================


paste debug logs here

=== Problem description =========================


Keep this part short and to the point. E.g. API doesn't work as expected.
or e.g. method ExecutionService.signalExecutionById throws exception.

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

2.1. The distribution


Unzip the jBPM download (jbpm-4.X.zip) to some location on your hard drive. You'll see following
subdirectories:

doc: User guide, javadocs and developers guide

examples: Example processes that are used in the user guide

install: Installation scripts for several environments

lib: Third party libs and some special jBPM libraries

src: Source files

migration: see developers guide

jbpm.jar: The jBPM main library archive

2.2. Required software


jBPM requires a JDK (standard java) version 5 or higher.

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

2.3. Getting started quickly


The demo setup is the simplest way to get started. This section describes the steps to complete the demo
setup.

If you have previously downloaded jboss-5.0.0.GA.zip, you can drop it in the


${jbpm.home}/install/downloads directory. Otherwise the script will download it for you, but it will take
some time (depending on your connection). The same is holds for eclipse-jee-galileo-win32.zip (or eclipse-
jee-galileo-linux-gtk(-x86_64).tar.gz on Linux and eclipse-jee-galileo-macosx-carbon.tar.gz on Mac OSX)

Open a command prompt and go do directory ${jbpm.home}/install. Then run

ant demo.setup.jboss

or

ant demo.setup.tomcat

That will

Install JBoss into the ${jbpm.home}/jboss-5.0.0.GA directory

Install jBPM into that JBoss installation.

Install hsqldb and start it in the background


Create the DB Schema

Start JBoss in the background.


Create an examples.bar business archive from the examples and deploy it to the jBPM DB.

5 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

Load the example users and groups from ${jbpm.home}/install/src/demo/example.identities.sql

Install eclipse into ${jbpm.home}/eclipse

Install the jBPM web console

Install the Signavio web modeler

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:

Table 2.1. Example console 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

2.4. Install scripts


The jBPM download contains an install directory with an ant build.xml file in it. You can use that to install
jBPM into your application environment.

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.

create.cfg: Creates a configuration in ${jbpm.home}/install/generated/cfg based on the current


parameters.

create.jbpm.schema: creates the jbpm tables in the database

create.user.webapp: Generates a basic webapp in ${jbpm.home}/install/generated/user-webapp

delete.jboss: Deletes the JBoss installation

delete.tomcat: Deletes the Tomcat installation

6 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

demo.teardown.jboss: Drops the jbpm db schema and stops jboss

demo.teardown.tomcat: Stops tomcat and then the hsqldb server (if needed)

drop.jbpm.schema: Drops the jbpm tables from the database

get.eclipse: Downloads eclipse if it is not available

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

hsqldb.databasemanager: Starts the hsqldb database manager

install.eclipse: Unzips eclipse, downloads eclipse if it is not available

install.jboss: Downloads JBoss if its not available and then unzips it

install.jbpm.into.jboss: Installs jBPM into JBoss

install.tomcat: Downloads tomcat to ${tomcat.distro.dir} if its not available and then unzips tomcat

install.jbpm.into.tomcat: Installs jBPM into tomcat

install.examples.into.tomcat: Deploys all the example processes

install.signavio.into.jboss: Installs signavio into jboss

install.signavio.into.tomcat: Installs signavio into tomcat

load.example.identities: Loads the example users and groups into the database

reinstall.jboss: Deletes the previous jboss installation and re-installs jboss

reinstall.jboss.and.jbpm: Deletes the previous jboss installation and re-installs jboss and installs
jbpm in it

reinstall.tomcat: Deletes the previous tomcat installation and re-installs tomcat

reinstall.tomcat.and.jbpm: Deletes the previous tomcat installation and re-installs tomcat and
installs jbpm in it

start.eclipse: Starts eclipse

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.

Also following properties are customizeable

database : Default value is hsqldb. Alternative values are mysql, oracle and postgresql

jboss.version : Default value is 5.0.0.GA. Alternative value is 5.1.0.GA

To customize the values for these properties, just use -D like this

ant -Ddatabase=postgresql demo.setup.jboss

Alternatively you can specify the customized values in ${user.home}/.jbpm4/build.properties

7 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

2.5. Library dependencies and configuration files


We provide support for installations of jBPM through our automatic ant scripts. Those scripts will put the right
libs and the right configuration files in the right location for you. If you want to create your own installation of
jBPM in your application, see the developers guide for more information.

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.

Specify property -Djboss.home=PathToYourJBossInstallation to customize the path to your JBoss


installation.

In JBoss, the ProcessEngine can be obtained from JNDI with


new InitialContext().lookup("java:/ProcessEngine"). The same ProcessEngine can be obtained with
Configuration.getProcessEngine()

2.7. Tomcat
The target install.jbpm.into.tomcat will install jBPM into your JBoss 5 installation.

2.8. Signavio web based process editor


The targets install.signavio.into.jboss and install.signavio.into.tomcat will install the Signavio
web based process editor into JBoss or Tomcat respectively.

2.9. User webapp


If you want to deploy jBPM as a part of your web application, use the install target create.user.webapp.
That will create a web application with jBPM in it, in the location
${jbpm.home}/install/generated/user-webapp.

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

2.10.1. Creating or dropping the database schema

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.

2.10.2. Upgrading an existing database

To upgrade, run target upgrade.jbpm.schema in the ${jbpm.home}/install directory.

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.

From 4.1 to 4.2 the upgrade procedure got more interesting.

A new table JBPM4_PROPERTY was introduced for storing engine-wide values.

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.

2.11. Graphical Process Designer (GPD)


Eclipse is used as the platform to host the jPDL graphical process designer. This section will describe how to
obtain and install Eclipse and how to install the GPD plugin in Eclipse.

2.11.1. Get Eclipse

You'll need Eclipse 3.5.0.

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.

2.11.2. Install the GPD plugin into eclipse

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

To add the update site to eclipse:

Help --> Install New Software...

Click Add...

In dialog Add Site dialog, click Archive...

Navigate to install/src/gpd/jbpm-gpd-site.zip and click 'Open'

Clicking OK in the Add Site dialog will bring you back to the dialog 'Install'

Select the jPDL 4 GPD Update Site that has appeared

Click Next... and then Finish

Approve the license


Restart eclipse when that is asked

Figure 2.1. Adding the GPD local archive site

2.11.3. Configuring the jBPM runtime

Click Window --> Preferences

Select JBoss jBPM --> jBPM 4 --> Runtime Locations

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

Click OK in the Add Location dialog

10 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

Figure 2.2. Defining jBPM Libraries

2.11.4. Define the jBPM User Library

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 Window --> Preferences

Select Java --> Build Path --> User Libraries

Click New...

Type name jBPM Libraries

Click Add JARs...

Navigate to the 'lib' folder of your jBPM installation

Select all jar files and click Open

Select the jBPM Libraries entry

Click Add JARs... again

Select the jbpm.jar file in the root of your jBPM installation

Click Open

Select entry Source attachment under jbpm.jar

Click Edit

In dialog Source Attachment Configuration, click External Folder...

Navigate to the src folder in your jBPM installation

Click Choose

11 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

Click OK twice to close all the open dialogs

Figure 2.3. Defining jBPM Libraries

2.11.5. Adding jPDL 4 schema to the catalog

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 Window --> Preferences

Select XML --> XML Catalog

Click 'Add...'

The 'Add XML Catalog Entry' dialog opens

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.

Click 'Open' and close all the dialogs

12 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

Figure 2.4. Adding jPDL 4 schema to the Catalog

2.11.6. Importing the Examples

In this section we will import the examples project in the installation in Eclipse

Select File --> Import...

Select General --> Existing Projects into Workspace

Click Next

Click Browse... to select a root directory

Navigate to the jBPM root installation directory


Click OK

The examples project is automatically found and selected

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!

2.11.7. Adding deployment with ant

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

Chapter 3. Graphical Process Designer (GPD)


3.1. Creating a new process file
3.2. Editing the process source

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.

Figure 3.1. The GPD

3.1. Creating a new process file


CRTL+N will open up the wizard selector.

Figure 3.2. Select wizard dialog

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

Figure 3.3. Create a new process dialog

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

3.2. Editing the process source


The GPD contains a 'Source' tab with the XML sources. These are directly editable in this tab and the
graphical view will reflect the changes when you switch back to the diagram.

Figure 3.4. Editing jPDL using the source view

Chapter 4. Deploying business archives


4.1. Deploying process files and process resources
4.2. Deploying classes

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.

4.1. Deploying process files and process resources


Process files and process resources have to be deployed in the process repository which is stored in the
database.

There is a jBPM ant task to deploy business archives (org.jbpm.pvm.internal.ant.JbpmDeployTask). The


JbpmDeployTask can deploy individual process files and business archives. They are deployed directly to the
database over a JDBC connection. So it is a requirement that the database is up and running before you can
deploy processes.

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

For creating a business archives, the jar task can be used.

<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" />

Then the ant task can be used like this

<jbpm-deploy file="${jbpm.home}/examples/target/examples.bar" />

Table 4.1. jbpm-deploy attributes:

Attribute Type Default Required? Description

A file to be deployed. Files ending with .xml will be


file file optional deployed as process files. Files ending with ar like .bar or
.jar will be deployed as business archives.
Points to the jbpm configuration file that has to be on the
cfg file jbpm.cfg.xml optional
classpath in which the jbpm-deploy task was defined.

Table 4.2. jbpm-deploy elements:

Element Multiplicity Description

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.

4.2. Deploying classes

17 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

Since version 4.2 jBPM has a process classloading mechanism as in jBPM 3.

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

5.1. Process definition, process instance and executions


A process definition is description of the steps in a procedure. For example, an insurance company could have
a loan process definition that describes the steps of how the company deals with loan requests.

18 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

Figure 5.1. The loan process definition example

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.

Figure 5.2. The loan process instance example

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

Figure 5.3. The loan executions example

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

ProcessEngine processEngine = new Configuration()


.buildProcessEngine();

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:

ProcessEngine processEngine = new Configuration()


.setResource("my-own-configuration-file.xml")
.buildProcessEngine();

There are other setXxxx methods that allow to specify the configuration content as an InputStream, an
xmlString, InputSource, URL or File.

From a ProcessEngine the following services can be obtained:

RepositoryService repositoryService = processEngine.getRepositoryService();


ExecutionService executionService = processEngine.getExecutionService();
TaskService taskService = processEngine.getTaskService();
HistoryService historyService = processEngine.getHistoryService();
ManagementService managementService = processEngine.getManagementService();

Process engine objects defined in the configuration can also be retrieved by type
(processEngine.get(Class<T>)) or by name (processEngine.get(String))

5.3. Deploying a process


The RepositoryService groups all methods to manage the repository of deployments. In this first example,
we'll deploy one process resource from the classpath with the RepositoryService:

20 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

String deploymentId = repositoryService.createDeployment()


.addResourceFromClasspath("org/jbpm/examples/services/Order.jpdl.xml")
.deploy();

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.

In this first example, we'll supply a name and nothing else.

<process name="Insurance claim">


...
</process>

Let's assume that this is the first time that this process gets deployed. Then it will get the following
properties:

Table 5.1. Process properties without key

Property Value Source

name Insurance claim process xml


key Insurance_claim generated
version 1 generated
id Insurance_claim-1 generated

And as a second example, we'll show how you can get shorter ids by specifying a process key:

<process name="Insurance claim" key="ICL">


...
</process>

Then the process definition properties look like this:

Table 5.2. Process properties with key

Property Value Source

21 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

Property Value Source


name Insurance claim process xml
key ICL process xml
version 1 generated
id ICL-1 generated

5.4. Deleting a deployment


Deleting a deployment will remove it from the DB.

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. Starting a new process instance

5.5.1. In latest

Simplest and most common way to start a new process instance for a process definition is like this:

ProcessInstance processInstance = executionService.startProcessInstanceByKey("ICL");

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.

5.5.2. Specific process 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");

5.5.3. With a key

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.

5.5.4. With variables

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.

Map<String,Object> variables = new HashMap<String,Object>();


variables.put("customer", "John Doe");
variables.put("type", "Accident");
variables.put("amount", new Float(763.74));

ProcessInstance processInstance =
executionService.startProcessInstanceByKey("ICL", variables);

5.6. Signalling a waiting execution


When using a state activity, the execution (or process instance) will halt when it arrives in a state, waiting
for a signal (aka external trigger). The method signalExecution and alike can be used for that. Executions
are referenced by an execution id (String).

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:

// assume that we know that after the next call


// the process instance will arrive in state external work

ProcessInstance processInstance =
executionService.startProcessInstanceById(processDefinitionId);
// or ProcessInstance processInstance =
// executionService.signalProcessInstanceById(executionId);

Execution execution = processInstance.findActiveExecutionIn("external work");


String executionId = execution.getId();

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.

List<Task> taskList = taskService.findPersonalTasks("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.

// read task variables


Set<String> variableNames = taskService.getVariableNames(taskId);
variables = taskService.getVariables(taskId, variableNames);

// write task variables


variables = new HashMap<String, Object>();
variables.put("category", "small");
variables.put("lires", 923874893);
taskService.setVariables(taskId, variables);

The taskService is also used to complete tasks

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:

If a task has one outgoing transition without a name then:

taskService.getOutcomes() returns a collection that includes one null value

taskService.completeTask(taskId) will take that outgoing transition


taskService.completeTask(taskId, null) will take that outgoing transition

24 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

taskService.completeTask(taskId, "anyvalue") will result in an exception

If a task has one outgoing transition with a name then:

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)

taskService.completeTask(taskId, "anyvalue") will result in an exception


taskService.completeTask(taskId, "myName") will take the transition with the given 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

taskService.completeTask(taskId, null) will take the transition without a name

taskService.completeTask(taskId, "anyvalue") will result in an exception

taskService.completeTask(taskId, "myName") will take the 'myName' transition

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

taskService.completeTask(taskId) will result in an exception, since there is no transition without a name

taskService.completeTask(taskId, null) will result in an exception, since there is no unnamed transition

taskService.completeTask(taskId, "anyvalue") will result in an exception

taskService.completeTask(taskId, "myName") will take the 'myName' transition

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'.

More on tasks in Section 6.2.6, “task”

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:

List<HistoryProcessInstance> historyProcessInstances = historyService


.createHistoryProcessInstanceQuery()
.processDefinitionId("ICL-1")
.orderAsc(HistoryProcessInstanceQuery.PROPERTY_STARTTIME)
.list();

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.

List<HistoryActivityInstance> histActInsts = historyService


.createHistoryActivityInstanceQuery()
.processDefinitionId("ICL-1")
.activityName("a")
.list();

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:

List<HistoryActivityInstance> histActInsts = historyService


.createHistoryActivityInstanceQuery()
.processInstanceId("ICL.12345")
.list();

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.

5.10. Query API


Starting from jBPM 4.0, a new API has been introuced with a query system that covers most of the queries
you can think of. Developers who need to write company-specific queries can of course still rely on
Hibernate. But for most use cases, the query API will be more then suffice. Queries can be written in a
unified way on all major jBPM concepts: Process Instances, Tasks, Deployments, Historical processes, etc.

For example:

List<ProcessInstance> results = executionService.createProcessInstanceQuery()


.processDefinitionId("my_process_definition")
.notSuspended()
.page(0, 50)
.list();

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.

Querying tasks is done in completely the same way:

List<Task> myTasks = taskService.createTaskQuery()


.processInstanceId(piId)
.assignee("John")
.page(100, 120)
.orderDesc(TaskQuery.PROPERTY_DUEDATE)
.list();

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

descending order based on the duedate.

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.

An example jPDL process file looks like this:

27 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

<?xml version="1.0" encoding="UTF-8"?>

<process name="Purchase order" xmlns="http://jbpm.org/4.4/jpdl">

<start>
<transition to="Verify supplier" />
</start>

<state name="Verify supplier">


<transition name="Supplier ok" to="Check supplier data" />
<transition name="Supplier not ok" to="Error" />
</state>

<decision name="Check supplier data">


<transition name="nok" to="Error" />
<transition name="ok" to="Completed" />
</decision>

<end name="Completed" />

<end name="Error" />

</process>

6.1. process
The top level element representing one process definition.

Table 6.1. process attributes:

Attribute Type Default Required? Description

name or label of the process used


name any text required to display to the process name in
user interactions.
identification to distinct different
if omitted, the key will
process definitions. Multiple
be generated based on
alpha numeric versions of a process with the same
the name by replacing
key characters and optional key can be deployed. The
all non-alpha-numeric
underscores key:name combination must
characters with
remain exactly the same for all
underscores
deployed versions.
one higher then highest
version number starting
version integer with 1 if no other process optional version number of this process
is deployed with the
same name/key.

Table 6.2. process elements:

Element Multiplicity Description

description 0..1 description text


a list of any activity type can be placed here. At least one start activity
activities 1..*
must be present.

28 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

6.2. Control flow activities

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.

Table 6.3. start attributes:

Attribute Type Default Required? Description

any name of the activity. Since a start activity cannot have


name optional
text incoming transitions, the name is optional.

Table 6.4. start elements:

Element Multiplicity Description

transition 1 the outgoing transition

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.

6.2.2.1. state sequence

Let's look at an example which shows states connected with transitions as a sequence

Figure 6.1. A sequence of states

29 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

<process name="StateSequence" xmlns="http://jbpm.org/4.4/jpdl">

<start>
<transition to="a" />
</start>

<state name="a">
<transition to="b" />
</state>

<state name="b">
<transition to="c" />
</state>

<state name="c" />

</process>

After you start an execution like this:

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.

Execution executionInA = processInstance.findActiveExecutionIn("a");


assertNotNull(executionInA);

processInstance = executionService.signalExecutionById(executionInA.getId());
Execution executionInB = processInstance.findActiveExecutionIn("b");
assertNotNull(executionInB);

processInstance = executionService.signalExecutionById(executionInB.getId());
Execution executionInC = processInstance.findActiveExecutionIn("c");
assertNotNull(executionInC);

6.2.2.2. state choice

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.

Figure 6.2. A choice between state

30 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

<process name="StateChoice" xmlns="http://jbpm.org/4.4/jpdl">

<start>
<transition to="wait for response" />
</start>

<state name="wait for response">


<transition name="accept" to="submit document" />
<transition name="reject" to="try again" />
</state>

<state name="submit document" />

<state name="try again" />

</process>

Let's start a new process instance for this process definition:

ProcessInstance processInstance = executionService


.startProcessInstanceByKey("StateChoice");

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:

String executionId = processInstance


.findActiveExecutionIn("wait for response")
.getId();

processInstance = executionService.signalExecutionById(executionId, "accept");

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 activity should be configured in one of the three following ways:

6.2.3.1. Decision conditions

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.

Table 6.5. decision.transition.condition attributes:

Attribute Type Default Required? Description

script that will be


expr expression required
evaluated in the

31 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

Attribute Type Default Required? Description


specified expression
language.
the default-expression-language the language in which
expression
lang taken from the script-manager optional expr is to be
language
configuration evaluated.

Example:

Figure 6.3. The decision conditions example process

<process name="DecisionConditions" >

<start>
<transition to="evaluate document" />
</start>

<decision name="evaluate document">


<transition to="submit document">
<condition expr="#{content=="good"}" />
</transition>
<transition to="try again">
<condition expr="#{content=="not so good"}" />
</transition>
<transition to="give up" />
</decision>

<state name="submit document" />

<state name="try again" />

<state name="give up" />

</process>

After starting a process instance with good content

Map<String, Object> variables = new HashMap<String, Object>();


variables.put("content", "good");
ProcessInstance processInstance =
executionService.startProcessInstanceByKey("DecisionConditions", variables);

32 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

The activity submit document will be active

assertTrue(processInstance.isActive("submit document"));

See the example unit test for more scenarios.

6.2.3.2. Decision expression

A decision expression evaluates to a String representing the name of an outgoing transition.

Table 6.6. decision attributes:

Attribute Type Default Required? Description

script that will be


evaluated in the
expr expression required
specified expression
language.
the default-expression-language the language in which
expression
lang taken from the script-manager optional expr is to be
language
configuration evaluated.

Example:

The decision expression example process

Figure 6.4. The decision expression example process

<process name="DecisionExpression" xmlns="http://jbpm.org/4.4/jpdl">

<start >
<transition to="evaluate document"/>
</start>

<decision name="evaluate document" expr="#{content}" >


<transition name="good" to="submit document" />
<transition name="bad" to="try again" />
<transition name="ugly" to="give up" />
</decision>

<state name="submit document" />


<state name="try again" />
<state name="give up" />

</process>

When you start an new process instance with good content like this

Map<String, Object> variables = new HashMap<String, Object>();


variables.put("content", "good");
ProcessInstance processInstance =
executionService.startProcessInstanceByKey("DecisionExpression", variables);

then the new execution will go to activity submit document.

33 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

See the example unit test for the other scenarios.

6.2.3.3. Decision handler

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.

public interface DecisionHandler {


String decide(OpenExecution execution);
}

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”.

Here's an example process of a decision using a DecisionHandler:

The decision handler example process

Figure 6.5. The decision handler example process

<process name="DecisionHandler">

<start>
<transition to="evaluate document" />
</start>

<decision name="evaluate document">


<handler class="org.jbpm.examples.decision.handler.ContentEvaluation" />
<transition name="good" to="submit document" />
<transition name="bad" to="try again" />
<transition name="ugly" to="give up" />
</decision>

<state name="submit document" />

<state name="try again" />

<state name="give up" />

</process>

The ContentEvaluation class looks like this

public class ContentEvaluation implements DecisionHandler {

public String decide(OpenExecution execution) {


String content = (String) execution.getVariable("content");
if (content.equals("you're great")) {
return "good";
}
if (content.equals("you gotta improve")) {
return "bad";
}
return "ugly";
}
}

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.

Table 6.7. join attributes:

Attribute Type Default Required? Description

The number of executions that should


nbr of arrive in this join before the join
multiplicity integer or expression incoming optional activates and push an execution out
transitions the single outgoing transition of the
join.
the hibernate lock mode applied on
{none, read,
the parent execution to prevent that
upgrade,
lockmode upgrade optional 2 concurrent transactions see each
upgrade_nowait,
other as not yet arrived at the join,
write}
causing a process deadlock.

6.2.4.1. Parallel split with fork

The fork activity allows a single path of execution to be split into two or more branches which can execute
activities concurrently.

Figure 6.6. Parallel split example process

35 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

<process name="ConcurrencyGraphBased" xmlns="http://jbpm.org/4.4/jpdl">

<start>
<transition to="fork"/>
</start>

<fork name="fork">
<transition to="send invoice" />
<transition to="load truck"/>
<transition to="print shipping documents" />
</fork>

<state name="send invoice" >


<transition to="final join" />
</state>

<state name="load truck" >


<transition to="shipping join" />
</state>

<state name="print shipping documents">


<transition to="shipping join" />
</state>

<join name="shipping join" >


<transition to="drive truck to destination" />
</join>

<state name="drive truck to destination" >


<transition to="final join" />
</state>

<join name="final join" >


<transition to="end"/>
</join>

<end name="end" />

</process>

6.2.5. end

Ends the execution.

6.2.5.1. end process instance

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.

Figure 6.7. The end event

36 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

<process name="EndProcessInstance" xmlns="http://jbpm.org/4.4/jpdl">

<start>
<transition to="end" />
</start>

<end name="end" />

</process>

When a new process instance is created, it immediately ends.

6.2.5.2. end execution

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"

Table 6.8. end execution attributes:

Attribute Type Default Required? Description

specifies if the whole process


instance should be ended or just
ends {processinstance|execution} processinstance optional
the path of execution that
arrives in the end activity.

6.2.5.3. end multiple

A process can have multiple end events. This can be handy to indicate different outcomes of a process
instance. For example

Figure 6.8. Multiple end events

37 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

<process name="EndMultiple" xmlns="http://;jbpm.org/4/jpdl">

<start>
<transition to="get return code" />
</start>

<state name="get return code">


<transition name="200" to="ok"/>
<transition name="400" to="bad request"/>
<transition name="500" to="internal server error"/>
</state>

<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.

ProcessInstance processInstance = executionService.startProcessInstanceByKey("EndMultiple");


String pid = processInstance.getId();
processInstance = executionService.signalExecutionById(pid, "400");

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.

6.2.5.4. end state

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.

Table 6.9. end execution attributes:

Attribute Type Default Required? Description

state String optional the state assigned to the execution.

Take for example the following process.

Figure 6.9. Different end states

38 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

<process name="EndState" xmlns="http://jbpm.org/4.4/jpdl">

<start>
<transition to="get return code"/>
</start>

<state name="get return code">


<transition name="200" to="ok"/>
<transition name="400" to="bad request" />
<transition name="500" to="internal server error"/>
</state>

<end name="ok" state="completed"/>


<end-cancel name="bad request"/>
<end-error name="internal server error"/>

</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

Creates a task for a person in the task component.

6.2.6.1. task assignee

A simple task that will be assigned to a specific user

Table 6.10. task attributes:

Attribute Type Default Required? Description

userId referring to the person that is responsible for


assignee expression optional
completing this task.

Figure 6.10. The task assignee example process

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}">

<transition to="wait" />


</task>

<state name="wait" />

</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.

Here's the Order class used in our example:

public class Order implements Serializable {

String owner;

public Order(String owner) {


this.owner = owner;
}

public String getOwner() {


return owner;
}

public void setOwner(String owner) {


this.owner = owner;
}
}

Next a new process instance is created with an order as a process variable.

Map<String, Object> variables = new HashMap<String, Object>();


variables.put("order", new Order("johndoe"));
ProcessInstance processInstance = executionService
.startProcessInstanceByKey("TaskAssignee", variables);

Then the task list for johndoe can be obtained like this.

List<Task> taskList = taskService.findPersonalTasks("johndoe");

Note that it is also possible to put plain text like assignee="johndoe". In that case the task will be assigned
to johndoe.

6.2.6.2. task candidates

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.

Table 6.11. task attributes:

Attribute Type Default Required? Description

resolves to a comma separated list of groupIds.


candidate-groups expression optional All the people in the groups will be candidates
for this task.
resolves to a comma separated list of userIds.
candidate-users expression optional
All the users will be candidates for this task.

Figure 6.11. The task candidates example process

Here's an example process using task candidates:

<process name="TaskCandidates">

<start>
<transition to="review" />
</start>

<task name="review"
candidate-groups="sales-dept">

<transition to="wait" />


</task>

<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");

identityService.createUser("johndoe", "johndoe", "John", "Doe");


identityService.createMembership("johndoe", "sales-dept");

identityService.createUser("joesmoe", "joesmoe", "Joe", "Smoe");


identityService.createMembership("joesmoe", "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.

6.2.6.3. task assignment handler

An AssignmentHandler can be used to calculate the assignee and the candidates for a task
programmatically.

public interface AssignmentHandler extends Serializable {

/** 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”

Let's look at the task assignment example process.

Figure 6.12. The task assignment handler example process

42 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

<process name="TaskAssignmentHandler" xmlns="http://jbpm.org/4.4/jpdl">

<start g="20,20,48,48">
<transition to="review" />
</start>

<task name="review" g="96,16,127,52">


<assignment-handler class="org.jbpm.examples.task.assignmenthandler.AssignTask">
<field name="assignee">
<string value="johndoe" />
</field>
</assignment-handler>
<transition to="wait" />
</task>

<state name="wait" g="255,16,88,52" />

</process>

The referenced class AssignTask looks like this:

public class AssignTask implements AssignmentHandler {

String assignee;

public void assign(Assignable assignable, OpenExecution execution) {


assignable.setAssignee(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.

6.2.6.4. task swimlanes

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.

Table 6.12. task attributes:

Attribute Type Default Required? Description

swimlane swimlane (string) optional refers to a swimlane that is declared in the process

Swimlanes can be declared inside a process element:

Table 6.13. swimlane attributes:

43 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

Attribute Type Default Required? Description

Name for this swimlane. This is the name that


swimlane
name required will be referenced by task swimlane
(string)
attributes.
userId referring to the person that is
assignee expression optional
responsible for completing this task.
resolves to a comma separated list of
candidate-groups expression optional groupIds. All the people in the groups will be
candidates for this the tasks in this swimlane.
resolves to a comma separated list of userIds.
candidate-users expression optional All the users will be candidates for the tasks in
this swimlane.

Figure 6.13. The task swimlane example process

The task swimlane example has the following process file :

<process name="TaskSwimlane" xmlns="http://jbpm.org/4.4/jpdl">

<swimlane name="sales representative"


candidate-groups="sales-dept" />

<start>
<transition to="enter order data" />
</start>

<task name="enter order data"


swimlane="sales representative">

<transition to="calculate quote"/>


</task>

<task
name="calculate quote"
swimlane="sales representative">
</task>

</process>

In this example we create the following information in the identity component:

identityService.createGroup("sales-dept");

identityService.createUser("johndoe", "johndoe", "John", "Doe");


identityService.createMembership("johndoe", "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.

Next, John Doe can complete the task like this:

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.

6.2.6.5. task variables

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.

Getting task variables can be done like this:

List<Task> taskList = taskService.findPersonalTasks("johndoe");

Task task = taskList.get(0);


long taskDbid = task.getDbid();

Set<String> variableNames = taskService.getVariableNames(taskDbid);

Map<String, Object> variables = taskService.getVariables(taskDbid, variableNames);

And setting task variables can be done like this:

variables = new HashMap<String, Object>();


variables.put("category", "small");
variables.put("lires", 923874893);

taskService.setVariables(taskDbid, variables);

6.2.6.6. e-mail support in tasks

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.

Table 6.14. task elements

Element Multiplicity Description

Sends a notification message when a task is assigned. If no template is


notification 0..1 referenced or supplied inline, mail support falls back on the template named
task-notification.
Sends a reminder message at specific intervals. If no template is referenced or
reminder 0..1
supplied inline, mail support falls back on the template named task-reminder.

Table 6.15. notification attributes:

45 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

Attribute Type Default Required? Description

Specifies if an asynchronous continuation should be


{sync | async |
continue sync optional introduced right before sending this notification
exclusive}
email.

Table 6.16. reminder attributes:

Attribute Type Default Required? Description

duration (plain string or Delay before a reminder email should be


duedate required
containing expression) send.
duration (plain string or Delay after a subsequent reminder email
repeat optional
containing expression) should be send
Specifies if an asynchronous continuation
{sync | async |
continue sync optional should be introduced right before sending
exclusive}
this notification email.

Here is a basic example that accepts the default templates.

<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.

Table 6.17. sub-process attributes:

Attribute Type Default Required? Description

Identifies the sub process by the id.


either this or This means that a specific version of a
string or
sub-process-id sub-process-key is process definition is referenced. Sub
expression
required process id can be specified as simple
text or EL expression.
Identifies the sub process by the key.
This means that the latest version of
the process definition with the given
either this or
string or key is referenced. The latest version of
sub-process-key sub-process-key is
expression the process is looked up each time the
required
activity executes. Sub process key can
be specified as simple text or EL
expression.
Expression that is evaluated when the
required when sub process instance ends. The value is
transitions have then used for outcome transition
outcome expression
outcome-value's mapping. Add outcome-value
specified elements to the outgoing transitions of

46 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

Attribute Type Default Required? Description


this sub-process activity.

Table 6.18. sub-process elements:

Element Multiplicity Description

Declares a variable that is passed to the sub process instance when it is


parameter-in 0..*
created.
Declares a variable that will be set in the super process execution when
parameter-out 0..*
the sub process ends.

Table 6.19. parameter-in attributes:

Attribute Type Default Required? Description

The name of the sub process variable in which


subvar string required
the value is set.
exactly one of {'var',
The name of the variable in the super process
var string 'expr'} is required to
execution context.
specify the value
exactly one of {'var', An expression that will be resolved in the super
expr string 'expr'} is required to process execution context. The resulting value
specify the value will be set in the sub process variable.
The scripting language in which the expression
lang string juel optional
should be resolved.

Table 6.20. parameter-out attributes:

Attribute Type Default Required? Description

The name of the variable in the super process


var string required
execution context in which the value will be set.
exactly one of {'subvar',
The name of the sub process variable from
subvar string 'expr'} is required to
which the value will be taken.
specify the value
exactly one of {'subvar', An expression that will be resolved in the sub
expr string 'expr'} is required to process execution context. The resulting value
specify the value will be set in the super process variable.
The scripting language in which the expression
lang string juel optional
should be resolved.

Table 6.21. Extra transition elements in case of outcome variable mappings:

Element Multiplicity Description

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.

6.2.7.1. sub-process variables

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.

The parent process involves a document that needs to be reviewed.

Figure 6.14. The subprocess document example process

<process name="SubProcessDocument" xmlns="http://jbpm.org/4.4/jpdl">

<start>
<transition to="review" />
</start>

<sub-process name="review"
sub-process-key="SubProcessReview">

<parameter-in var="document" subvar="document" />


<parameter-out var="reviewResult" subvar="result" />

<transition to="wait" />


</sub-process>

<state name="wait"/>

</process>

The review process is a reusable process for all kinds of reviews.

Figure 6.15. The subprocess review example process

<process name="SubProcessReview" xmlns="http://jbpm.org/4.4/jpdl">

<start>
<transition to="get approval"/>
</start>

<task name="get approval"


assignee="johndoe">

<transition to="end"/>
</task>

<end name="end" />

</process>

48 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

The document process is started with a document variable:

Map<String, Object> variables = new HashMap<String, Object>();


variables.put("document", "This document describes how we can make more money...");

ProcessInstance processInstance = executionService


.startProcessInstanceByKey("SubProcessDocument", variables);

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.

List<Task> taskList = taskService.findPersonalTasks("johndoe");


Task task = taskList.get(0);

We can see that the document has been passed from the super process instance to the sub process instance:

String document = (String) taskService.getVariable(task.getDbid(), "document");


assertEquals("This document describes how we can make more money...", document);

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.

Map<String, Object> variables = new HashMap<String, Object>();


variables.put("result", "accept");
taskService.setVariables(task.getDbid(), variables);

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.

6.2.7.2. sub-process outcome value

In the SubProcessOutcomeValueTest example, the value of a sub process variable is used to select the
outgoing transition of the sub-process activity.

Figure 6.16. The subprocess document example process

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}">

<transition name="ok" to="next step" />


<transition name="nok" to="update" />
<transition name="reject" to="close" />
</sub-process>

<state name="next step" />


<state name="update" />
<state name="close" />

</process>

The SubProcessReview is the same as above in the subprocess variables example:

Figure 6.17. The subprocess review example process for outcome value

<process name="SubProcessReview" xmlns="http://jbpm.org/4.4/jpdl">

<start>
<transition to="get approval"/>
</start>

<task name="get approval"


assignee="johndoe">

<transition to="end"/>
</task>

<end name="end" />

</process>

A new document process instance is started like usual:

ProcessInstance processInstance = executionService


.startProcessInstanceByKey("SubProcessDocument");

Then task is fetched from johndoe's task list

List<Task> taskList = taskService.findPersonalTasks("johndoe");


Task task = taskList.get(0);

Then the result variable is set and the task is completed.

50 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

Map<String, Object> variables = new HashMap<String, Object>();


variables.put("result", "ok");
taskService.setVariables(task.getId(), variables);
taskService.completeTask(task.getDbid());

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.

6.2.7.3. sub-process outcome activity

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">

<transition name="ok" to="next step" />


<transition name="nok" to="update" />
<transition name="reject" to="close" />
</sub-process>

<state name="next step" />


<state name="update" />
<state name="close" />

</process>

The SubProcessReview now has multiple end activities:

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

<process name="SubProcessReview" xmlns="http://jbpm.org/4.4/jpdl">

<start>
<transition to="get approval"/>
</start>

<task name="get approval"


assignee="johndoe">

<transition name="ok" to="ok"/>


<transition name="nok" to="nok"/>
<transition name="reject" to="reject"/>
</task>

<end name="ok" />


<end name="nok" />
<end name="reject" />

</process>

A new document process instance is started like usual:

ProcessInstance processInstance = executionService


.startProcessInstanceByKey("SubProcessDocument");

Then task is fetched from johndoe's task list

List<Task> taskList = taskService.findPersonalTasks("johndoe");


Task task = taskList.get(0);

Then the task is completed with outcome ok.

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.

The example test case also shows the other scenarios.

6.2.8. custom

Invokes user code that implements custom behaviour of an activity.

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

<process name="Custom" xmlns="http://jbpm.org/4.4/jpdl">

<start >
<transition to="print dots" />
</start>

<custom name="print dots"


class="org.jbpm.examples.custom.PrintDots">

<transition to="end" />


</custom>

<end name="end" />

</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.

public class PrintDots implements ExternalActivityBehaviour {

private static final long serialVersionUID = 1L;

public void execute(ActivityExecution execution) {


String executionId = execution.getId();

String dots = ...;

System.out.println(dots);

execution.waitForSignal();
}

public void signal(ActivityExecution execution,


String signalName,
Map<String, ?> parameters) {
execution.take(signalName);
}
}

6.3. Automatic activities

6.3.1. java

The Java task. A process execution will execute the method of the class that is configured in this activity.

Table 6.22. java attributes:

Attribute Type Default Required? Description

The fully qualified classname. See Section 6.7.2,


either 'class' or “User code classloading” for classloading
class classname 'expr' has to be information. The user code object will be lazy
specified initialized and cached as part of the process
definition.

53 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

Attribute Type Default Required? Description


either 'expr' or
An expression that returns the target object on
expr expression 'class' has to be
which the method should be invoked.
specified
method methodname required The name of the method to invoke
The name of the variable in which the return
var variablename optional
value should be stored.

Table 6.23. java elements:

Element Multiplicity Description

describes a configuration value to inject in a memberfield before the method is


field 0..*
invoked.
arg 0..* method parameters

Consider the following example.

Figure 6.20. A java task

54 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

<process name="Java" xmlns="http://jbpm.org/4.4/jpdl">

<start >
<transition to="greet" />
</start>

<java name="greet"
class="org.jbpm.examples.java.JohnDoe"
method="hello"
var="answer"
>

<field name="state"><string value="fine"/></field>


<arg><string value="Hi, how are you?"/></arg>

<transition to="shake hand" />


</java>

<java name="shake hand"


expr="#{hand}"
method="shake"
var="hand"
>

<arg><object expr="#{joesmoe.handshakes.force}"/></arg>
<arg><object expr="#{joesmoe.handshakes.duration}"/></arg>

<transition to="wait" />


</java>

<state name="wait" />

</process>

Classes involved:

public class JohnDoe {

String state;
Session session;

public String hello(String msg) {


if ( (msg.indexOf("how are you?")!=-1)
&& (session.isOpen())
) {
return "I'm "+state+", thank you.";
}
return null;
}
}

public class JoeSmoe implements Serializable {

static Map<String, Integer> handshakes = new HashMap<String, Integer>();


{
handshakes.put("force", 5);
handshakes.put("duration", 12);
}

public Map<String, Integer> getHandshakes() {


return handshakes;
}
}

55 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

public class Hand implements Serializable {

private boolean isShaken;

public Hand shake(Integer force, Integer duration) {


if (force>3 && duration>7) {
isShaken = true;
}

return this;
}

public boolean isShaken() {


return isShaken;
}
}

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.

There are 2 ways of specifying a script:

6.3.2.1. script expression

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.

Table 6.24. script expression attributes:

Attribute Type Default Required? Description

the expression text to


expr text required
evaluate.
scripting language name the default expression
the language in which the
lang as defined in Chapter 8, language as defined in optional
expression is specified.
Scripting Chapter 8, Scripting
name of the variable in
var variablename optional which the return value

56 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

Attribute Type Default Required? Description


should be stored.

In the next example, we'll see how a script activity with an expression and how the result is stored in a
variable.

Figure 6.21. The script.expression example process

<process name="ScriptExpression" xmlns="http://jbpm.org/4.4/jpdl">

<start>
<transition to="invoke script" />
</start>

<script name="invoke script"


expr="Send packet to #{person.address}"
var="text">

<transition to="wait" />


</script>

<state name="wait"/>

</process>

This example uses a Person class that looks like this.

public class Person implements Serializable {

String address;

public Person(String address) {


this.address = address;
}

public String getAddress() {


return address;
}

public void setAddress(String address) {


this.address = address;
}
}

When starting a process instance for this process, we supply a person with a given address property as
variable person.

Map<String, Object> variables = new HashMap<String, Object>();


variables.put("person", new Person("Honolulu"));

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

6.3.2.2. script text

The second way of specifying a script is with a text element. This is convenient when the script text spans
multiple lines.

Table 6.25. script text attributes:

Attribute Type Default Required? Description

scripting language name the default scripting


the language in which the
lang as defined in Chapter 8, language as defined in optional
script is specified.
Scripting Chapter 8, Scripting
name of the variable in
var variablename optional which the return value
should be stored.

Table 6.26. script text elements:

Element Multiplicity Description

text 1 contains the script text

For example

Figure 6.22. The script.text example process

<process name="ScriptText" xmlns="http://jbpm.org/4.4/jpdl">

<start>
<transition to="invoke script" />
</start>

<script name="invoke script"


var="text">
<text>
Send packet to #{person.address}
</text>
<transition to="wait" />
</script>

<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.

Table 6.27. hql attributes:

Attribute Type Default Required? Description

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.

Table 6.28. hql elements:

Element Multiplicity Description

query 1 The HQL query.


parameter 0..* The query parameters

For example:

Figure 6.23. The hql example process

59 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

<process name="Hql" xmlns="http://jbpm.org/4.4/jpdl">

<start>
<transition to="get process names" />
</start>

<hql name="get process names"


var="activities with o">
<query>
select activity.name
from org.jbpm.pvm.internal.model.ActivityImpl as activity
where activity.name like :activityName
</query>
<parameters>
<string name="activityName" value="%o%" />
</parameters>
<transition to="count activities" />
</hql>

<hql name="count activities"


var="activities"
unique="true">
<query>
select count(*)
from org.jbpm.pvm.internal.model.ActivityImpl
</query>
<transition to="wait" />
</hql>

<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.

Table 6.29. mail attributes

Attribute Type Default Required? Description

Reference to a mail-template element in the configuration


template string no file. If absent, the template must be specified inline using the
child elements.

Table 6.30. mail elements

Element Multiplicity Description

from 0..1 list of sender(s)

60 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

Element Multiplicity Description


to 1 list of primary recipients
cc 0..1 list of carbon copy recipients
bcc 0..1 list of blind carbon copy recipients
subject 1 text content of this element becomes the message subject
text 0..1 text content of this element becomes the message text content
html 0..1 text content of this element becomes the message HTML content
attachments 0..1 each attachment is configured in a separate subelement

Table 6.31. attachment attributes

Attribute Type Default Required? Description

File name associated with this attachment. If


no, unless expression absent, data sources that encapsulate files such
name string
is present as resource, file and url provide a reasonable
fallback value.
Descriptive information associated with this
description string no
attachment.
Expression that evaluates to a representation of
expression string the attachment data in the form of a Java object.
Useful to extract content from process variables.
Path to the attachment data in the file system.
file string one of expression,
The denoted file must exist.
file, url or resource
Location of the attachment data in the worldwide
url string must be present
web. The pointed resource must exist.
Name of the resource containing the attachment
resource string data in the class path. The denoted resource
must exist.
no, unless expression MIME type of the object returned by the
mime-type string
is present expression.

Example usage:

<process name="InlineMail" xmlns="http://jbpm.org/4.4/jpdl">


<start>
<transition to="send birthday reminder note" />
</start>
<mail name="send birthday reminder note">
<to addresses="johnDoe@some-company.com" />
<subject>Reminder: ${person} celebrates his birthday!</subject>
<text>Do not forget: ${date} is the birthday of ${person} </text>
<attachments>
<attachment resource="org/example/birthday_card.png"/>
<attachment name="picture.jpg" expression="${picture}" mime-type="image/jpeg"/>
</attachments>
<transition to="end" />
</mail>
<state name="end"/>
</process>

6.4. Common activity contents

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:

Table 6.32. Common activity attributes:

Attribute Type Default Required? Description

name any text required name of the activity

Table 6.33. Common activity elements:

Element Multiplicity Description

transition 0..* the outgoing transitions

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.

The EventListener interface looks like this:

public interface EventListener extends Serializable {

void notify(EventListenerExecution execution) throws Exception;

All automatic activities can be used as event listeners as well.

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.

Table 6.34. on attributes:

Attribute Type Default Required? Description

event {start | end} required name name of the event

Table 6.35. on elements:

Element Multiplicity Description

event-listener 0..* An event listener implementation object.


any automatic activity 0..*

Table 6.36. event listener attributes:

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:

Attribute Type Default Required? Description

{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”

6.5.1. Event listener example

Let's look at an example process with event listeners:

Figure 6.24. The event listener example process

<process name="EventListener" xmlns="http://jbpm.org/4.4/jpdl">

<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>

LogListener will maintain a list of logs as a process variable:

63 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

public class LogListener implements EventListener {

// value gets injected from process definition


String msg;

public void notify(EventListenerExecution execution) {


List<String> logs = (List<String>) execution.getVariable("logs");
if (logs==null) {
logs = new ArrayList<String>();
execution.setVariable("logs", logs);
}

logs.add(msg);

execution.setVariable("logs", logs);
}
}

Next, we start a new process instance.

ProcessInstance processInstance = executionService.startProcessInstanceByKey("EventListener");

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.

Execution execution = processInstance.findActiveExecutionIn("wait");


executionService.signalExecutionById(execution.getId());

The list of log messages will now look like this:

[start on process definition,


start on activity wait,
end on activity wait,
take transition]

6.5.2. Event propagation

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.

6.6. Asynchronous continuations


Each invocation of ExecutionService.startProcessInstanceById(...) or
ExecutionService.signalProcessInstanceById(...) will cause the process to be executed in the thread
it was called from (=client). In other words, those methods will only return after the process execution has
arrived in a wait state.

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.

Table 6.37. Attribute of any activity, transition or on:

Attribute Type Default Required? Description

{sync | async | indicates if an asynchronous continuation should be


continue sync optional
exclusive} performed before the element is executed.

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.

Let's look at a couple of examples.

6.6.1. Async activity

Figure 6.25. The async activity example process

65 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

<process name="AsyncActivity" xmlns="http://jbpm.org/4.4/jpdl">

<start>
<transition to="generate pdf"/>
</start>

<java name="generate pdf"


continue="async"
class="org.jbpm.examples.async.activity.Application"
method="generatePdf" >
<transition to="calculate primes"/>
</java>

<java name="calculate primes"


continue="async"
class="org.jbpm.examples.async.activity.Application"
method="calculatePrimes">
<transition to="end"/>
</java>

<end name="end"/>

</process>

public class Application {

public void generatePdf() {


// assume long automatic calculations here
}

public void calculatePrimes() {


// assume long automatic calculations here
}
}

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:

Job job = managementService.createJobQuery()


.processInstanceId(processInstanceId)
.uniqueResult();
managementService.executeJob(job.getDbid());

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.

6.6.2. Async fork

66 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

Figure 6.26. The async fork example process

<process name="AsyncFork" xmlns="http://jbpm.org/4.4/jpdl">

<start >
<transition to="fork"/>
</start>

<fork >
<on event="end" continue="exclusive" />
<transition />
<transition />
</fork>

<java class="org.jbpm.examples.async.fork.Application" >


<transition />
</java>

<java class="org.jbpm.examples.async.fork.Application" >


<transition />
</java>

<join >
<transition to="end"/>
</join>

<end />

</process>

public class Application {

public void shipGoods() {


// assume automatic calculations here
}

public void sendBill() {


// assume automatic calculations here
}
}

By placing the asynchronous continuation on the end event of the fork


(<on event="end" continue="exclusive" />), each forked execution that takes a transition out of the
fork will be continued asynchronously.

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

ProcessInstance processInstance = executionService.startProcessInstanceByKey("AsyncFork");


String processInstanceId = processInstance.getId();

List<Job> jobs = managementService.createJobQuery()


.processInstanceId(processInstanceId)
.list();

assertEquals(2, jobs.size());

Job job = jobs.get(0);

// here we simulate execution of the job,


// which is normally done by the job executor
managementService.executeJob(job.getDbid());

job = jobs.get(1);

// here we simulate execution of the job,


// which is normally done by the job executor
managementService.executeJob(job.getDbid());

Date endTime = historyService


.createHistoryProcessInstanceQuery()
.processInstanceId(processInstance.getId())
.uniqueResult()
.getEndTime();

assertNotNull(endTime);

6.7. User code


Various elements in the jPDL process language refer to a an object on which an interface method will be
invoked. This section describes the common attributes and elements for the instantiation and configuration of
such user code objects.

custom

event-listener

assignment-handler in task

handler in decision

condition in transition

6.7.1. User code configuration

Table 6.38. attributes:

Attribute Type Default Required? Description

one of The fully qualified classname. Instantiation is done


class classname {class|expr} is only once and the user object is cached as part of
required the process definition.
Expression for which the resulting value will be
one of
taken as the target object. Expressions will be
expr expression {class|expr} is
evaluated for every usage. In other words, the
required
resulting value of the evaluation will not be cached.

68 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

Table 6.39. user code configuration elements:

Element Multiplicity Description

describes a configuration value to be injected directly in a memberfield before


field 0..*
this user class is used.
describes a configuration value to injected through a setter method before this
property 0..*
user object is used.

Table 6.40. field and property attributes:

Attribute Type Default Required? Description

name string required the name of the field or property.

Table 6.41. field and property contained element:

field and property elements have exactly one child element that represents the value that will be injected.

Element Multiplicity Description

string 0..1 a java.lang.String


int 0..1 a java.lang.Integer
long 0..1 a java.lang.Long
float 0..1 a java.lang.Float
double 0..1 a java.lang.Double
true 0..1 Boolean.TRUE
false 0..1 Boolean.FALSE
object 0..1 a object that will be instantiated with reflection

Table 6.42. Attribute for basic type string, int, long, floatand double:

Attribute Type Default Required? Description

value text required text value that will be parsed to the respective type

6.7.2. User code classloading

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).

Objects that are referenced by an expression are calculated dynamically.

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

7.1. Variable scoping


7.2. Variable types
7.3. Updating serialized process variables
7.4. Declared variables
7.5. Variables history

Process variables can be accessed from outside the process with methods from the ExecutionService:

ProcessInstance startProcessInstanceById(String processDefinitionId, Map<String, Object> variables);

ProcessInstance startProcessInstanceById(String processDefinitionId, Map<String, Object> variables,

ProcessInstance startProcessInstanceByKey(String processDefinitionKey, Map<String, ?> variables);

ProcessInstance startProcessInstanceByKey(String processDefinitionKey, Map<String, ?> variables, Str

void setVariable(String executionId, String name, Object value);

void setVariables(String executionId, Map<String, ?> variables);

Object getVariable(String executionId, String variableName);

Set<String> getVariableNames(String executionId);

Map<String, Object> getVariables(String executionId, Set<String> variableNames);

And from inside the process with methods from Execution interfaces passed to user code like
ActivityExecution and EventListenerExecution:

Object getVariable(String key);

void setVariables(Map<String, ?> variables);

boolean hasVariable(String key);

boolean removeVariable(String key);

void removeVariables();

boolean hasVariables();

Set<String> getVariableKeys();

Map<String, Object> getVariables();

void createVariable(String key, Object value);

void createVariable(String key, Object value, String typeName);

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.

7.1. Variable scoping


By default variables are created in the top level process instance scope. This means they are visible and
accessible in all the paths of execution of the whole process instance. Process variables are created
dynamically. Meaning that a variable is created the first time it is set through one of these methods.

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.

7.2. Variable types


jBPM supports following Java types as process variables:

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

byte[] (byte array)

char[] (char array)

hibernate entity with a long id

hibernate entity with a string id

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.

7.3. Updating serialized process variables


(Since jBPM 4.3)

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:

public class UpdateSerializedVariables implements ActivityBehaviour {

public void execute(ActivityExecution execution) {


Set<String> messages = (Set<String>) execution.getVariable("messages");
messages.clear();
messages.add("i");
messages.add("was");
messages.add("updated");
}
}

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.

7.4. Declared variables


(Since jBPM 4.4)

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.

There are several possible ways for declaring variable:

declare String variable initialized with static text

<variable name="declaredVar" type="string" init-expr="testing declared variable"/>

declare custom variable initialized with EL

<variable name="declaredVar" type="long" init-expr="#{anotherVar}"/>

declare custom variable initialized with serializable class

<variable name="declaredVar" type="serializable" >


<object class="org.jbpm.examples.variable.declared.HistoryVariable" />
</variable>

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.

Table 7.1. Attribute for variable element:

Attribute Type Default Required? Description

name text required name of the variable


type of the variable, must refer to types defined
type text required
in jbpm.variable.types.xml
text (EL value for the variable, this attribute or nested
init-expr optional
expression) element must be given
init-expr-type text UEL optional defines language for expression evaluation
indicates wheater variable should be stored in
history or not - default false, for more
history boolean false optional
information about history see Section 7.5,
“Variables history”

72 de 75 08/09/2010 14:51
jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

Table 7.2. Nested element for variable:

Element Multiplicity Description

Value for the variable as custom object, either this element or init-expr
object 1
attribute must be specified

7.5. Variables history


(Since jBPM 4.4)

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.

History can be enabled for variable in two ways:

via public API ExecutionService:

void createVariable(String executionId, String name, Object value, boolean historyEnabled);

void createVariables(String executionId, Map<String, ?> variables, boolean historyEnabled);

on variable declaration

<variable name="declaredVar" type="string" init-expr="testing declared variable" his

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.

Access to history variables is given via HistoryService methods:

Object getVariable(String processInstnceId, String name);

Map<String, Object> getVariables(String processInstnceId, Set<String> variableNames);

Set<String> getVariableNames(String processInstnceId);

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

9.1. Business calendar


To customize the business calendar configuration, remove the default business calendar configuration import
and replace it with the custom values.

<jbpm-configuration>

<import resource="jbpm.businesscalendar.cfg.xml" />


...

<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

Das könnte Ihnen auch gefallen