Java Development News:

Bonita v2 Series: Part Three

By Brice Revenant

01 Sep 2006 |

This is part three of a trilogy on Bonita v2. Be sure to read part one and part two.

In the two previous articles of the Bonita trilogy, Miguel and Jordi discussed many intrinsic topics of Bonita Workflow engine. This follow-up article steps back and deals with the application layer. Indeed it demonstrates a possible way to couple a Workflow Engine and a Portal. More precisely, Bonita and eXo have been selected by way of implementation. The article shows how workflow processes can be deployed, managed and monitored through JSR 168 Portlets. It also shows how Bonita workflow engine can be leveraged to validate documents contained in the eXo Java Content Repository. We hope ideas presented here can be applied to different integration scenarios.

The first section introduces key concepts. Then we will have a look at the way both components can be integrated, and finally we will study some use cases.

Concepts overview

In this section, we will tackle the concepts of Portal and Workflow in J2EE. Then we will see the advantages offered by their integration.

What is a Portal?

A Portal is a Web application providing unique and customized access to resources of the organization, such as applications, people, documents, and business processes. Java building blocks of Portals are called Portlets. Portlets can be considered as specialized areas in the Web browser acting as a negotiator between users and information systems. Portlets are used in many fields like enterprise content management, groupware, business intelligence, monitoring, or online forms. The following screenshot illustrates a groupware portlet:

Figure 1: Groupware Portlet example. More precisely this is the eXo Calendar Portlet. It enables the management and sharing of the user timetable.

Portlets are laid out in the Web browser to form a kind of patchwork called a Portal Page. By grouping different portlets in the same page, it is possible to provide the user with a control panel to manage his business. This in turn can be compared with multitasking operating systems, which allow interfacing with many applications at once.

Portals are flexible in the sense that they allow customization and personalization. Customization enables the user to tune his or her portal. For example, a user might specify those categories of information he or she wishes to access from personal pages. As a supplement, personalization allows content to be automatically tailored, based on the user profile. For example, a monitoring portlet might determine which business processes a user is involved in and render an appropriate synthetic view. So portals help to increase users' productivity.

Developers are not left out. The JSR 168 standardizes development by providing an API implementing portlets. The implementation is modeled on the servlet API, popular in the J2EE community. Features like security, rendering, profiling, mobility, internationalization and accessibility are handled by the portal infrastructure. This enables developers to focus on the added value, without reinventing the wheel.

System Integrators also join the party. Portals run in JEE application servers and benefit from embedded connectivity stacks, such as JCA (Java Connector Architecture), JMS (Java Message Service), and JAX-WS (Java API for XML WebServices). Portals provide a single sign in to access all integrated applications by authenticating once. Portals are within the reach of customers, employees or business partners. At Bull S.A.S, we think that Portals are a perfect interface with the components of an SOA platform.

eXo Platform is the open source portal implementation in the spotlight for this article. In addition to a generic portal, eXo provides a line of products adapted for specialized fields, such as Enterprise Content Management (eXo ECM), Business Intelligence (eXo BI), and Groupware (eXo Groupware). Within these products, eXo ECM also provides a Portal infrastructure to capture, store, manage, publish and backup documents. eXo ECM features a JCR (Java Content Repository), which is a structured database for storing data. eXo ECM is a good candidate for integrating with Bonita because, as we will see later, a Workflow system adds value when managing document lifecycles.

What is a workflow engine?

The second module in the stack is the workflow engine. A workflow engine, sometimes referred as a BPM (Business Process Management) engine, is a software component that breaks a work process down into tasks. A basic example of such a process is an approval workflow process, in which an employee needs a manager's permission before running an application. A workflow engine provides an infrastructure to model this workflow, execute it, assign the tasks to its participants , and monitor it. To achieve the desired results, it may interact with humans or machines through, for example, Web services. This enables integration with platforms different from Java, like mainframes or .NET.

Bonita is one of the workflow engines gaining great momentum over the past year. Bonita's success is notably due to its API, entirely based on J2EE, hence the concept of "Workflow Beans."

  • In concrete terms,
  • Process models, process instances and users are modeled by Entity Beans,
  • Workflow operations are executed in Session Beans manipulating those Entity Beans,
  • Workflow events can be handled in Message Driven Beans.

Learning Bonita API is fast because it involves concepts familiar to most Java developers. This also implies that Bonita runs in an Application Server and benefits from built-in services such as transactions, security, connectivity, presentation, clustering, and high availability. As often in J2EE, there is no need to reinvent the wheel.

Bonita API can be used to design process models programmatically by invoking EJBs. In addition, Bonita v2 series recently introduced the possibility to import Workflow models in XPDL (XML Process Definition Language). We utilize this new feature deploying processes in eXo.

The following screenshot shows "ProEd," a designer tool that allows generating custom-tailored Bonita processes in XPDL.

Figure 2 ProED example: "ProEd" is a Workflow Process designer appropriate for Bonita

Why merge eXo Portal and Bonita Workflow?

Now that Portal and Workflow concepts are clarified, let's look at the benefits of the merge.

First, many organizations express the need to run a flexible and unique solution to interface with their back office. This solution includes business processes. On one side, as we have seen, we have eXo which is skilled at presentation, personalization and integration. On the other, Bonita Workflow stands out with automation, modeling and collaboration. A unique tool pools all these strengths and provides an answer to the organization's expectations. Employees or customers need to authenticate only once to access all resources. In addition, the common "look and feel" of the organization are commonly applied thanks to CSS (Cascading Style Sheets) skins in eXo.

Second, eXo ECM provides an infrastructure for content management. Documents are created by writers in the Portal, read over by proofreaders who plan the publication during a period of time. At the end, those documents must be archived. Bonita complements the solution devised by the eXo Platform to implement the flow of documents and organize the collaboration between humans. In exchange, eXo exposes its JCR and allows Bonita to invoke stored Groovy scripts or Business Rules during task executions.

Third, Bonita is mainly a Workflow Engine. Bonita requires a user interface layer to generate online forms when interacting with humans. eXo could put its JSF (Java Server Faces) functionalities at disposal. The fact that JSF is now included in J2EE will undoubtedly make this technology grow even more in the future. eXo can also be combined with AJAX (Asynchronous JavaScript and XML) to enrich the user's experience when Workflow forms are filled in.

To summarize, the major objective is to benefit from the best of Portal and Workflow components. The following session details how they can be integrated.

How to integrate the Portal and the Workflow engine

We will now unveil the underlying technical points behind the integration of eXo Platform and Bonita.

How to bundle both components

On one hand, eXo is a set of Portlet WARs (Web Application Archives), plus a lightweight container composed of JARs (Java Archives). On the other, Bonita EJBs are typically deployed in JOnAS, the application server backed by Bull S.A.S. It was decided to bundle everything in the same EAR (Enterprise Archive). This makes deployment easier if clustering is needed to improve performance and reinforce high availability. This also allows the security context to be propagated from portlets to workflow EJBs. The merge was made easy by the eXo build configuration based on Maven 2. When that merge occurred, Bonita artifacts were created and made available on the Internet. The current repository site is When the final version is available, we will also publish the artifacts to

The inner architecture of eXo is key when integrating third party software components. Indeed, eXo is based on a lightweight container where services running in the portal are deployed. Examples of services are Portlet Container, Security, Logging or Database. Dependency Injection is used to propagate references between them. This means that instead of directly hard coding Java references to other components, a service receives those references from the container. This pattern was used when implementing workflow logic in the portal. An eXo service was developed wrapping Bonita functionality. It presents a set of basic functions needed to manipulate the workflow. The following illustration shows the service interface:


 public interface WorkflowServiceContainer { public void deployProcess(InputStream iS) throws IOException; public List<Process> getProcesses(); public Process getProcess(String processId); public boolean hasStartTask(String processId); public List<ProcessInstance> getProcessInstances(String processId); public ProcessInstance getProcessInstance(String processInstance); public Map getVariables(String processInstanceId, String taskId); public List<Task> getTasks(String processInstanceId); public Task getTask(String taskId); public List<Task> getAllTasks(String user) throws Exception; public List<Task> getUserTaskList(String user); public List<Task> getGroupTaskList(String user) throws Exception; public List<Timer> getTimers(); public void startProcess(String processId); public void startProcess(String remoteUser, String processId, Map variables); public void startProcessFromName(String remoteUser, String processName, Map variables); public void endTask(String taskId, Map variables); public void endTask(String taskId, Map variables, String transition); public void deleteProcess(String processId); public void deleteProcessInstance(String processInstanceId); }

Figure 3: Methods contained in the Bonita Workflow service

The corresponding implementation is located in the eXo Platform source tree. It can be invoked from portlets or other services, such as the one in charge of Enterprise Content Management. Particularly, it can be leveraged from homemade portlets, which should be interesting in the scope of custom development. Components are loosely coupled. Any evolution in Bonita (for example...a migration to EJB 3.0) has zero impact on dependent code.

Figure 4: Adopted architecture: The Portlet communicates with the Workflow Engine through an abstract layer to increase agility

How to share a common user repository

One benefit of integration is the single login between the Portal and the Workflow Engine. This allows users to not have to authenticate twice when working with workflow portlets.

Bonita implements its own concept of roles to increase flexibility. Bonita tasks are assigned a role determining which J2EE users can execute them. The contents of those roles are dynamically resolved, each time a process is started. To accomplish this, "Role Mappers" are invoked for each possible role. Role Mappers exist as Java code. Although Bonita comes with ready to use Role Mappers, it is possible for process authors to program their own classes and handle custom cases. The following snippet shows the implemented Java interface. The method basically returns a list of J2EE users corresponding to the specified role.


 public interface RoleMapperI { // Returns a collection of users making up the specified role public Collection searchMembers(Object obj, BnRoleLocal role, String userName) throws HeroException; }

Figure 5: Required interface for implementation when writing custom Role Mappers

A new Role Mapper named "ExoOrganizationRoleMapper" is aimed at Workflow designers using eXo and Bonita. It maps Bonita roles with eXo groups. More precisely, it fills in Bonita roles whose names are the same as eXo groups. This allows task assignment to users who are members of a specific group in eXo; for example, "Human Resources," "Directors" or "Administrators." More information about Role Mappers is provided in the introduction article of this series.

In the integration, this concept of roles is preserved. However, the J2EE users are not identified by Bonita, but by the eXo organization service. This is done by appropriately configuring the application server so that the eXo JAAS (Java Authentication and Authorization Service) module is invoked by Bonita. Of course, this works because all components are contained in the same EAR.

The JAAS module delegates to the eXo Organization Service, currently supporting authentication based on database, LDAP and CAS. eXo provides an API to implement support for other authentication systems, including custom authentication.

Figure 6: This diagram shows that eXo and Bonita both leverage the organization service in the container when authenticating users. This service is compatible with various repositories.

Bonita comes with companion tools, such as "Manager" or "Graph Editor." A convenient script is provided to make them connect to the application server hosting both eXo and Bonita. As the user repository is now shared, they can be used to inspect processes deployed in eXo.

Figure 7: "Manager" and "Graph Editor" applications shipped with Bonita. They can be used to connect with the Application Server running eXo and Bonita. This sample screenshot shows a live process instance running in the portal.

How to design the user interface

From human perspective, this tool is accessed through a couple of JSR 168 workflow portlets. Those portlets can be included in portal pages that aggregate other applications to form a unified dashboard.

The Controller Portlet

First, the Controller Portlet is aimed at standard users. It provides two panes. One of those panes renders the processes that the current user is able to start.

Figure 8: List of processes the current user may start

When the user selects one of the processes, a form is displayed in the pane. The form enables the user to supply information for launching the new process instance.

Figure 9: An example of a form in eXo-Bonita

The second pane contains the list of tasks assigned to the current user. This is what we call the Bonita "To Do" list.

Figure 10: This panel lists the tasks assigned to the current user.

When the user selects one of the tasks in Figure 10, the corresponding form dialog is displayed. Some fields may already be filled, based on the contents of the running process instance.

The Admin Portlet

The second portlet is aimed at administrators. It also contains two panes. The first pane lists all processes deployed in eXo. It is possible to undeploy some of the processes by selecting the "Delete" icon. In addition, it is possible to deploy new processes by clicking on the top right icon.

Figure 11: This pane lists all deployed processes

By selecting a process, the administrator can display all the corresponding running instances. An administrator can also kill instances.

Figure 12: This pane lists all running process instances

If the user scrolls down, they can monitor the status of the running instance, including executed tasks. An empty end date means the task is waiting for what has not been processed yet by human action.

Figure 13: This pane lists the executed and waiting tasks. It also gives the corresponding roles.

The second pane of the Portlet lists all Bonita currently set deadlines. Deadlines consist of timers giving some temporal constraints to the Workflow execution.

Figure 14: This pane monitors the Bonita deadlines

Both controller and admin portlets are available only in private portal pages. These portlets require user authentication before interacting with the workflow engine.

How to display workflow dialog forms

Bonita distinguishes between two types of properties. There are the task properties, which are specific to a given task, and the global properties, which are shared by all tasks in the process. Users can set or retrieve both properties by means of bounded fields. Those fields are displayed in dialog forms when starting a new process or when managing a task in the to do list.

A form service has been designed in eXo to handle the dialog generation. The person in charge of designing a workflow has three options when specifying a form.

Automatic generation

A designer can let the service automatically generate a form, based on local and global properties of the process. This feature is notably mostly useful when prototyping. It is also potentially useful when running cooperative Bonita processes. Cooperative processes allow some users to edit in real time the behavior of a long term running process, for which some tasks are unknown a priori. To a certain extent, they are a kind of Wikis for Workflows. In that scenario, automatic forms allow people to bypass the form specification and focus on the design of the process.

Form dialogs specification

A designer can also select which properties have to be shown, internationalize their labels, and specify the JSF renderers to be used. This configuration is done in "forms.xml," a descriptor coming with each process deployed in eXo. The following snippet shows an extract of this file:


 <forms> ... <form> <resource-bundle>evaluation</resource-bundle> <state-name>evaluation</state-name> <variable name="document-id" component="nodeview"/> <variable name="initiator" editable="false"/> <variable name="startDate" component="datetime"/> <variable name="endDate" component="datetime"/> <variable name="delegate"/> <variable name="decision" component="radiobox"/> </form> ... </forms>

Figure 15: Definition of a form

Figure 15 demonstrates how Workflow properties are bounded with rendering components. The corresponding form is shown below:

Figure 16: The corresponding form

The following screenshot shows the range of currently available widgets.

Figure 17: All those widgets can be included in forms

Velocity specification

Finally, a designer can provide a Velocity template. Velocity Templates are similar to JSPs (Java Server Pages) and are widespread in eXo Platform s because of their easy usage. In that scenario, eXo instantiates the JSF components behind the scene and the template is responsible for arranging them in the Portlet area.

This option is perfect for a fine layout of components. In addition, as the HTML code is controlled, Java Script code can be written to manage values provided by the user. This paves the way for AJAX.

The following snippet shows an example of a Velocity template. An image is first displayed for a bit of atmosphere. Then JSF fields are added and bounded to Bonita properties by the "#jsfFormField" Velocity directive. Finally a numeric check is attached to a field to demonstrate how javascript can be used.


 #jsfForm() <table border="0"> <tr> <th colspan="2" height="50" align="center"> My custom velocity form<br> <img src="" height="35" width="150" border="0"> </th> </tr> <tr> <td> <tr> <td>Employee :</td> <td>#jsfFormField("initiator")</td> </tr> <tr> <td>Amount to be added :</td> <td>#jsfFormField("amount-granted")</td> </tr> </td> </tr> <tr> <td> #jsfFormButton("finish it" $uicomponent.endOfState) #jsfFormButton("@UITask.cancel" $uicomponent.cancelProcess) </td> </tr> </table> <script type="text/javascript"> var previous = 0 function myalert() { value = document.getElementsByName("amount-granted")[0].value if (((value / value) != 1) && (value != 0)) { alert("Please enter a numeric value !") document.getElementsByName("amount-granted")[0].value = previous } else { previous = value } } document.getElementsByName("amount-granted")[0].onkeyup = myalert </script> #end

Figure 18: A sample Workflow form in Velocity

The following screenshot shows the resulting Workflow form dialog:

Figure 19: Result of the previous Velocity template: Some fields are dynamically checked by JavaScript when the user updates them.

How to package and deploy processes

When deploying Processes in the Portal, it was decided to package all needed items in simple zip files called BPARs ("Business Process Archives"). A BPAR typically contains:

  • The Process Definition file, in XPDL,
  • Custom Java classes needed by Bonita when running the Process. They include Hooks invoked when Tasks are being executed and Role Mappers invoked when resolving roles.
  • The forms.xml file,
  • Velocity templates,
  • Internationalization bundle files.

This makes Process manipulation more practical. A Maven 2 sample project is provided to help designers compile and package their own BPARs.

How to leverage the JCR?

As specified earlier, a JCR is a sort of hierarchical database. Information is contained by Nodes which contain Properties themselves. The approach promoted by eXo is to store and structure the documents of the Organization in such Nodes.

A dedicated service is available in eXo to abstract operations on JCR Nodes. Thus it is possible to retrieve a reference to that service from Bonita Hooks, when executing a Process. The JCR API can be used subsequently to manage documents. This feature is notably useful for validating content. Indeed, JCR documents can be referenced from Process Properties and rendered in Portlets. We will study this use case later.

We also found that the JCR is a great place to persist the contents of the deployed BPARs. In eXo, there exists a path dedicated to stor ing system information needed by the Portal, such as taxonomies, rules, scripts, or Velocity templates. A new entry was added, to hold the files contained by the BPARs, such as the Process Definition, the form definitions, or the internationalization bundles. The administrator can edit them online thanks to the ECM File Explorer, without having to redeploy the Processes.

Figure 20: BPAR contents, accessible from the ECM File Explorer.

Use cases

In this final section, we present two possible applications. The first demonstrates a simple approval workflow and the second demonstrates content validation using JCR. Before the applications are explained, eXo-Bonita installation instructions are presented.


eXo-Bonita is available on top of the JOnAS application server, as a package containing all appropriate modules and configuration. The eXo-Bonita package needs to be unzipped in a fresh JOnAS 4.7. X installation. The required steps are as follows:

  1. First download JDK 1.5 from After the JDK installation, make sure that the JAVA_HOME environment variable is defined and correctly references the JDK directory.
  2. JOnAS 4.7. X is available at Download the JOnAS package and install. Create a JONAS_ROOT environment variable, referencing the JOnAS installation location.
  3. Download eXo-Bonita 1.0 from Although we published this article using Release Candidate 4, we strongly recommend the Final release when available. In the list, search preferentially for a file named "," or if not yet available, "" When downloaded, extract it into your JONAS_ROOT directory. This should create and overwrite some files.
  4. Execute the final configuration procedure . Enter:
  • "%JONAS_ROOT%binntpost-patch.bat" on Windows or "$JONAS_ROOT/bin/nt/" on Unix.

To access the Portal, first issue the command "%JONAS_ROOT%binntjonas start" on Windows, or "$JONAS_ROOT/bin/unix/jonas start" on Unix. Then in a browser enter http://localhost:9000/ecm. Login is "exoadmin" and password is "exo". The Workflow Portlets can be reached by selecting the "Portlets" menu.

Approval use case

Together in this first use case, we create our first BPAR. Remember, in the first article of this trilogy, Miguel presented an Approval Process. This sample models a request process granting usage of fictitious applications named "application1," "application2" and "application3." The user launching the Process is supposed to choose among one of them and supply a name, email address and phone number before submitting the request. Then, the "Approval" Task is assigned to an administrator who has to make a decision. The processing flow is finally routed toward the "Acceptance" or "Rejection" task, depending on the decision. In both case, a notification email is simply sent back to the initiator.

Figure 21: Graphic representation of the Approval Process sample to be ran in the Portal

We will take this opportunity to migrate this Approval Process to the Portal.


Maven 2 must be installed on the machine beforehand. Please follow the instructions provided at Maven 2 is supposed to download dependent project libraries from the Internet, but for legal reasons, some libraries need to be downloaded manually. This is notably the case for a required EJB library. For that reason, it is necessary to run a preliminary command.

On Windows:

mvn install:install-file -DgroupId=javax.ejb -DartifactId=ejb -Dversion=2.1 -Dpackaging=jar -Dfile=%JONAS_ROOT%libappsejb-2.1.jar

On Unix:

mvn install:install-file -DgroupId=javax.ejb -DartifactId=ejb -Dversion=2.1 -Dpackaging=jar -Dfile=$JONAS_ROOT/lib/apps/ejb-2.1.jar

Afterwards, Maven 2 has all necessary components.

Files creation

Now create a directory called "approval" somewhere on your machine. It contains all necessary files when building the BPAR. Each file is listed below. The location, content and related explanations are given, to complete the tutorial.


  • approval/pom.xml


 <project> <groupId>org.objectweb.bonita</groupId> <version>1.0</version> <modelVersion>4.0.0</modelVersion> <artifactId>approval</artifactId> <packaging>jar</packaging> <name>Approval Workflow BPAR</name> <dependencies> <!-- Bonita API --> <dependency> <groupId>org.objectweb.bonita</groupId> <artifactId>bonita</artifactId> <version>1.7-2006_05_23</version> <type>ejb</type> <scope>compile</scope> </dependency> </dependencies> <build> <sourceDirectory>src/java</sourceDirectory> <outputDirectory>target/classes</outputDirectory> <!-- What to be included in the BPAR --> <resources> <resource> <directory>src/conf</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> <include>**/*.xpdl</include> </includes> </resource> </resources> </build> <repositories> <!-- Remote repository where Bonita artifacts are located --> <repository> <id>objectweb-snapshot</id> <url></url> </repository> </repositories> </project>

This is the object model describing the project. The "bonita" artifact specified in the dependencies section allows reusing the Bonita API. Please note that the version "1.7-2006_05_23" corresponds to a release candidate. It is recommended to switch to a stable artifact when the final release is available. For more information about Maven 2, we strongly recommend browsing the excellent project site at

You may want to reuse the same file when packaging your own Processes for eXo.


  • approval/src/conf/Approval_workflow.xpdl


 <?xml version="1.0" encoding="UTF-8"?> <Package xmlns="" xmlns:xpdl="" xmlns:xsi="" xsi:schemaLocation="" Id="Approval_workflow" Name="Approval_workflow"> <PackageHeader> <XPDLVersion>1.0</XPDLVersion> <Vendor>Bull</Vendor> <Created>07 juin 2006 08:40:39</Created> </PackageHeader> <RedefinableHeader PublicationStatus="UNDER_TEST"> <Author>Miguel Valdes Faura</Author> </RedefinableHeader> <ConformanceClass>NON_BLOCKED</ConformanceClass> <WorkflowProcesses> <WorkflowProcess AccessLevel="PUBLIC" Name="Approval_workflow" Id="Approval_workflow"> <DataFields> <DataField Id="decision" Name="decision"> <DataType> <EnumerationType> <EnumerationValue Name="reject" /> <EnumerationValue Name="grant" /> </EnumerationType> </DataType> <InitialValue>reject</InitialValue> <ExtendedAttributes> <ExtendedAttribute Name="PropertyActivity" /> </ExtendedAttributes> </DataField> <DataField Id="User_name" Name="User_name"> <DataType> <BasicType Type="STRING" /> </DataType> </DataField> <DataField Id="Email_address" Name="Email_address"> <DataType> <BasicType Type="STRING" /> </DataType> </DataField> <DataField Id="Phone_number" Name="Phone_number"> <DataType> <BasicType Type="STRING" /> </DataType> </DataField> <DataField Id="Available_applications" Name="Available_applications"> <DataType> <EnumerationType> <EnumerationValue Name="application1" /> <EnumerationValue Name="application2" /> <EnumerationValue Name="application3" /> </EnumerationType> </DataType> <InitialValue>application1</InitialValue> </DataField> </DataFields> <Participants> <Participant Id="SYSTEM" Name="SYSTEM"> <ParticipantType Type="SYSTEM" /> <ExtendedAttributes> <ExtendedAttribute Name="NewParticipant" Value="true" /> </ExtendedAttributes> </Participant> <Participant Id="member:/company/direction" Name="member:/company/direction"> <ParticipantType Type="ROLE" /> <ExtendedAttributes> <ExtendedAttribute Name="Mapper" Value="Custom" /> <ExtendedAttribute Name="MapperClassName" Value="hero.mapper.ExoOrganizationMapper" /> <ExtendedAttribute Name="NewParticipant" Value="true" /> </ExtendedAttributes> </Participant> </Participants> <Activities> <Activity Id="Rejection" Name="Rejection"> <Implementation> <No /> </Implementation> <StartMode> <Automatic /> </StartMode> <ExtendedAttributes> <ExtendedAttribute Name="hook" Value="hero.hook.MailReject"> <HookEventName>beforeTerminate</HookEventName> </ExtendedAttribute> </ExtendedAttributes> </Activity> <Activity Id="Acceptance" Name="Acceptance"> <Implementation> <No /> </Implementation> <StartMode> <Automatic /> </StartMode> <ExtendedAttributes> <ExtendedAttribute Name="hook" Value="hero.hook.MailAccept"> <HookEventName>beforeTerminate</HookEventName> </ExtendedAttribute> </ExtendedAttributes> </Activity> <Activity Id="start" Name="start"> <TransitionRestrictions> <TransitionRestriction> <Join Type="AND" /> </TransitionRestriction> </TransitionRestrictions> <Implementation> <No /> </Implementation> <StartMode> <Automatic /> </StartMode> <ExtendedAttributes> <ExtendedAttribute Name="hook" Value="hero.hook.InitialValuesHook"> <HookEventName>beforeTerminate</HookEventName> </ExtendedAttribute> </ExtendedAttributes> </Activity> <Activity Id="Approval" Name="Approval"> <Implementation> <No /> </Implementation> <Performer>member:/company/direction</Performer> <StartMode> <Manual /> </StartMode> <ExtendedAttributes> <ExtendedAttribute Name="property" Value="decision"> <Propagated>No</Propagated> </ExtendedAttribute> </ExtendedAttributes> </Activity> </Activities> <Transitions> <Transition Id="Approval_Rejection" Name="Approval_Rejection" From="Approval" To="Rejection"> <Condition Type="CONDITION">decision.equals("reject")</Condition> </Transition> <Transition Id="Approval_Acceptance" Name="Approval_Acceptance" From="Approval" To="Acceptance"> <Condition Type="CONDITION">decision.equals("grant")</Condition> </Transition> <Transition Id="start_Approval" Name="start_Approval" From="start" To="Approval" /> </Transitions> </WorkflowProcess> </WorkflowProcesses> <ExtendedAttributes> <ExtendedAttribute Name="MadeBy" Value="ProEd" /> <ExtendedAttribute Name="View" Value="Activity" /> </ExtendedAttributes> </Package>

This above corresponds to the definition of the Approval Process. The file should be importable from any XPDL editor, such as BSOA ProEd. It is reworked a bit to fit the Portal environment. First, an automatic Task named "start" is added when launching the Process. Automatic means that the Task is processed by the Workflow engine and requires no human operation to begin. This allows a Bonita Hook to be invoked and the hook populates Process properties with information retrieved from the Portal. Second, the "Approval" Task is assigned the role "member:/company/direction", resolved by the Role Mapper previously mentioned ("hero.mapper.ExoOrganizationMapper"). This allows the mapping Bonita roles with eXo groups.

You will need to do typical adjustments when "portalizing" your own Bonita Process.


  • approval/src/java/hero/hook/


 package hero.hook; import hero.interfaces.BnNodeLocal; import hero.interfaces.Constants; import hero.interfaces.ProjectSessionLocal; import hero.interfaces.ProjectSessionLocalHome; import hero.interfaces.ProjectSessionUtil; import hero.util.HeroHookException; import hero.user.UserBaseService; import hero.user.UserBase; public class InitialValuesHook implements NodeHookI { public String getMetadata() { return Constants.Nd.BEFORETERMINATE; } public void beforeTerminate(Object obj, BnNodeLocal node) throws HeroHookException { ProjectSessionLocal projectSession = null; try { // Initialize Project Session String projectName = node.getBnProject().getName(); ProjectSessionLocalHome projectSessionHome = ProjectSessionUtil.getLocalHome(); projectSession = projectSessionHome.create(); projectSession.initProject(projectName); /* * Retrieve a reference to the User Base service in Bonita. This * service communicates with eXo to retrieve information on users. */ UserBaseService userBaseService = UserBaseService.getInstance(); UserBase userBase = (UserBase) userBaseService.getUserBases().toArray()[0]; // Retrieve workflow session creator and set the instance property with it String userName = projectSession.getCreator(); projectSession.setProperty("User_name", userName); // Retrieve the email address from eXo String emailAddress = (String) userBase.getUserInfos(userName).get("email"); projectSession.setProperty("Email_address", emailAddress); // Retrieve the phone number from eXo String phoneNumber = (String) userBase.getUserInfos(userName).get("phone"); projectSession.setProperty("Phone_number", phoneNumber); } catch (Exception e) { e.printStackTrace(); } finally { try { projectSession.remove(); } catch (Exception ignore) { } } } public void beforeStart(Object arg0, BnNodeLocal arg1) throws HeroHookException {} public void afterStart(Object arg0, BnNodeLocal arg1) throws HeroHookException {} public void afterTerminate(Object arg0, BnNodeLocal arg1) throws HeroHookException {} public void anticipate(Object arg0, BnNodeLocal arg1) throws HeroHookException {} public void onCancel(Object arg0, BnNodeLocal arg1) throws HeroHookException {} public void onDeadline(Object arg0, BnNodeLocal arg1) throws HeroHookException {} public void onReady(Object arg0, BnNodeLocal arg1) throws HeroHookException {} }

The above is a Bonita Hook. The Java code is invoked when an instance is triggered. The first instructions create an EJB Session Bean aimed at modifying settings in the instance. Then, a UserBase is retrieved. A UserBase is a Bonita service that allows retrieving information about the users. By default, the UserBase obtained allows retrieving information from the eXo Organization service. Finally, Process Properties are set based on the obtained user name, phone number and email address. That way, the user does not have to specify this information. It is automatically supplied by the Portal infrastructure.


  • approval/src/java/hero/hook/


 package hero.hook; import hero.interfaces.*; import hero.interfaces.BnNodeLocal; import hero.util.HeroHookException; import hero.util.BonitaServiceLocator; import java.util.*; public class MailAccept implements hero.hook.NodeHookI { public String getMetadata() { return Constants.Nd.BEFORETERMINATE; } public void create(Object b,BnNodeLocal n) throws HeroHookException {} public void beforeStart(Object b,BnNodeLocal n) throws HeroHookException {} public void afterTerminate(Object b,BnNodeLocal n) throws HeroHookException {} public void onCancel(Object b,BnNodeLocal n) throws HeroHookException {} public void anticipate(Object b,BnNodeLocal n) throws HeroHookException {} public void onDeadline(Object b,BnNodeLocal n) throws HeroHookException {} public void afterStart(Object b, BnNodeLocal n) throws HeroHookException {} public void onReady(Object b,BnNodeLocal n) throws HeroHookException {} public void beforeTerminate(Object b,BnNodeLocal n) throws HeroHookException { try { String nodeName = n.getName(); BnProjectLocal project = n.getBnProject(); String prjName = project.getName(); System.out.println("send mail accept OK during the "+nodeName+" execution"); } catch (Exception e) {System.out.println("mail service error: "+e);e.printStackTrace();} } }

The above code is invoked when the Acceptance Task starts. It simulates the emission of a mail notification. We won't bother with sending an actual email here, but if interested, you can find the actual code in Bonita samples (src/ bonitaStandAloneClient directory). This code basically uses the application server infrastructure to retrieve a Javamail provider.


  • approval/src/java/hero/hook/


 package hero.hook; import hero.interfaces.*; import hero.util.*; import hero.interfaces.Constants; import java.util.*; public class MailReject implements hero.hook.NodeHookI { public String getMetadata(){ return Constants.Nd.BEFORETERMINATE; } public void create(Object b,BnNodeLocal n) throws HeroHookException {} public void beforeStart(Object b,BnNodeLocal n) throws HeroHookException {} public void afterTerminate(Object b,BnNodeLocal n) throws HeroHookException {} public void onCancel(Object b,BnNodeLocal n) throws HeroHookException {} public void anticipate(Object b,BnNodeLocal n) throws HeroHookException {} public void onDeadline(Object b,BnNodeLocal n) throws HeroHookException {} public void afterStart(Object b, BnNodeLocal n) throws HeroHookException {} public void onReady(Object b,BnNodeLocal n) throws HeroHookException {} public void beforeTerminate(Object b,BnNodeLocal n) throws HeroHookException { try { String nodeName = n.getName(); BnProjectLocal project = n.getBnProject(); String prjName = project.getName(); System.out.println("send mail rejection OK during the "+nodeName+" execution"); } catch (Exception e) {System.out.println("mail service error: "+e);e.printStackTrace();} } }

The above Hook is similar in all respects to the previous one.


  • approval/src/conf/forms.xml


 <forms> <form> <!-- The Start name is an empty String by convention --> <resource-bundle>request</resource-bundle> <state-name></state-name> <variable name="Available_applications" component="select"/> </form> <form> <resource-bundle>approval</resource-bundle> <state-name>Approval</state-name> <variable name="User_name" editable="false"/> <variable name="Email_address" editable="false"/> <variable name="Phone_number" editable="false"/> <variable name="Available_applications" editable="false"/> <variable name="decision" component="radiobox"/> </form> </forms>

Above is the file specifying a couple of form dialogs displayed in the Portal. The first <form> tag defines the form displayed for users starting the Process . The second <form> tag defines the form aimed at approvers. For each definition, there are the internationalization resource bundle to be used (<resource-bundle> tag), the name of the corresponding Task (<state-name> tag) and the Workflow Properties accessible from the dialog (<variable> tags).

In the first dialog, only the "Available_applications" property can be set. A combo box is used for that. In the second dialog, all variables are displayed, including those set by the InitialValuesHook. All of the variables are read only, except for the decision variable that must be set by the approver.


  • approval/src/conf/


 task-name=request title=request submit=Request the application Phone_number.label=Your phone number: Available_applications.label=Choose an application:

This is the resource bundle for the first dialog panel. The title of the dialog is provided, as well as labels and possible values for the combo box.


  • approval/src/conf/


 task-name=approval title=A user requested an application submit.submit=Submit submit.value=Submit User_name.label=Requester username: Email_address.label=Requester email: Phone_number.label=Requester phone number: Available_applications.label=Chosen application: decision.label=Your decision: decision.radiobox-0=reject decision.radiobox-1=grant

This resource bundle is similar to the previous one. It is possible to localize the dialogs by supplying additional files, suffixed by the country identification (eg: "").

That's it. At the end, check that the structure of the "approval" directory contains the following directories and files:


 $ find approval/ -print approval/ approval/pom.xml approval/src approval/src/conf approval/src/conf/ approval/src/conf/Approval_workflow.xpdl approval/src/conf/forms.xml approval/src/conf/ approval/src/java approval/src/java/hero approval/src/java/hero/hook approval/src/java/hero/hook/ approval/src/java/hero/hook/ approval/src/java/hero/hook/


In the "approval" directory, issue the command " mvn package". A file "approval-1.0.jar" is generated in the "target" directory. This is your BPAR.


To deploy the BPAR in eXo, log in as an administrator and access the Administration Portlet in edit mode by clicking on its top right corner icon.

Figure 22: Click on that icon to switch the Administration Portlet in Edit mode

You can now upload the generated BPAR to the Portal.

When completed, the "Approval_workflow" Process should appear in the list.


The Process may now be started by Portal users requesting an application. To do so, log in with a standard account, access the Controller Portlet and click on the "Start" icon corresponding to the "Approval_workflow" Process.

Figure 23: Click on "Start"

The first form dialog appears. It allows you to select an application. This is the result of the form specification in the BPAR (see above).

Figure 24: First form dialog

When submitted, a new Task appears in the To Do list of members of the "/company/direction" eXo group. Additional information is provided, such as the current variables and the Process start date.

Figure 25: A Task appears in the To Do list

If you select the "Manage" icon, you can access the second dialog form. This enables termination of the Process. Note that the email and phone number fields are retrieved from the Portal infrastructure.

Figure 26: Second form dialog

At any time, the state of the request can be retrieved from the Processes Monitor tab in the Administration Portlet. It lists the Tasks, the assigned roles, and the execution date. In the following screenshot, the "Approval" Task is waiting execution, hence the empty date field.

Figure 27: State of the Process

Content validation use case

In this second use case study, we illustrate the content validation capabilities of eXo ECM. We create an article in the JCR. Then we request its publication using a Bonita Process and see how the Portal releases it. First, a short introduction to content management in eXo is required to set the scene.

Enterprise Content Management in eXo

From the beginning, eXo Platform has ECM (Enterprise Content Management) capabilities to manage documents accessible from Portlets. An ECM is a framework structuring the Organization content through the process of capturing, storing, managing, publishing , and referencing.

As previously stated, a JCR (Java Content Repository) is used to store documents. In eXo ECM, the JCR is partitioned in Workspaces in independent storage areas. They can be compared with the partitions of a file system. Workspaces allow a first classification of documents. Indeed, eXo provides four classifications by default:

  • The "Draft" Workspace contains documents in creation phase, which have not been approved,
  • The "Production" Workspace contains approved documents and are therefore potentially widely visible,
  • The "Backup" Workspace contains archived documents which are no longer visible,
  • The "Digital Assets" Workspace contains uploaded artifacts that can be referenced when creating documents, for example images, movies, or binary attachments.

Each Workspace is partitioned with Nodes, which comparable with directories in a file system. Some locations are noteworthy. Notably, each user owns a home directory containing private documents. Also, a centralized directory exists to contain published documents.

Documents in directories are contained by JCR Nodes behind the scenes. eXo makes a distinction between two kinds of documents:

  • Structured documents are broken down and stored using Node Properties
  • Unstructured documents are directly stored as binary

The latter option is mostly used for OpenOffice or MS Office documents.

Directories or documents can be monitored by eXo Actions. An Action is a callback invoked when an event occurred at a specified location. They make it possible to launch an appropriate processing in response to a creation, removal, or look up. Predefined Actions are provided, for instance Groovy script execution, Business Rule execution, or Workflow Process execution. Of course, it is possible to implement customized Actions. Each Action has full access to the target document and can provide appropriate processing based on content.

The JCR content is accessible from the eXo ECM Portlet, which has the same principles as Windows File Explorer. It shows available Workspaces, allows selection of one of them, and to access down into its directories. Documents in directories are listed. When selecting one of the documents for reading or editing, a specific Velocity template is displayed in the Portlet. Templates are specific to document types and allow a fine rendering in HTML. Default eXo Templates are provided to render or create common documents such as text files or articles. It is also possible to provide homemade Templates when rendering additional document types.

eXo ECM also displays content through WebDAV (Web-based Distributed Authoring and Versioning). This is a set of extensions to the HTTP protocol allowing users to edit and manage files on remote web servers. The latest versions of Windows have a built-in WebDAV client. This allows browsing the JCR and manipulat ion of the documents (edit, upload, download) from the Windows File Explorer. Quite handy, isn't it?

Hopefully this short introduction to eXo ECM features contributes to have a better understanding of the use case. More information is found in eXo Platform technical documentation at We now set everything in motion. The first step is to create a document. Then we request its publication in the Portal. At that time, we see how a Bonita process is triggered and enables managers to validate the document. Finally we see how other users can reference a document and how its end of life is supported.

Document drafting

First, you must to log on with your Portal account and access the ECM Portlet. By default, this Portlet shows the four default Workspaces mentioned above.

Figure 28: The ECM Portlet showing available Workspaces

Select the "Draft" Workspace to start working on your documents. The view changes to render the directories available in that Workspace.

Figure 29: The ECM Portlet allows browsing into the directories

It is possible to access your home directory. Note that the JCR applies security constraints preventing other users from accessing it. You can now create a new document by clicking on the appropriate icon in the toolbar.

Figure 30: Click on that icon to create an empty document

The type of article to create can be specified in the combo box in the left hand side top corner. Let's say you wish to create a document of type "exo:article." This is a structured document type whose content is stored as JCR Node Properties. It models a news article and contains information such as a title, a summary, a date, an image, and a body. You can fill in the fields. Some fields allow rich text editing.

Figure 31: Article creation

It is also been possible to upload binary documents instead of choosing a structured document type. When completed, click on OK. A new document of type article is created in the JCR. You can see how it is rendered by clicking on it.

Figure 32: The created document as rendered by the Velocity Template

If you are satisfied with the results, you must save your current work session. To save, click on the disk icon located in the upper right corner.

Figure 33: Saving your current work session

Publication request

We now request the document to be published. As seen previously, a dedicated directory is supposed to contain all documents in verifying status. To publish, right click on the document icon, select "Actions," then "Cut."

Figure 34: Moving the document.

Go to the "cms/publication" directory and click on the paste icon. You finally must assign a category to your document. Click on the corresponding icon in the toolbar.

Figure 35: The "Manage Categories" icon

The panel that appears allows choosing hierarchical categories available in eXo. It is also possible to define your own categories to match your needs. In this tutorial, let us choose "cms/news/world".

Figure 36: This panel allows assigning categories to a document

Once again, you need to save your work session to commit the changes. An action is configured to monitor new documents in this directory. It has the effect to launch a Bonita Process instance so that authorized people can review it.


The following Bonita process is launched behind the scenes:

Figure 37: Content Validation Workflow

The approvers are assigned the Task "evaluation" to review the document. Approvers are offered four options:

  • They can approve the document. In that case, they need to set start and end publication dates
  • They can ask the submitter to rework his contribution. After that, the submitter is free to modify the request. In that case, the processing flow iterates so that the document can be re-evaluated. Regarding iterations, we recommend reading the previous article of this trilogy, about iterations. The submitter can also drop everything
  • Approvers can refuse the request
  • Approvers can specify an eXo group name and delegate the work to their members. In that case, a separate Process instance is started

By default, approvers are part of the "/company/direction" eXo group. The "exoadmin" account is one of its members. Let's log into the Portal using this account and access the Workflow Portlet. In the To Do list, we can see that we are assigned a new Task.

Figure 38: The approver is asked to process a document

If you click on the "Manage" icon, you can access the corresponding Workflow form dialog. The form contains classical fields as we saw in the previous use case. The Velocity template is also summarized so that the approver can glance at the article and make a decision.

Figure 39: The approval form dialog. The reviewed document is incorporated.

Specify the dates, make sure the radio button "Approve" is selected and click on "Submit." The Bonita Process is placed in a wait state until the start date is reached. At that time, the document is moved from the "Draft" Workspace to the "Publication" Workspace. It is officially published.

There are two ways to observe this. The first is to use the ECM Portlet to browse the JCR. You see that the document is no longer in the "Draft" Workspace but is stored in the "Publication" Workspace, still under "cms/publication." The second way is to use the "Content Browser" Portlet. This Portlet is available to all Portal users. It basically allows the user to browse documents based on categories. Access the "cms/news/world" category. The document should appear in the content area.

Figure 40: Content Browser Portlet

Click on the document. It is now displayed in the browser.

End of life

The document is accessible from the "Content Browser Portlet" till the publication end date. At that date the document is moved to the "Backup" Workspace for archiving.


Hopefully this article gives you a good insight on this collaborative tool. The integration skills of eXo Platform should help to apply most concepts covered here to any component of an SOA platform.

We won't let the matter rest there. Both eXo and Bonita teams are on the move to add cool new features, such as SVG dynamic rendering of the Workflow Process, JCR-stored rules execution from Workflow Tasks, and Groovy script execution when pre-filling or checking fields. Of course, we welcome any feedback or contribution from the community. We can be reached at the mailing lists (for Workflow related topics) or (for Portal related topics). Finally, the Bonita team would like to thank the eXo team for its great help and openness.

Stay tuned!


  • There are many people who deserve the acknowledgments of the Bonita team. We would like to thank the eXo folks for their great help and openness. We also thank Patrick Silani and Fouad Allaoui for their involvement in the project. We finally thank Roger Perey at Bull Phoenix for his great work when reviewing the articles.


About the author

Brice Revenant is an Engineer working with Bull S.A.S, in the 'service-oriented architecture' division. The mission of this division is to provide an integrated middleware platform to Bull customers. Previously, Brice was involved in J2EE development projects, in telecom and system management areas. Brice develops and designs in both eXo Platform and Bonita open source projects. He lives in southern east of France.

Related Content

Related Resources