jbpm user guide

75
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 jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution 1 de 75 08/09/2010 14:51

Upload: leonardojlbcyahoocombr

Post on 26-Mar-2015

1.324 views

Category:

Documents


17 download

TRANSCRIPT

Page 1: jBPM User Guide

jBPM User Guide

1. Introduction1.1. License and EULA1.2. Downloads

1.3. Sources1.4. What is it

1.5. Contents of this userguide1.6. Migration from jBPM 31.7. Reporting problems

2. Installation2.1. The distribution

2.2. Required software2.3. Getting started quickly

2.4. Install scripts2.5. Library dependencies and configuration files2.6. JBoss

2.7. Tomcat2.8. Signavio web based process editor

2.9. User webapp2.10. Database

2.10.1. Creating or dropping the database schema

2.10.2. Upgrading an existing database2.11. Graphical Process Designer (GPD)

2.11.1. Get Eclipse2.11.2. Install the GPD plugin into eclipse

2.11.3. Configuring the jBPM runtime2.11.4. Define the jBPM User Library2.11.5. Adding jPDL 4 schema to the catalog

2.11.6. Importing the Examples2.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 archives4.1. Deploying process files and process resources

4.2. Deploying classes

5. Services

5.1. Process definition, process instance and executions5.2. ProcessEngine

5.3. Deploying a process5.4. Deleting a deployment

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

1 de 75 08/09/2010 14:51

Page 2: jBPM User Guide

5.5. Starting a new process instance

5.5.1. In latest5.5.2. Specific process version

5.5.3. With a key5.5.4. With variables

5.6. Signalling a waiting execution

5.7. TaskService5.8. HistoryService

5.9. ManagementService5.10. Query API

6. jPDL6.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 contents6.5. Events

6.5.1. Event listener example6.5.2. Event propagation

6.6. Asynchronous continuations

6.6.1. Async activity6.6.2. Async fork

6.7. User code6.7.1. User code configuration6.7.2. User code classloading

7. Variables7.1. Variable scoping

7.2. Variable types7.3. Updating serialized process variables

7.4. Declared variables7.5. Variables history

8. Scripting

9. Configuration

9.1. Business calendar9.2. Console9.3. Email

Chapter 1. Introduction

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

2 de 75 08/09/2010 14:51

Page 3: jBPM User Guide

1.1. License and EULA1.2. Downloads1.3. Sources

1.4. What is it1.5. Contents of this userguide

1.6. Migration from jBPM 31.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 UserLicense 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 arelational 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 moreadvanced 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

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

3 de 75 08/09/2010 14:51

Page 4: jBPM User Guide

When reporting a problem in the user forum or in our support portal, please use the following snippet as atemplate:

=== 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 ofeffort 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 twicebefore replacing libs with other versions.

Chapter 2. Installation

2.1. The distribution2.2. Required software

2.3. Getting started quickly2.4. Install scripts

2.5. Library dependencies and configuration files2.6. JBoss2.7. Tomcat

2.8. Signavio web based process editor2.9. User webapp

2.10. Database2.10.1. Creating or dropping the database schema2.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 eclipse2.11.3. Configuring the jBPM runtime2.11.4. Define the jBPM User Library

2.11.5. Adding jPDL 4 schema to the catalog2.11.6. Importing the Examples

2.11.7. Adding deployment with ant

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

4 de 75 08/09/2010 14:51

Page 5: jBPM User Guide

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

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.

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

5 de 75 08/09/2010 14:51

Page 6: jBPM User Guide

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, “GraphicalProcess 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 initializeon 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

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

6 de 75 08/09/2010 14:51

Page 7: jBPM User Guide

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

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

7 de 75 08/09/2010 14:51

Page 8: jBPM User Guide

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 ofjBPM 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 todelete 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 currentschema. 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.

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

8 de 75 08/09/2010 14:51

Page 9: jBPM User Guide

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 thatwere 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 Javadevelopers 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. Thereis an archived update site included in the runtime installation of jBPM when you unzip it at

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

9 de 75 08/09/2010 14:51

Page 10: jBPM User Guide

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

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

10 de 75 08/09/2010 14:51

Page 11: jBPM User Guide

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 libraryas well as its dependencies. If you create a new Java project, it will be sufficient to add this user library tothe 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

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

11 de 75 08/09/2010 14:51

Page 12: jBPM User Guide

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

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

12 de 75 08/09/2010 14:51

Page 13: jBPM User Guide

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 workswith 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 file3.2. Editing the process source

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

13 de 75 08/09/2010 14:51

Page 14: jBPM User Guide

This chapter will explain how to work with the Graphical Process Designer. After installing the GPD andsetting up the examples, you'll see that the jPDL process files will get a special icon. Double clicking such afile 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.

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

14 de 75 08/09/2010 14:51

Page 15: jBPM User Guide

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

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

15 de 75 08/09/2010 14:51

Page 16: jBPM User Guide

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 resources4.2. Deploying classes

A business archive is a collection of files assembled in a jar formatted file. The files in a business archive canbe 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 thedatabase.

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

An example of creating and deploying a business archive can be found in the ant build script (build.xml) inthe 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.

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

16 de 75 08/09/2010 14:51

Page 17: jBPM User Guide

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

file file optional

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

deployed as process files. Files ending with ar like .bar or

.jar will be deployed as business archives.

cfg file jbpm.cfg.xml optionalPoints to the jbpm configuration file that has to be on the

classpath in which the jbpm-deploy task was defined.

Table 4.2. jbpm-deploy elements:

Element Multiplicity Description

fileset 0..*

files to be deployed expressed as a plain ant fileset. Files ending with .xml will

be deployed as process files. Files ending with ar like .bar or .jar will be

deployed as business archives.

4.2. Deploying classes

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

17 de 75 08/09/2010 14:51

Page 18: jBPM User Guide

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 theroot 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 namecom/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 callsjBPM. That's because we use the current context classloader when searching for classes during processexecution.

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 executions5.2. ProcessEngine

5.3. Deploying a process5.4. Deleting a deployment

5.5. Starting a new process instance5.5.1. In latest5.5.2. Specific process version

5.5.3. With a key5.5.4. With variables

5.6. Signalling a waiting execution5.7. TaskService5.8. HistoryService

5.9. ManagementService5.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 havea loan process definition that describes the steps of how the company deals with loan requests.

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

18 de 75 08/09/2010 14:51

Page 19: jBPM User Guide

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

A process instance contains all the runtime state. The most prominent property is the pointer that keepstrack 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:

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

19 de 75 08/09/2010 14:51

Page 20: jBPM User Guide

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 casewhere 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 bothProcessInstances and Executions.

5.2. ProcessEngine

Interacting with jBPM occurs through services. The service interfaces can be obtained from theProcessEngine 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 theexample 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:

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

20 de 75 08/09/2010 14:51

Page 21: jBPM User Guide

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

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

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

21 de 75 08/09/2010 14:51

Page 22: jBPM User Guide

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

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

22 de 75 08/09/2010 14:51

Page 23: jBPM User Guide

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 beretrieved 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 akey 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 processinstance.

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

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

23 de 75 08/09/2010 14:51

Page 24: jBPM User Guide

executionService.signalExecutionById(executionId);

There is an alternatively (less preferrable) way to obtain the executionId when the execution arrives in thestate 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 theactual 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 variablesSet<String> variableNames = taskService.getVariableNames(taskId);variables = taskService.getVariables(taskId, variableNames);

// write task variablesvariables = 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 iscompleted. 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

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

24 de 75 08/09/2010 14:51

Page 25: jBPM User Guide

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

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, otherusers 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 displayforms 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. TheHistoryService 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();

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

25 de 75 08/09/2010 14:51

Page 26: jBPM User Guide

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. Followingquery 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 makesthat 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. Thisfunctionality 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 onHibernate. But for most use cases, the query API will be more then suffice. Queries can be written in aunified 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

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

26 de 75 08/09/2010 14:51

Page 27: jBPM User Guide

descending order based on the duedate.

Every service has operations of creating such unified queries (eg. querying jobs through theManagementService, 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 activities6.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 activities6.3.1. java

6.3.2. script

6.3.3. hql

6.3.4. sql

6.3.5. mail

6.4. Common activity contents6.5. Events

6.5.1. Event listener example

6.5.2. Event propagation6.6. Asynchronous continuations

6.6.1. Async activity6.6.2. Async fork

6.7. User code

6.7.1. User code configuration6.7.2. User code classloading

This chapter will explain the jPDL file format for describing process definitions. jPDL is the prominent processlanguage 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 canbe found in the developers guide.

An example jPDL process file looks like this:

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

27 de 75 08/09/2010 14:51

Page 28: jBPM User Guide

<?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 any text required

name or label of the process used

to display to the process name inuser interactions.

keyalpha numeric

characters andunderscores

if omitted, the key willbe generated based on

the name by replacingall non-alpha-numericcharacters with

underscores

optional

identification to distinct differentprocess definitions. Multipleversions of a process with the same

key can be deployed. Thekey:name combination must

remain exactly the same for alldeployed versions.

version integer

one higher then highest

version number startingwith 1 if no other process

is deployed with thesame name/key.

optional version number of this process

Table 6.2. process elements:

Element Multiplicity Description

description 0..1 description text

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

must be present.

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

28 de 75 08/09/2010 14:51

Page 29: jBPM User Guide

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

nameanytext

optionalname of the activity. Since a start activity cannot haveincoming 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 thecommon 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

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

29 de 75 08/09/2010 14:51

Page 30: jBPM User Guide

<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

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

30 de 75 08/09/2010 14:51

Page 31: jBPM User Guide

<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 signalNameaccept 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 outgoingtransitions and when an execution arrives in a decision activity, an automatic evaluation will decide whichoutgoing 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

expr expression requiredscript that will beevaluated in the

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

31 de 75 08/09/2010 14:51

Page 32: jBPM User Guide

Attribute Type Default Required? Description

specified expressionlanguage.

langexpressionlanguage

the default-expression-language

taken from the script-manager

configuration

optional

the language in which

expr is to be

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

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

32 de 75 08/09/2010 14:51

Page 33: jBPM User Guide

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

expr expression required

script that will beevaluated in thespecified expression

language.

langexpression

language

the default-expression-language

taken from the script-manager

configuration

optional

the language in whichexpr is to be

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.

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

33 de 75 08/09/2010 14:51

Page 34: jBPM User Guide

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

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

34 de 75 08/09/2010 14:51

Page 35: jBPM User Guide

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

multiplicity integer or expressionnbr ofincoming

transitions

optional

The number of executions that shouldarrive in this join before the joinactivates and push an execution out

the single outgoing transition of thejoin.

lockmode

{none, read,upgrade,upgrade_nowait,

write}

upgrade optional

the hibernate lock mode applied on

the parent execution to prevent that2 concurrent transactions see each

other as not yet arrived at the join,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

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

35 de 75 08/09/2010 14:51

Page 36: jBPM User Guide

<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 arestill active within the same process instance, all of them will be ended.

Figure 6.7. The end event

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

36 de 75 08/09/2010 14:51

Page 37: jBPM User Guide

<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 beleft active. To get this behaviour, set attribute ends="execution"

Table 6.8. end execution attributes:

Attribute Type Default Required? Description

ends {processinstance|execution} processinstance optional

specifies if the whole process

instance should be ended or justthe 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

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

37 de 75 08/09/2010 14:51

Page 38: jBPM User Guide

<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

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

38 de 75 08/09/2010 14:51

Page 39: jBPM User Guide

<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

assignee expression optionaluserId referring to the person that is responsible for

completing this task.

Figure 6.10. The task assignee example process

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

39 de 75 08/09/2010 14:51

Page 40: jBPM User Guide

<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

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

40 de 75 08/09/2010 14:51

Page 41: jBPM User Guide

A task that will be offered to a group of users. One of the users should then take the task in order tocomplete it.

Table 6.11. task attributes:

Attribute Type Default Required? Description

candidate-groups expression optionalresolves to a comma separated list of groupIds.All the people in the groups will be candidates

for this task.

candidate-users expression optionalresolves to a comma separated list of userIds.

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

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

41 de 75 08/09/2010 14:51

Page 42: jBPM User Guide

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 onthe 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 fromall 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 userinterface.

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

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

42 de 75 08/09/2010 14:51

Page 43: jBPM User Guide

<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 candidateusers 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 canbe 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 tothose user and candidates.

A swimlane can also be considered as a process role. In some cases, this might boil down to authorizationroles 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:

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

43 de 75 08/09/2010 14:51

Page 44: jBPM User Guide

Attribute Type Default Required? Description

nameswimlane

(string) required

Name for this swimlane. This is the name thatwill be referenced by task swimlane

attributes.

assignee expression optionaluserId referring to the person that is

responsible for completing this task.

candidate-groups expression optionalresolves to a comma separated list ofgroupIds. All the people in the groups will be

candidates for this the tasks in this swimlane.

candidate-users expression optionalresolves to a comma separated list of userIds.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");

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

44 de 75 08/09/2010 14:51

Page 45: jBPM User Guide

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 incase 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 comesfrom 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 atspecific intervals. Every email message is produced from a template. Templates may be specified inline or inthe process-engine-context section of the configuration file.

Table 6.14. task elements

Element Multiplicity Description

notification 0..1

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

referenced or supplied inline, mail support falls back on the template namedtask-notification.

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

Table 6.15. notification attributes:

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

45 de 75 08/09/2010 14:51

Page 46: jBPM User Guide

Attribute Type Default Required? Description

continue{sync | async |

exclusive}sync optional

Specifies if an asynchronous continuation should beintroduced right before sending this notification

email.

Table 6.16. reminder attributes:

Attribute Type Default Required? Description

duedateduration (plain string orcontaining expression)

requiredDelay before a reminder email should besend.

repeatduration (plain string or

containing expression) optional

Delay after a subsequent reminder email

should be send

continue{sync | async |

exclusive}sync optional

Specifies if an asynchronous continuation

should be introduced right before sendingthis 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

sub-process-idstring or

expression

either this or

sub-process-key isrequired

Identifies the sub process by the id.This means that a specific version of a

process definition is referenced. Subprocess id can be specified as simpletext or EL expression.

sub-process-keystring orexpression

either this orsub-process-key is

required

Identifies the sub process by the key.This means that the latest version of

the process definition with the givenkey is referenced. The latest version ofthe process is looked up each time the

activity executes. Sub process key canbe specified as simple text or EL

expression.

outcome expression

required whentransitions haveoutcome-value's

specified

Expression that is evaluated when thesub process instance ends. The value is

then used for outcome transitionmapping. Add outcome-value

elements to the outgoing transitions of

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

46 de 75 08/09/2010 14:51

Page 47: jBPM User Guide

Attribute Type Default Required? Description

this sub-process activity.

Table 6.18. sub-process elements:

Element Multiplicity Description

parameter-in 0..*Declares a variable that is passed to the sub process instance when it iscreated.

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

Table 6.19. parameter-in attributes:

Attribute Type Default Required? Description

subvar string requiredThe name of the sub process variable in whichthe value is set.

var string exactly one of {'var','expr'} is required tospecify the value

The name of the variable in the super processexecution context.

expr string exactly one of {'var','expr'} is required to

specify the value

An expression that will be resolved in the superprocess execution context. The resulting value

will be set in the sub process variable.

lang string juel optionalThe scripting language in which the expressionshould be resolved.

Table 6.20. parameter-out attributes:

Attribute Type Default Required? Description

var string requiredThe name of the variable in the super process

execution context in which the value will be set.

subvar string exactly one of {'subvar','expr'} is required to

specify the value

The name of the sub process variable from

which the value will be taken.

expr string exactly one of {'subvar','expr'} is required to

specify the value

An expression that will be resolved in the subprocess execution context. The resulting value

will be set in the super process variable.

lang string juel optionalThe scripting language in which the expression

should be resolved.

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

Element Multiplicity Description

outcome-value 0..1If the outcome matches the value, this transition is taken after the

sub-process ended. The value is specified with one child element.

6.2.7.1. sub-process variables

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

47 de 75 08/09/2010 14:51

Page 48: jBPM User Guide

The SubProcessVariables example scenario will show the basic workings of the sub-process activity, how tofeed information in the sub process when it starts and how to extract information out of the subprocess whenit 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>

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

48 de 75 08/09/2010 14:51

Page 49: jBPM User Guide

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

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

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

49 de 75 08/09/2010 14:51

Page 50: jBPM User Guide

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

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

50 de 75 08/09/2010 14:51

Page 51: jBPM User Guide

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:

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

51 de 75 08/09/2010 14:51

Page 52: jBPM User Guide

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 attributesand elements. Let's look at the example:

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

52 de 75 08/09/2010 14:51

Page 53: jBPM User Guide

<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

class classname

either 'class' or

'expr' has to bespecified

The fully qualified classname. See Section 6.7.2,“User code classloading” for classloading

information. The user code object will be lazyinitialized and cached as part of the processdefinition.

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

53 de 75 08/09/2010 14:51

Page 54: jBPM User Guide

Attribute Type Default Required? Description

expr expression either 'expr' or'class' has to be

specified

An expression that returns the target object on

which the method should be invoked.

method methodname required The name of the method to invoke

var variablename optionalThe name of the variable in which the return

value should be stored.

Table 6.23. java elements:

Element Multiplicity Description

field 0..*describes a configuration value to inject in a memberfield before the method isinvoked.

arg 0..* method parameters

Consider the following example.

Figure 6.20. A java task

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

54 de 75 08/09/2010 14:51

Page 55: jBPM User Guide

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

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

55 de 75 08/09/2010 14:51

Page 56: jBPM User Guide

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

expr text requiredthe expression text to

evaluate.

langscripting language nameas defined in Chapter 8,

Scripting

the default expressionlanguage as defined in

Chapter 8, Scripting

optionalthe language in which the

expression is specified.

var variablename optionalname of the variable in

which the return value

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

56 de 75 08/09/2010 14:51

Page 57: jBPM User Guide

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

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

57 de 75 08/09/2010 14:51

Page 58: jBPM User Guide

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

langscripting language name

as defined in Chapter 8,Scripting

the default scripting

language as defined inChapter 8, Scripting

optionalthe language in which the

script is specified.

var variablename optional

name of the variable in

which the return valueshould 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

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

58 de 75 08/09/2010 14:51

Page 59: jBPM User Guide

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.

unique {true, false} false optional

a value of true means that the result from the

hibernate query should be obtained with methoduniqueResult(). 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

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

59 de 75 08/09/2010 14:51

Page 60: jBPM User Guide

<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 specifiedinline or in the process-engine-context section of the configuration file.

Table 6.29. mail attributes

Attribute Type Default Required? Description

template string no

Reference to a mail-template element in the configuration

file. If absent, the template must be specified inline using thechild elements.

Table 6.30. mail elements

Element Multiplicity Description

from 0..1 list of sender(s)

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

60 de 75 08/09/2010 14:51

Page 61: jBPM User Guide

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

name string no, unless expression

is present

File name associated with this attachment. Ifabsent, data sources that encapsulate files such

as resource, file and url provide a reasonable

fallback value.

description string noDescriptive information associated with this

attachment.

expression string

one of expression,

file, url or resource

must be present

Expression that evaluates to a representation ofthe attachment data in the form of a Java object.

Useful to extract content from process variables.

file string Path to the attachment data in the file system.

The denoted file must exist.

url string Location of the attachment data in the worldwideweb. The pointed resource must exist.

resource string Name of the resource containing the attachmentdata in the class path. The denoted resourcemust exist.

mime-type string no, unless expression

is present

MIME type of the object returned by the

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="[email protected]" /> <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

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

61 de 75 08/09/2010 14:51

Page 62: jBPM User Guide

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

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

62 de 75 08/09/2010 14:51

Page 63: jBPM User Guide

Any automatic activities (including event-listener) that are placed on events can specify following additional

attributes:

Attribute Type Default Required? Description

propagation{enabled |disabled | true |

false | on | off}

disabled optionalindicates if the event listener should also be

invoked for propagating events.

continue{sync | async |exclusive}

sync optional

indicates if the execution should be continued

asynchronously right before the event listeneris 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:

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

63 de 75 08/09/2010 14:51

Page 64: jBPM User Guide

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

By default, event listeners are only invoked for events that are fired on the elements on which the eventlisteners 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 clientto 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 multipleautomatic activities are executed inbetween 2 wait states. So in most situations, it's good to do all that work

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

64 de 75 08/09/2010 14:51

Page 65: jBPM User Guide

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 andcontinue the rest of the automatic process work asynchronously. jBPM uses asynchronous messaginginternally 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

continue{sync | async |

exclusive}sync optional

indicates if an asynchronous continuation should be

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 committedand 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 thejBPM 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 yourjBPM configuration has multiple asynchronous message processors (like the JobExecutor) running ondifferent 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

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

65 de 75 08/09/2010 14:51

Page 66: jBPM User Guide

<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 jobexecutor 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 theexecution till the end.

6.6.2. Async fork

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

66 de 75 08/09/2010 14:51

Page 67: jBPM User Guide

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.

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

67 de 75 08/09/2010 14:51

Page 68: jBPM User Guide

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 executormanagementService.executeJob(job.getDbid());

job = jobs.get(1);

// here we simulate execution of the job,// which is normally done by the job executormanagementService.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 beinvoked. 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

class classname one of{class|expr} is

required

The fully qualified classname. Instantiation is doneonly once and the user object is cached as part of

the process definition.

expr expression

one of

{class|expr} isrequired

Expression for which the resulting value will betaken as the target object. Expressions will be

evaluated for every usage. In other words, theresulting value of the evaluation will not be cached.

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

68 de 75 08/09/2010 14:51

Page 69: jBPM User Guide

Table 6.39. user code configuration elements:

Element Multiplicity Description

field 0..*describes a configuration value to be injected directly in a memberfield beforethis user class is used.

property 0..*describes a configuration value to injected through a setter method before thisuser 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 istypically 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

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

69 de 75 08/09/2010 14:51

Page 70: jBPM User Guide

7.1. Variable scoping7.2. Variable types7.3. Updating serialized process variables

7.4. Declared variables7.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, String pro

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

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

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 likeActivityExecution 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. aserializable 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 andaccessible 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 thecreateVariable methods in the execution interfaces ActivityExecution and EventListenerExecution,

execution-local variables can be created.

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

70 de 75 08/09/2010 14:51

Page 71: jBPM User Guide

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 matchwill 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 theneed 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 pieceof 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 updatedin the database automatically.

When reading process variables that are stored in serialized format from the DB jBPM will monitor that

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

71 de 75 08/09/2010 14:51

Page 72: jBPM User Guide

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 wasset 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 basedon comparing the byte arrays from serializing the object again and comparing that with the byte array thatwas 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 processinstance 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 text requiredtype of the variable, must refer to types definedin jbpm.variable.types.xml

init-exprtext (EL

expression) optional

value for the variable, this attribute or nested

element must be given

init-expr-type text UEL optional defines language for expression evaluation

history boolean false optional

indicates wheater variable should be stored inhistory or not - default false, for moreinformation about history see Section 7.5,

“Variables history”

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

72 de 75 08/09/2010 14:51

Page 73: jBPM User Guide

Table 7.2. Nested element for variable:

Element Multiplicity Description

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

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 UnifiedExpression 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. Console9.3. Email

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

73 de 75 08/09/2010 14:51

Page 74: jBPM User Guide

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") andreplace 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=localhostmail.smtp.port=25mail.from=noreply@jbpm.org

If the SMTP server requires authentication, the application can supply a custom authenticator in theconfiguration file.

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

74 de 75 08/09/2010 14:51

Page 75: jBPM User Guide

<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. Toemploy 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 theauthenticator. The combined absence of session-properties and session-jndi constitutes an

error.

Refer to the Developer Guide for advanced, yet unsupported, email settings.

jBPM User Guide http://docs.jboss.com/jbpm/v4/userguide/html_single/#thedistribution

75 de 75 08/09/2010 14:51