The Danet Workflow Component

User Manual

Dr. Michael Lipp

Danet GmbH
BU BTS

For version 2.1

All rights reserved.

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA


Table of Contents

Introduction
1. Integrating the workflow component
1.1. Prerequisites
1.2. Preparing the database
1.3. Application and client assembly
1.3.1. Workflow APIs
1.3.2. Client JAR
1.3.3. The Danet AN utility library
1.3.4. Workflow module
1.3.5. The utility module
1.3.6. Additional libraries
1.4. Deploying the component
1.4.1. Preparing the modules
1.4.2. Basic deployment
1.4.3. Additional services
2. States and state transitions of processes and activities
2.1. States of processes and activities
2.2. State transitions of processes and activities
2.3. Triggers of state transitions
2.4. Exceptions
2.5. Suspended state and deadlines
2.6. Debugging workflows
2.6.1. Enabling debug mode
2.6.2. Effect on state changes
2.6.3. Effect on exceptions
2.6.4. Effect on deadlines
3. Using the workflow component
3.1. Component structure
3.2. Client API
3.2.1. Adapted OMG interfaces
3.2.2. Extending the core interface
3.3. Sample client
3.3.1. Client code
3.3.2. Running the sample client
3.4. Resource assignment SPI
3.5. Tool invocation SPI
3.5.1. Invocation mode
3.5.2. Accessing the workflow engine context
3.5.3. Accessing JNDI
3.5.4. Exception handling
4. Process definitions
4.1. Managing process definitions
4.2. Process definition format
4.2.1. Base format
4.2.2. XPDL and the OMG API
4.2.3. Specifying XML data
4.2.4. Deadlines
4.2.5. Defined extensions
4.2.6. Miscellaneous
4.3. Semantics
4.3.1. Start and finish of a process
4.3.2. Split and Join
4.3.3. Condition evaluation
4.3.4. Loops
4.3.5. Deferred choice
5. Tools
5.1. Overview
5.2. The XForms Tool
5.2.1. Usage
5.2.2. Defining an XForms application in the process definition
5.3. JavaScript tools
5.4. Jelly tool
5.4.1. General usage
5.4.2. LDAP tag library
5.5. Mail tool
5.6. XSLT tool
5.7. Generic SOAP tool
5.8. RPC SOAP tool
5.9. Wait tool
5.10. MBean invocation tool
5.11. EJB invocation tool
5.12. Channel based access
5.12.1. Receiver tool
5.12.2. Sender tool
5.12.3. Generic HTTP Access
6. The sample resource assignment service
6.1. The sample assignment service
6.2. Provided functionality
6.3. The underlying resource management service
6.4. Provided RMS implementations
6.4.1. Database based RMS
6.4.2. EIS based RMSes
7. Wf-XML
7.1. Installation
7.2. Accessing Wf-XML Resources
7.3. Properties
7.4. Deviations from the Wf-XML 2.0 Standard
7.4.1. ServiceRegistry
7.4.2. Factory
7.4.3. Instance
7.4.4. Activity
7.5. Example Client
8. Management portlets
8.1. Process definition portlet
8.2. Process definition upload portlet
8.3. Process portlet
8.4. Deploying the portlet application in a portal
8.4.1. General procedure
8.4.2. Deploying in Jetspeed2
9. Known bugs and limitations
9.1. Bugs
9.2. Limitations
A. The API documentation
A.1. Package de.danet.an.workflow.omgcore
A.1.1. Additional Information
A.1.2. Exception AlreadyRunningException
A.1.3. Exception AlreadySuspendedException
A.1.4. Exception CannotChangeRequesterException
A.1.5. Exception CannotCompleteException
A.1.6. Exception CannotResumeException
A.1.7. Exception CannotStartException
A.1.8. Exception CannotStopException
A.1.9. Exception CannotSuspendException
A.1.10. Exception HistoryNotAvailableException
A.1.11. Exception InvalidControlOperationException
A.1.12. Exception InvalidDataException
A.1.13. Exception InvalidPerformerException
A.1.14. Exception InvalidPriorityException
A.1.15. Exception InvalidRequesterException
A.1.16. Exception InvalidResourceException
A.1.17. Exception InvalidStateException
A.1.18. Exception NotAssignedException
A.1.19. Exception NotEnabledException
A.1.20. Exception NotRunningException
A.1.21. Exception NotSuspendedException
A.1.22. Interface ProcessData
A.1.23. Interface ProcessDataInfo
A.1.24. Exception RequesterRequiredException
A.1.25. Exception ResultNotAvailableException
A.1.26. Exception SourceNotAvailableException
A.1.27. Exception TransitionNotAllowedException
A.1.28. Exception UpdateNotAllowedException
A.1.29. Interface WfActivity
A.1.30. Interface WfAssignment
A.1.31. Interface WfAssignmentAuditEvent
A.1.32. Interface WfAuditEvent
A.1.33. Interface WfAuditHandler
A.1.34. Interface WfCreateProcessAuditEvent
A.1.35. Interface WfDataAuditEvent
A.1.36. Interface WfExecutionObject
A.1.37. Class WfExecutionObject.ClosedState
A.1.38. Class WfExecutionObject.NotRunningState
A.1.39. Class WfExecutionObject.OpenState
A.1.40. Class WfExecutionObject.State
A.1.41. Interface WfObject
A.1.42. Interface WfProcess
A.1.43. Interface WfProcessMgr
A.1.44. Interface WfRequester
A.1.45. Interface WfResource
A.1.46. Interface WfStateAuditEvent
A.2. Package de.danet.an.workflow.api
A.2.1. Additional Information
A.2.2. Interface Activity
A.2.3. Class Activity.ClosedCompletedState
A.2.4. Class Activity.DeadlineInfo
A.2.5. Interface Activity.Implementation
A.2.6. Class Activity.Info
A.2.7. Class Activity.JoinAndSplitMode
A.2.8. Class Activity.StartFinishMode
A.2.9. Interface Activity.SubFlowImplementation
A.2.10. Interface Activity.ToolImplementation
A.2.11. Class ActivityUniqueKey
A.2.12. Exception AlreadyAssignedException
A.2.13. Interface Application
A.2.14. Interface Batch
A.2.15. Interface Batch.Context
A.2.16. Exception CannotRemoveException
A.2.17. Interface Channel
A.2.18. Interface Configuration
A.2.19. Class DefaultProcessData
A.2.20. Class DefaultRequester
A.2.21. Interface EventSubscriber
A.2.22. Interface ExecutionObject
A.2.23. Interface ExternalReference
A.2.24. Error FactoryConfigurationError
A.2.25. Class FormalParameter
A.2.26. Class FormalParameter.Mode
A.2.27. Interface GroupResource
A.2.28. Exception ImportException
A.2.29. Exception InvalidIdException
A.2.30. Exception InvalidKeyException
A.2.31. Class MethodInvocationBatch
A.2.32. Class MethodInvocationBatch.Result
A.2.33. Exception NoSuchResourceException
A.2.34. Interface Participant
A.2.35. Class Participant.ParticipantType
A.2.36. Class PrioritizedMessage
A.2.37. Class PrioritizedMessage.Priority
A.2.38. Interface Process
A.2.39. Interface ProcessClosedAuditEvent
A.2.40. Interface ProcessDefinition
A.2.41. Interface ProcessDefinition.PackageHeaderData
A.2.42. Interface ProcessDefinition.ProcessHeaderData
A.2.43. Interface ProcessDefinitionDirectory
A.2.44. Interface ProcessDirectory
A.2.45. Interface ProcessMgr
A.2.46. Interface RoleResource
A.2.47. Interface SAXEventBuffer
A.2.48. Interface Transition
A.2.49. Interface UserResource
A.2.50. Interface WorkflowService
A.2.51. Class WorkflowServiceFactory
A.3. Package de.danet.an.workflow.spis.aii
A.3.1. Additional Information
A.3.2. Exception ApplicationNotStoppedException
A.3.3. Exception CannotExecuteException
A.3.4. Interface ContextRequester
A.3.5. Interface ExceptionMappingProvider
A.3.6. Class ExceptionMappingProvider.ExceptionMapping
A.3.7. Interface ExecutionModeProvider
A.3.8. Interface ResultProvider
A.3.9. Class ResultProvider.ExceptionResult
A.3.10. Interface ToolAgent
A.3.11. Interface ToolAgentContext
A.3.12. Interface XMLArgumentTypeProvider
A.4. Package de.danet.an.workflow.spis.ras
A.4.1. Additional Information
A.4.2. Interface ActivityFinder
A.4.3. Error FactoryConfigurationError
A.4.4. Exception NoSuchActivityException
A.4.5. Interface ResourceAssignmentService
A.4.6. Class ResourceAssignmentServiceFactory
A.5. Package de.danet.an.workflow.spis.rms
A.5.1. Additional Information
A.5.2. Class DefaultGroupResource
A.5.3. Class DefaultResource
A.5.4. Class DefaultRoleResource
A.5.5. Class DefaultUserResource
A.5.6. Error FactoryConfigurationError
A.5.7. Interface ResourceAssignmentContext
A.5.8. Interface ResourceManagementService
A.5.9. Class ResourceManagementServiceFactory
A.5.10. Exception ResourceNotFoundException
A.6. Package de.danet.an.workflow.tools.util
A.6.1. Additional Information
A.6.2. Interface DirectInvocable
A.6.3. Class SimpleApplicationAgent
A.6.4. Interface SimpleApplicationDirectory
A.6.5. Class SimpleApplicationDirectoryEJB
A.6.6. Interface SimpleApplicationDirectoryHome
A.6.7. Interface SimpleApplicationDirectoryLocal
A.6.8. Interface SimpleApplicationDirectoryLocalHome
A.6.9. Class SimpleApplicationDirectoryLookup
A.6.10. Class SimpleApplicationInfo
B. The service provider classes
B.1. Package de.danet.an.workflow.ejbs.client
B.1.1. Additional Information
B.1.2. Class StandardWorkflowServiceFactory
B.2. Package de.danet.an.workflow.assignment
B.2.1. Additional Information
B.2.2. Class StandardResourceAssignmentServiceFactory
B.3. Package de.danet.an.workflow.rmsimpls.dbrms
B.3.1. Class DatabaseRmsFactory
B.4. Package de.danet.an.workflow.rmsimpls.eisrms
B.4.1. Class EisRmsFactory
B.5. Package de.danet.an.workflow.rmsimpls.eisrms.aci
B.5.1. Additional Information
B.5.2. Interface RmsConnection
B.5.3. Interface RmsConnectionFactory
B.5.4. Class RmsEntry
C. The demo applications
C.1. Installing a demo application
C.1.1. Installing JBoss
C.1.2. Create JBoss server configuration
C.1.3. Creating datasources etc.
C.1.4. Working with the Pluto based demo
C.1.5. Working with the Liferay based demo
D. Installing Liferay
D.1. Creating a configuration
D.2. Deploying Liferay
D.2.1. Disabling the default root context application
D.2.2. Unpacking the JBoss extension libraries
D.2.3. Unpacking the EAR
D.2.4. Fixing the transaction manager configuration
D.2.5. Adapting the portal configuration
D.2.6. Configure security
D.3. Providing a database
D.4. Starting JBoss
E. Notes
F. GNU General Public License
F.1. Preamble
F.2. TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
F.2.1. Section 0
F.2.2. Section 1
F.2.3. Section 2
F.2.4. Section 3
F.2.5. Section 4
F.2.6. Section 5
F.2.7. Section 6
F.2.8. Section 7
F.2.9. Section 8
F.2.10. Section 9
F.2.11. Section 10
F.2.12. NO WARRANTY
F.2.13. Section 12
Index

List of Figures

1.1. Copying option
1.2. Copying destination
1.3. Creating the schema with the installer (1)
1.4. Creating the schema with the installer (2)
1.5. Application assembly
2.1. State transitions of execution objects
3.1. Structure of the workflow component
3.2. OMG core workflow model
4.1. XOR-Split example
5.1. XForm task list
5.2. XForm sample
6.1. Sample resource adapter configuration for JBoss
6.2. Sample resource adapter configuration
8.1. Process definition page
8.2. Process list
8.3. Process detail
8.4. Events display
8.5. Assignments display
C.1. Create JBoss configuration
C.2. JBoss installation directory
C.3. Liferay configuration options
C.4. Setup wfdemo configuration
C.5. JBoss configuration directory
C.6. Advanced installation options
C.7. Choose demo application

List of Tables

2.1. Meaning of execution object states
2.2. State transitions triggered by client API calls
2.3. State transitions triggered by the engine
5.1. Entries that can be specified as attributes
7.1. Resource identification through the ReceiverKey

Introduction

This document describes how to integrate and use Danet's J2EE based workflow component. The Maintenance Guide describes the internal structures and design principles of the component.

What is Danet's workflow component?

Danet's workflow component is a J2EE based implementation of a workflow facility (workflow engine) as proposed by the Workflow Management Coalition (WfMC) and the Object Management Group (OMG).

The workflow component includes and is based on a set of JAVA interfaces that define an API for a workflow management facility. These "omgcore" interfaces follow OMG's Workflow Management Facility Specification, V1.2 very closely, while making some changes to adapt the CORBA service to the established design practices for a Java API.

Danet's workflow component provides a collection of EJBs that implement the omgcore interfaces together with some additional interfaces for tasks not covered by the OMG specification. The EJBs are provided as a J2EE module that can be used in any J2EE compliant application server.

The workflow engine is designed as a J2EE component. It is intended to be integrated in an application that requires a workflow engine. As a proof of concept and test environment, we provide a demo application. The demo application consists of the workflow component and some additional modules with a portal based GUI. Combined they provide a small workflow system that may be used to get acquainted with the workflow engine. You can find more information about this demo application in Appendix C, The demo applications

Required knowledge

This manual assumes that you are familiar with Sun's Java™ 2 Platform Enterprise Edition Specification, v1.2.

Structure of the remaining document

Chapter 1, Integrating the workflow component

describes all steps required to integrate the workflow component in an application.

Chapter 2, States and state transitions of processes and activities

describes all defined and supported states and state transitions of processes and activities.

Chapter 3, Using the workflow component

gives an inside view of the internal structure of Danet's workflow component.

Chapter 4, Process definitions

helps managing process definitions.

Chapter 5, Tools

lists the tools available in this workflow component. Tools are applications that can be started from an activity.

Chapter 6, The sample resource assignment service

shows how to develop or integrate a resource assignment service with the help of a simple example.

Chapter 9, Known bugs and limitations

lists the bugs and limitations of the workflow component currently known.

Appendix A, The API documentation

describes the java user interface of the workflow components in javadoc format.

Appendix C, The demo applications

gives an inside view of the provided demo applications.

Documentation conventions

The following conventions will be applied throughout this document:

name

to state a common name or id as it is used within the workflow component.

package

for package name.

class

for class names.

variable

to describe a name of a variable.

Chapter 1. Integrating the workflow component

The workflow engine is designed as a component. Therefore the typical usage is to integrate it into your application. The following sections describe the steps required to do this. If you want to get acquainted with the workflow engine by installing a demo application, please proceed to Appendix C, The demo applications. If you want to experiment with the API, step by step instructions how to build a basic sample client can be found in Section 3.3, “Sample client”. If you want to integrate the workflow component with your application or understand its structure, continue reading here.

The binary distribution comes as an installer. In the simplest case, the installer only copies the libraries and documentation to your filesystem. It provides, however, additional operations to configure your application server and initialize a database. The installer is distributed as an executable jar. It is invoked as "java -jar wfmopen-n.m-installer.jar".

The figures below show the installer screens for copying the components to the filesystem.

Copying option

Figure 1.1. Copying option


Copying destination

Figure 1.2. Copying destination


In the sections following, the term $DIST represents the top level directory of the binary distribution, i.e. the installation directory that you have specified in the dialog above.

1.1. Prerequisites

WfMOpen requires JDK 1.4.2 (see Section 1.3.6, “Additional libraries” for more details). Older JDK versions back to 1.3 may work, tests have, however, only been made with JDK 1.4.2_15 and JDK 1.6.0_02.

The workflow component requires a database that supports distributed transactions. WfMOpen relies on operations on queues and on the database being made in a single transaction. This can only be accomplished by using distributed transactions[1]. If you are looking for an OpenSource solution, we recommend using MAXDB (formerly known as SAPDB).

1.2. Preparing the database

The workflow component relies on the presence of a number of tables in a database. The table definitions are provided as file $DIST/lib/wfdemo/database/RDBMS-type/create.sql. The files contain SQL statements that can be executed by appropriate database tools.

If you cannot find scripts for your database, you can still use the generic table definition in $DIST/lib/wfdemo/database/database-schema.xml. It is suited to be processed by the Apache DDLUtils (see Apache DDLUtils site)[2].

As an alternative, the schema can be created by the installer. In order to do this, choose the option "(Re-)create schema" as shown below.

Creating the schema with the installer (1)

Figure 1.3. Creating the schema with the installer (1)


You will now be prompted for an RBMS type.
Creating the schema with the installer (2)

Figure 1.4. Creating the schema with the installer (2)


If you select one of the specific types, you will only be prompted for database instance information and credentials on the next screen. If you select "Other", a generic dialog prompts you additionally for the driver class and a driver jar.

The installer then uses the DDLUtils to create the schema in your database. This will work for all databases that are supported by DDLUtils.

1.3. Application and client assembly

The workflow component software consists of several JAR files (modules and libraries) that have to be assembled into a J2EE application or have to be included in the classpath of a client. The figure shows an overview of the JAR files and their usage.

Application assembly

Figure 1.5. Application assembly


The following sections describe each JAR file and its role in application assembly.

1.3.1. Workflow APIs

The specified workflow APIs (packages de.danet.an.workflow.omgcore and de.danet.an.workflow.api, see Section 3.2, “Client API”) are packaged in a separate jar de.danet.an.wfcore-apis.jar located in the distribution directory $DIST/lib/wfcore. Only this JAR file should be used in the classpath when compiling clients. Consequently, it must also be included in the runtime classpath of a client.

1.3.2. Client JAR

The runtime-classes needed by a client that wants to use the workflow component are provided as de.danet.an.wfcore-client.jar in $DIST/lib/wfcore. This JAR file is not self contained, i.e. it relies on the presence of the workflow APIs (de.danet.an.wfcore-apis.jar), the Danet AN utility classes (de.danet.an.util.jar, see following section) and the additional libraries described in Section 1.3.6, “Additional libraries”. In addition, the client needs some information about how to contact the server. See the description of the basic WorkflowServiceFactory (in Section A.2.51, “Class WorkflowServiceFactory”), the description of the WfMOpen specific factory implementation (in de.danet.an.workflow.ejbs.client.StandardWorkflowServiceFactory) and the remarks in Section 1.3.4, “Workflow module” below.

1.3.3. The Danet AN utility library

All J2EE based software from the division AN uses a library with some common utility objects and components. This library is supplied as de.danet.an.util.jar (again located in the $DIST/lib/wfcore). Some components in this library (currently the logging service) need server side support. This support is provided by the corresponding EJB module described below.

The Danet AN utility library (package de.danet.an.util) is a general library used at our site. This library is packaged as two JAR files. By default, classes are in de.danet.an.util.jar. Some classes in the package (sub-package de.danet.an.util.jsf), however, are helper classes for JSF based portlets. These classes are are not included in de.danet.an.util.jar. They can be found in de.danet.an.util-jsf.jar. The reason for separating those classes is that they may not be put in the common classpath of a J2EE application. In order to avoid classpath problems, you have to put these JSF utility classes in the same directory as the JSF libraries (usually the WEB-INF/lib directory of your web module). Note that the classes from de.danet.an.util.jsf are only needed by the portlets that come with the workflow component. The deployment of the workflow EJBs requires de.danet.an.util.jar only.

1.3.4. Workflow module

The central (server side) workflow component is an EJB-type J2EE module. This module is not self contained, i.e. it relies on the presence of the workflow APIs, the Danet AN utility library and the additional libraries listed below. The module is located in the distribution directory $DIST/lib/wfcore as de.danet.an.wfcore-ejbs.jar.

The manifest file of de.danet.an.wfcore-ejbs.jar includes in its Class-Path: statement the entries lib/de.danet.an.wfcore-apis.jar and lib/de.danet.an.util.jar. Thus, the dependencies between the workflow module, the workflow APIs and the Danet AN utility library will be resolved automatically if de.danet.an.util.jar is put in the lib/ directory of the enterprise archive (the .ear-file).

1.3.4.1. Vendor specific deployment descriptors

The file de.danet.an.wfcore-ejbs.jar includes vendor specific deployment descriptors for some application servers. These deployment descriptors define, among other things, the binding of EJBs (EJB's home interfaces, to be precise) to global JNDI names[3]. As the workflow engine is intended to be integrated in different applications that may run on one application server concurrently, the JNDI names must be adapted to the specific application the engine is integrated with; else there will be conflicts between the applications. All deployment descriptors therefore use "generic" names for JNDI bindings such as "ejb/@@@_JNDI_Name_Prefix_@@@SomeEJB". When packing the workflow engine EJBs, the prefix "@@@_JNDI_Name_Prefix_@@@" should be replaced with some reasonable value (e.g. ""@@@_JNDI_Name_Prefix_@@@ = de.danet.wfdemo.").

Whereever the workflow module references the utility module (see Section 1.3.5, “The utility module”) in the included vendor specific deployment descriptors, it uses the same symbolic names as the deployment descriptors of the utility module (again, see Section 1.3.5, “The utility module”). These symbolic names must be adapted as well when assembling an application.

Note that "generic" names and "symbolic" names for resources appear only in vendor specific deployment descriptors. So supplying your own vendor specific deployment descriptors from scratch is an alternative integration strategy.

The workflow module includes Ant helper scripts for executing the required adaptions. See Section 1.4.1, “Preparing the modules” for details.

1.3.4.2. Accessing the engine from a client

One global JNDI name is of specific importance. It is the name of the WorkflowEngineEJB. This EJB is the only EJB looked up directly in JNDI by a workflow engine's client (remote interfaces of other EJBs are passed to the client directly or indirectly by methods of the WorkflowEngineEJB). Therefore, the global JNDI name of the WorkflowEngineEJB's home interface must be made known to the client. The lookup of this home interface need not be made explicitly. Rather, it is encapsulated in the creation of a new workflow service by the WorkflowServiceFactory (see newWorkflowService()). Thus the configuration of the JNDI name becomes a configuration issue of WfMOpen's implementation of the WorkflowServiceFactory. WfMOpen's implementation class and its configuration is described in detail in de.danet.an.workflow.ejbs.client.StandardWorkflowServiceFactory. The preferred way to do the configuration[4] is to first create a file de.danet.an.workflow-wfs.properties with an entry engine = ejb/@@@_JNDI_Name_Prefix_@@@WorkflowEngine (applying the replacement described above) and then to add this file to the client JAR de.danet.an.wfcore-client.jar. This results in an "application specific" client library. Anywhere this client JAR is used, the resource de.danet.an.workflow-wfs.properties is found by the StandardWorkflowServiceFactory in the JAR and the proper workflow engine EJB is looked up.

Another value that may need replacement is the security domain. The JBoss vendor specific deployment descriptor defines the security domain as java:/jaas/wfmopen. This should be replaced by the application's domain.

1.3.4.3. Queues and Topics

In addition to the EJBs and the libraries, the workflow module requires three queues to be defined. By default, the JNDI names of these queues are "queue/@@@_JNDI_Name_Prefix_@@@ApplicationInvocations", "queue/@@@_JNDI_Name_Prefix_@@@InternalEventQueue" and "topic/@@@_JNDI_Name_Prefix_@@@EventService", with the latter being a topic queue. These names are referenced in the vendor specific deployment descriptors of the EJBs and must be adapted with the prefix replacement as described above.

You can find sample definitions of the required queues for JBoss in $DIST/lib/wfcore/wfcore-destinations-service.xml. Depending on your application server, you have to created these queues before the deployment of your application using e.g. some console application. Alternatively, you may usually trigger the creation and configuration of the queues by adding some vendor specific information to your enterprise archive (this mechanism is used in the demo applications, see Appendix C, The demo applications).

1.3.4.4. Security roles

The workflow module as distributed uses in its deployment descriptors a predefined security role "WfMOpenAdmin" as only role and this role has all permissions[5].

1.3.5. The utility module

As described above, all J2EE based software from the division AN uses some common utility objects and components. While most of these elements can be simply supplied as a library, some components (currently the logging support) consist of a client and a server part. The J2EE server side elements are packaged in the distinct EJB-type J2EE module de.danet.an.util-ejbs.jar that is also located in the $DIST/lib/wfcore distribution directory. This module must be deployed along with the workflow module.

As the utility module is intended to be used in several applications, we have deliberately not defined defaults for some information needed during deployment. Providing defaults for these values would imply the risk that different applications inadvertently access each others utility EJBs. Instead of defaults we use symbolic names in the deployment descriptors that can reliably be replaced automatically.

All symbolic names are described below. The description should be sufficient to allow you to adapt the deployment descriptors for your application. For more information about these EJBs, see the maintenance manual.

The symbolic names used are:

@@@_Utility-EJBs_UtilEJB_JNDI_Name_@@@

The utility EJB's global JNDI name. This EJB has a global JNDI name defined because it may be needed by stand-alone clients. A reasonable value if the utility module is used in a workflow application would be de.danet.an.workflow.util-lib.Util.

@@@_Utility-EJBs_KeyGenEJB_JNDI_Name_@@@

The key generator EJB's global JNDI name. The key generator EJB has a global JNDI name defined because it may be needed by stand-alone clients. A reasonable value if the utility module is used in a workflow application would be de.danet.an.workflow.util-lib.KeyGen.

@@@_Utility-EJBs_EJBSinkEJB_JNDI_Name_@@@

The log4j EJB-appender's global JNDI name. This EJB has a global JNDI name defined because it may be needed by stand-alone clients. A reasonable value if the utility module is used a workflow application would be de.danet.an.workflow.util-lib.EJBSink.

As distributed, the utility module's descriptors do not specify any security constraints. We do, however, strongly recommend adding such constraints as appropriate for an application's security domain when assembling the application[6]. A common configuration is to introduce the same security role as used for the workflow engine EJBs (i.e. "WfMOpenAdmin", see Section 1.3.4, “Workflow module”) and allow this role to execute all methods.

The module includes support for executing the required adaptions. See Section 1.4.1, “Preparing the modules” for details.

1.3.6. Additional libraries

As is usually the case with complex Java applications, the workflow component needs some third party libraries in addition to the standard JDK. Those libraries are:

When you want to use WfMOpen with JDK/JRE 1.4, updated versions of the JRE XML packages (org.w3c.dom, org.xml.sax, org.xml.sax.ext and org.xml.sax.helpers) are needed. You you must therefore use the Endorsed Standards Override Mechanism of the JDK to provide those newer versions, i.e. you have to set the system property java.endorsed.dirs to the directory $DIST/lib/wfdemo/endorsed[7]. For the versions of the XML libraries currently used see the CVS information in the tools/endorsed subdirectory.

1.4. Deploying the component

1.4.1. Preparing the modules

As has been described in the previous sections, the deployment descriptors of the EJB modules must be adapted to the application that integrates the workflow engine. In order to facilitate this task, the EJB JARs have in their subdirectory assembly-resources ant scripts with targets that may be called to perform the adaption. Of course, these scripts do not have to be used to adapt the EJBs, they are simply provided as useful helpers.

1.4.1.1. General helpers

File assembly-resources/assembly-utils.xml provides general purpose targets that can be used for any EJB JAR, not only for the workflow engine or utility EJBs.

add-ejb-resource-ref

Add a resource reference to an EJB. Must be called with properties "src-ejb-jar=<the ejb jar to patch>", "target-ejb-jar=<the patch result>", "ejb-name=<the ejb that references the resource>", "ref-name=<the locigal name used by the EJB to reference the resource>", "jndi-name=<the (global) JNDI entry for the resource>", "res-auth" and "res-type" as to be put into the ejb-jar.xml. This target needs additional resources (DTDs and stylesheets) that must be provided in a directory specified with property "resource-dir=<directory>".

adapt-ejb-jar

Modify the deployment descriptors of an ejb jar by replacing given strings with other strings as specified in a properties file. Must be called with properties "src-ejb-jar=<filename of distributed ejb jar>", "target-ejb-jar=<filename of adapted ejb jar>" and "props=<filename with properties>". If the special properties "security-roles", "security-identities" and "security-domain" are defined, security information will additionally be inserted into the deployment descriptors as specified by these properties. This target needs additional resources (DTDs and stylesheets) that must be provided in a directory specified with property "resource-dir=<directory>". This target also removes the sub-directory "assembly-resources" from the ejb jar if such a sub-directory exists.

adapt-war

Modify the deployment descriptors of a war by replacing given strings with other strings as specified in a properties file. Must be called with properties "src-war=<filename of distributed war>", "dest-war=<filename of adapted war>" and "props=<filename with properties>". An optional property "libs-to-remove" may be set to a comma separated list of files to remove from WEB-INF/lib (because they will be supplied by the containing EAR).

add-env-entry-to-servlet

Modify the deployment descriptors of a war by adding an environment entry. Must be called with properties "src-war=<filename of distributed war>", "dest-war=<filename of adapted war>" and "env-entry-name=<name of environment entry>", "env-entry-type=<type of environment entry>" and "env-entry-value=<value of environment entry>". The target needs additional resources (DTDs, schemas and "assembly-utils.xml") which must be provided in a directory specified with property "resource-dir=<directory>".

1.4.1.2. Helpers for adapting the workflow engine EJBs

File assembly-resources/assembly-helpers.xml in the workflow engine EJB JAR uses the general purposes targets described above and adds to them, thus providing specific targets for the workflow engine EJBs.

adapt-wfmopen-modules

Modify the deployment descriptors of WfMOpen modules "de.danet.an.wfcore-ejbs.jar", "de.danet.an.wfcore-client.jar" and "de.danet.an.workflow.wfxml.war". Must be called with properties "src-dir=<directory with distributed modules>", "target-dir=<directory for adapted modules>" and "props=<filename with properties>". The target needs additional resources (DTDs, schemas and "assembly-utils.xml") which must be provided in a directory specified with property "resource-dir=<directory>". An optional property "libs-to-remove" may be set to a comma separated list of files to remove from WEB-INF/lib of the WARs (because they will be supplied by the containing EAR).

adapt-client-jar

This target is called by "adapt-wfmopen-modules". It configures the StandardWorkflowEngineFactory by adding a file de.danet.an.workflow-wfs.properties with an appropriate entry to the client jar. Must be called with properties "src-client-jar=<filename of distributed client jar>", "target-client-jar=<filename of adapted client jar>" and "props=<filename with properties>".

make-deployment-service

Replace strings with other strings in a deployment descriptor as specified by a properties file and wraps the result as a SAR. This target is provided because JBoss documentation does not explicitly state that you can put arbitrary deployment descriptors (e.g. for creating a data source) in an EAR. You can, however, wrap them in a SAR and put this SAR in the EAR (and have it deployed by an entry in "jboss-app.xml". This target must be called with properties "deployment-xml=<the deployment description>", "dest-file=<filename of the SAR>" and "props=<filename with properties>".

1.4.1.3. Helpers for adapting the utility EJBs

File assembly-resources/assembly-helpers.xml in the utility EJB JAR uses the general purposes targets described above and adds to them, thus providing specific targets for the utility EJBs.

adapt-util-ejbs

Modify the deployment descriptors of utility ejbs by replacing given strings with other strings as specified in a properties file and adding security information retrieved from the same properties file. Must be called with properties "src-ejb-jar=<filename of distributed ejb jar>", "target-ejb-jar=<filename of adapted ejb jar>" and "props=<filename with properties>". The target needs additional resources (DTDs, schemas and "assembly-utils.xml") which must be provided in a directory specified with property "resource-dir=<directory>".

adapt-util-modules

Modify the deployment descriptors of the utility library modules. Must be called with properties "src-dir=<directory with distributed modules>", "target-dir=<directory for adapted modules>" and "props=<filename with properties>". The target needs additional resources (DTDs, schemas and "assembly-utils.xml") which must be provided in a directory specified with property "resource-dir=<directory>".

1.4.1.4. Sample properties file

A sample properties file for use with the above ant scripts is shown below.

# # Information needed for
        application assembly #

# Adapt utility EJBs' JNDI names. They have no "reasonable" defaults,
# so we have to specify very much. Note that these JNDI names are
# define separately as the utility EJBs may be shared between
# different applications. Note that "ejb/" will be prepended to the names
# specified below automatically and the entries for local home interfaces
# have "Local" appended to the name.
@@@_Utility-EJBs_UtilEJB_JNDI_Name_@@@ = \
          de.danet.an.wfdemo.util-lib.Util
@@@_Utility-EJBs_KeyGenEJB_JNDI_Name_@@@ = \
          de.danet.an.wfdemo.util-lib.KeyGen
@@@_Utility-EJBs_KeyGenLockEJB_JNDI_Name_@@@ = \
          de.danet.an.wfdemo.util-lib.KeyGenLock
@@@_Utility-EJBs_EJBSinkEJB_JNDI_Name_@@@ = \
          de.danet.an.wfdemo.util-lib.EJBSink
# Adapt utility EJB's data source reference
java\:/DefaultDS = java:/WfMOpenDS

# Adapt other EJBs' JNDI names. Most application servers require that
# you specify JNDI names although all references to the EJB are via
# links within the application. We simply define a prefix for those.
# This prefix is also used for JNDI names of other resources. Note that
# "ejb/" will be prepended to the prefix specified below when used to
# derive JNDI names for EJBs.
@@@_JNDI_Name_Prefix_@@@ = de.danet.an.wfdemo.

util-ejbs-security-domain = java:/jaas/wfdemo
util-ejbs-security-roles = \
  WfMOpenAdmin: \
    KeyGen*KeyGenLock*EJBSink*Util;
util-ejbs-security-identities = TimeoutHandler:WfMOpenAdmin
util-ejbs-security-principals = TimeoutHandler:WfMOpenAdmin_Principal

# Adapt workflow engine (note that the engine uses the util EJBs, 
# necessary replacements are already covered by the properties above).
java\:/jaas/wfmopen = java:/jaas/wfdemo

1.4.2. Basic deployment

The workflow EJBs can be deployed in the usual way defined by J2EE:

<application>
  <display-name>My application using WfMOpen</display-name>
  <module>
    <ejb>de.danet.an.util-ejbs.jar</ejb>
  </module>
  <module>
    <ejb>de.danet.an.wfcore-ejbs.jar</ejb>
  </module>

  <module>
    <ejb>some.user.my.application.jar</ejb>
  </module>
</application>

Make sure that you have included all libraries needed by the workflow EJBs in the lib/ directory of your J2EE application as described in Section 1.3.4, “Workflow module”. This is a usable configuration if you only define workflow processes without any resources (i.e. only automatically executed activities). If resource assignment to activities is needed, some additional services have to be supplied as described below.

If you combine the workflow engine EJBs and servlets (packed as WARs) in a single EAR, it is advisable to have libraries used by both components only in the EAR (i.e. not in the WARs' WEB-INF/lib directory. In such a configuration, the libraries must explicitly be deployed as Java modules in application.xml. Note that this and other packaging aspects are not WfMOpen specific. Rather they apply to J2EE applications in general and details are bexond the scope of this manual. See one of the many books about J2EE for further informations.

1.4.3. Additional services

An issue not necessarily handled by a workflow core service is the issue of resource assignment. The OMG specification explicitly leaves this topic to a to-be-defined resource assignment facility. We have therefore chosen to introduce a simple interface to a resource assignment service in our design. This interface is described in detail in the package de.danet.an.workflow.spis.ras.

In order to keep this interface easily implementable by any kind of architecture, access to this service is not based on JNDI and an EJB home interface. Access rather follows the established generic pattern to create a service using a factory class. In order to use the workflow component, an implementation of this service must be provided.

The workflow component includes a sample implementation of a resource assignment service. If you want to use this implementation, some additional configuration issues arise which are discussed in Section 6.1, “The sample assignment service”.



[1] Most applications servers still support distributed transactions if one participating resource does not support distributed transactions. If your application server does, you may use a database that does not support distributed transactions. Be prepared to get some warnings from your application server, though.

[2] The provided RDBMS specific scripts were generated by processing this file with the DDLUtils for the specific RDBMSs.

[3] You should expect that only EJBs that are to be looked up by clients require binding to global JNDI names. It has turned out, however, that some application servers require explicit specification of global JNDI names for all EJBs, and others (even worse) choose default global JNDI names based on the EJB's names. Therefore, to avoid conflicts between different instances of the workflow engine on one application server, global JNDI names must be supplied in any case.

[4] The other supported methods also have some benefits; it depends on your usage scenario.

[5] Thus you have three possibilities to provide the required priviledges:

  1. In the user management system used by your application server, make all users of the workflow engine members of the role "WfMOpenAdmin".

  2. If your application server supports mapping between application roles and roles managed in your security domain (JBoss does not support this, e.g. Sun AS does) you can map "WfMOpenAdmin" to an existing role in your security domain, thus allowing all users in the existing role to access the workflow engine.

  3. In all deployment descriptors, replace "WfMOpenAdmin" with the name of an exsting role in your user management system. This is typically done during deployment but may also be done during application assembly.

[6] The source distribution includes a stylesheet that, together with the appropriate invocations from ant scripts, adds security information to deployment descriptors.

[7] If you use JBoss, you do not have to set the endorsed library directory, because JBoss comes updated libraries in its $JBOSS_HOME/lib/endorsed directory. This directory is automatically set as endorsed directory in the JBoss run-scripts.

Chapter 2. States and state transitions of processes and activities

Dr. Christian Weidauer

Danet GmbH
BU BTS

Dr. Michael Lipp

Danet GmbH
BU BTS

2.1. States of processes and activities

Both WfProcess and WfActivity objects can assume the same six different states. The following table itemizes these states and explains their meaning for processes and activities.

Table 2.1. Meaning of execution object states

state \ objectprocessactivity
open.not_running.not_startedAfter creation the process is active and ready to be initialized and started.After creation the activity is active and ready to be initialized and started when its start condition is fulfilled.
open.running The process is active and executing in the workflow. The process may start new activities.The activity is executing in the workflow. The activity is invoking the implementing tools or a sub process was started and is running.
open.not_running.suspended The process is active and quiescent, but ready to execute. Its execution is temporarily paused, so that no further activities depending on this process may be started. The execution of the activity is temporarily paused. If the activity is implemented as a sub process the process is also suspended.
closed.aborted Indicates that the enactment of the process has been aborted before normal completion. The only assumption on the state of activities depending on this process is that no activity is running. Note, however, that tools may still be running if they do not support asynchronous termination. Indicates that the enactment of the activity has been aborted before normal completion. No assumptions on the state of sub processes and tools depending on this activity are made when it enters this state.
closed.terminated Indicates that enactment of the process was stopped before normal completion. It is assumed that all activities depending on this process have never been started or are completed or are terminated when it enters this state. Indicates that enactment of the activity was stopped before normal completion. It is assumed that all sub processes and tools depending on this activity are either completed or are terminated when it enters this state.
closed.completed When a process has finished its task normally in the overall workflow process it enters the completed state. It is assumed that all activities associated with the process are completed or not started when it enters this state. Further, the combination of the conditions on the incoming transitions of activities that are not started must evaluate to false. When an activity has finished its task normally it enters the completed state. It is assumed that all tools or sub processes associated with the activity are completed when it enters this state.

2.2. State transitions of processes and activities

During the life cycle of processes and activities their states change. The following figure shows supported state transitions of WfProcess and WfActivity objects.

State transitions of execution objects

Figure 2.1. State transitions of execution objects


As can be seen in the figure, both the WfProcess and WfActivity objects start in state open.not_running.not_started when they are created and finish in one of three different closed states.

2.3. Triggers of state transitions

State transitions are triggered by the client API and the engine or can be an reaction to exceptions occuring when invoking tools.

The following table shows how calling a client API operation changes the state of an execution object (process or activity). The numbers used in the following tables refer to the state transitions in the above state diagram.

Note that triggering a state change will cause the workflow engine to either make the intended transition or to throw one of the exceptions declared in the API (see Section A.1.36, “Interface WfExecutionObject”, Section A.1.42, “Interface WfProcess” and Section A.1.29, “Interface WfActivity”). As a result of the transition made, however, the object's state may further be updated by the engine or other clients running in different threads. Thus querying the state of an execution object immediately after successfully triggering a state change may return a state different from the target state of the transition in the table.

Table 2.2. State transitions triggered by client API calls

object \ methodstartsuspendresumeterminateabortcomplete
WfProcess1432, 75n. a.
WfActivityn. a.432, 758, 9

The "unobservable" (from the client's point of view) state transitions caused by a call to complete may seem strange at first. See the method's API documentation (complete()) for further information about the behaviour.

Usually, state transitions of an execution object will cause further state transitions of other execution objects. There are six cases to distinguish, which are shown in the following table. The head row of the table defines the state transition of the triggering object. This transition may influence the triggered object (triggering object -> triggered object). Its potential transitions are listed in the table elements. E. g. table element (1(a)) in the second table row (WfProcess (parent) -> WfActivity) and fifth column (3) means: The state transition 3 of a parent process may cause a state transition 1 of its activities if the start condition of the activities is fulfilled.

Special attention has to be paid to state transitions of activities with manual start and/or finish mode. These modes are implemented by setting the activity object to state open.not_running.suspended instead of state open.running (manual start mode) or state closed.completed (manual finish mode). When resuming an activity object (transition 3) the engine will therefore take into account why the activity was suspended and proceed accordingly.

Table 2.3. State transitions triggered by the engine

object \ transition0123456789
WfProcess (parent) -> WfActivity01(a) 1(a) 5, 7, 4(j)n. a.7n. a.n. a.
WfProcess (sub) -> WfActivityn. a.n. a.n. a.  587n. a.n. a.
WfActivity -> WfProcess (parent)n. a.n. a.   46(d), 7(e)7(c)  
WfActivity -> WfProcess (sub) 0 & 1(k)n. a.345n. a.7 n. a.
WfProcess -> WfProcess (itself)    5(b)   n. a.n. a.
WfActivity -> WfActivity (itself) 4(f) 4(g), 6(h)5(b)   4(g), 6(i) 

(a)

If the start conditions of the activity evaluate to true.

(b)

If the triggering transition 4 (to open.not_running.suspended) was caused by an activity state transition 5 (to closed.aborted). Occurs if an activity aborts (causing everything else to abort) and the process (or an activity of the process) is in state open.running. Then closed.aborted can only be reached via an intermediate open.not_running.suspended.

(c)

If there are no more running activities or activities with start conditions evaluating to true.

(d)

If there are no more running activities and no activities with start conditions evaluating to true and all closed activities have state closed.completed.

(e)

If there are no more running activities and no activities with start conditions evaluating to true and one or more closed activities have a state other than closed.completed.

(f)

If start mode is manual.

(g)

If the activity's finish mode is manual and no work remains to be done.

(h)

If activity was suspended because finish mode is manual.

(i)

If the activity's finish mode is automatic and no work remains to be done.

(j)

If the activity cannot be terminated.

(k)

If the start mode of the activity is manual, creation and start of the sub-process will be delayed until the activity has been resumed.

Besides the triggering by the client or the engine, there are three more possible causes for state transitions:

  • A failure to invoke a tool causes state transition 7 of the invoking WfActivity object.

  • The detection of a loop causes the activities on the path to be reset, i.e. their state changes internally from closed... to open.not_running.not_started (see Section 4.3.4, “Loops” for details about loops). This change of state is not recorded as an audit event, because the repeated execution of an activity is interpreted as several instances of the activity being executed one after the other. Thus the first activity instance is started, runs and completes, then the second activity instance is started, runs and completes. There is no observable change from closed... to open.not_running.not_started.

  • If the preliminary choice of an activity in a deferred choice is revoked (because another activity is chosen), its state changes from open.running to open.not_running.not_started (see Section 4.3.5, “Deferred choice” for details about the deferred choice). This change of state is recorded as an audit event, as it is part of the activity's execution sequence.

2.4. Exceptions

Besides events triggered by a client, an activity may also receive exceptions. Exceptions are defined in the XPDL specification as a general mechanism to signal an exceptional condition to an activity. The only specifically defined exceptions are those generated by the arrival of a deadline that has been defined for an activity. WfMOpen additionally supports handling exceptions from tool invocations, see Section 3.5.4, “Exception handling” for details.

As far as state is concerned, exceptions are basically handled like the final complete call[8]. Any running tool is terminated and tools not yet invoked are skipped.

It may at first be surprising that the activity reaches closed.completed when an exception occurs. However, any other resulting state of an activity would have a strange effect on the final process state, as it would prohibit the process from reaching the completed state (see Section 2.1, “States of processes and activities”)[9]. From a process' point of view everything is all right. A deadline may have occurred and some special transitions may have been taken, but the process has still performed within its specification.

Things look a bit different, though, from the perspective of a subprocess started by an activity that receives an exception. This process is forcefully terminated by its requester (the activity that has received the exception). It therefore assumes the state terminated or aborted. In contrary to the normal state transitions, this does not cause the requesting activity to assume the same state as the activity is set to state completed by the exception processing.

Under normal circumstances, the occurrence of an exception should be derived from the transitions taken in a process. However, as a help for automated evaluations, WfMOpen has introduced the sub-states closed.completed.normal and closed.completed.abandoned with the latter being assigned to an activity that has been completed due to an exception.

2.5. Suspended state and deadlines

XPDL introduces deadlines, OMG knows about a "suspended" state, but neither knows about the other. This leaves the question of how the suspended state affects deadlines. We have defined the semantics as follows.

If an activity is set to state suspended, deadlines are suspended as well, i.e. no exceptions from deadlines will occur[10]. Note that "if an activity is set to state suspended" is not the same as "if an activity is in state suspended". Activities may also reach the state suspended if they have manual start or finish mode. In these cases deadlines are not suspended[11].

If the deadline has been defined as an absolute date time value (see Section 4.2.4, “Deadlines” then setting an activity in the suspended state will not prolong the deadline. If the deadline is reached while the activity is suspended, the related exception will be delivered immediately when the activity is resumed.

If the deadline has been defined as a duration then setting an activity in the suspended state will prolong the deadline, i.e. the deadline will be delayed by the accumulated time that the activity has spent in the suspended state.

Dynamic deadline conditions, i.e. conditions that depend on process relevant data, will be re-evaluated every time the activity is resumed. The advantage of this behavior is that it effectively offers you a choice. If you want your expiration date to remain, you simply use only process relevant data that does not change. The disadvantage is that in order to have invariant process relevant data, you may have to make copies of several items (or, maybe better, calculate your deadline in an independent expression and keep it in some data field).

Maybe the biggest trap in re-evaluation is that the simple conversion of a duration to an absolute date "new Date((new Date()).getTime() + duration)" will not work. While this yields a date, which is not prolonged by the suspend state, it will be re-evaluated when the activity is resumed. Thus the deadline will probably be delayed even more than by using the duration in the first place. There is no solution to this other than saving the start time of the activity in a data item (e.g. by calling the JavaScript tool as first tool of the activity).

2.6. Debugging workflows

Workflows may be run in debugging mode. In this mode, the activities assume some additional, intermediate states. Note that the associated state transitions are neither recorded nor distributed as state change events. The debug mode has been designed to run the workflow in a way that resembles the normal execution as closely as possible. The debug mode is not a simulation. It can best be compared to running a program in a debugger, i.e. the workflow is really executed. There are, however, predefined break points and the invocation of tools may be simulated instead of actually performed.

2.6.1. Enabling debug mode

Debugging mode is enabled for a specific process by calling setDebugEnabled(true) on the process after creating, but before starting the process (see setDebugEnabled(boolean)).

Debugging can also be enabled for a process type by default using the XPDL extension mechanism as described in Section 4.2.5.2, “Extensions on Package and Process Level”.

2.6.2. Effect on state changes

When debug mode is enabled, the execution of activities breaks before the invocation of a tool and before completion of an activity.

Immediately before invoking a tool, the activity's state changes to open.running.debug.invoking. To continue the execution, the activity's state must be changed to either open.running or to open.running.debug.skipping. In the former case, the tool will be invoked as in non-debugging mode. In the latter case, tool invocation will be skipped and the activity will either assume the state open.running.debug.invoking again (if there are more tools to be executed by the activity) or the state open.running.debug.completing (if the invocation of the last tools has been skipped, see below). Of course, the process data must subsequently be modified manually to reflect the changes that would have been made by the tool invocation.

Before the activity is eventually closed, it enters one of the states open.running.debug.terminating, ...aborting or ...completing depending on the closed-state that the activity will assume. To continue execution and cause the activity to assume it proper closed state, the activity's state must be changed to open.running.

2.6.3. Effect on exceptions

In debugging mode, exceptions thrown by tools (i.e. calls to abandon, see abandon(java.lang.String) will cause the activity to assume the state open.running.debug.abandoning. To continue the execution, it is not sufficient to provide the possibility to change the state to open.running as described above for the "normal" transitions to the closed state. There may be several exceptional transitions defined, and it must be possible to specify which exception should be used, else it wouldn't be possible to test the different paths during debugging.

In order to avoid polluting the interface with methods that are only used for debugging, we have defined a special sequence of method invocations that cause the execution to continue (i.e. the state will change to closed.completed.abandoned and the execution of subsequent activities will be triggered as specified by the transitions). You first change the state to open.running.debug.awaiting_exception and then call abandon (see abandon(java.lang.String)) with the name of the exception to be processed. The preceding state change causes abandon(String) to behave differently from normal operation, effectively continuing execution as described above.

In order to avoid any ambiguities, we strongly recommend to execute the two operations (state change and abandoning) in a single transaction. This may be achieved by using a user transaction as described in the J2EE specification or by using the method invocation batch (see Section A.2.31, “Class MethodInvocationBatch”).

WorkflowService wfs = ...;
MethodInvocationBatch mib = new MethodInvocationBatch(true);
mib.addInvocation (activity, "changeState", 
		   new String[] {"java.lang.String"},
		   new Object[] {"open.running.debug.awaiting_exception"});
mib.addInvocation (activity, "abandon",
		   new String[] {"java.lang.String"},
		   new Object[] {exception});
MethodInvocationBatch.Result mir
    = (MethodInvocationBatch.Result)wfs.executeBatch(mib);

2.6.4. Effect on deadlines

Deadlines will be be started in debugging mode just as in non-debugging mode. However, nothing happens when deadlines are reached. The state of deadlines may be monitored by calling deadlines(). To cause the process to proceed as if a synchronous deadline had been reached, you must first call abandon(String), which causes the activity to assume the state open.running.debug.abandoning, and then continue execution as described for exceptions in general above (see Section 2.6.3, “Effect on exceptions”). This may, of course, be done before the deadline has been reached, i.e. the effect of a deadline may be tested without actually waiting for the associated time (which may be quite long) to elapse.

In order to simulate an asynchronous deadline, the state of an activity must first be changed to open.running.debug.forwarding_exception. This causes a subsequent call to abandon to mimic the behavior of an asynchronous deadline, i.e. transitions will be triggered as specified for the given exception. The activity will automatically resume the state that it had before the change to open.running.debug.forwarding_exception. Of course, this sequence of method calls should also be executed in a single transaction, as described above.



[8] The impact on transitions is quite different, of course.

[9] We could have relaxed this dependency, allowing the process to reach the completed state even if an activity is terminated or aborted, provided this state was reached due to an exception. But then the state definition wouldn't be OMG compliant any more.

[10] There has been some disussion if this is the proper behaviour. The reasoning is that setting the activity in the suspend state is nothing that occurs during normal workflow execution. It is a deliberate management action. This action would become farcial if it could be circumvented by a deadline.

[11] We assume that a process designer who defines start or finish mode manual together with a deadline wants that deadline to be executed to e.g. notify the administrator.

Chapter 3. Using the workflow component

3.1. Component structure

The following figure shows the overall structure of Danet's workflow component.

Structure of the workflow component

Figure 3.1. Structure of the workflow component


As can be seen in the figure, the workflow core component provides an EJB based client API. Helper classes on the client side hide most of the EJB invocation details, thus enabling the usage of the component without constantly keeping EJB details in mind.

The workflow component relies on the availability of a resource assignment service. As this service must be provided to the workflow component, it can be thought of as an additional API, or SPI to be precise, of the workflow component.

The distribution includes a sample implementation of such a resource assignment service which is described in detail in Chapter 6, The sample resource assignment service.

Finally the workflow package defines an API (SPI) used to invoke applications that perform activities.

The following sections describe each API in detail.

3.2. Client API

A standard workflow Java API has not been defined yet. Still, we did not want to provide users of our workflow component with a completely proprietary API. Therefore, we have taken a two stage approach.

3.2.1. Adapted OMG interfaces

As a first step, we have adapted the API specified by OMG's Workflow Management Facility Specification, V1.2 to the Java domain. The result of this adaptation can be found in the package description of de.danet.an.workflow.omgcore (see de.danet.an.workflow.omgcore or