It is an important task to understand the jBPM framework structure. We will find out how the framework sources are divided.
Also, this section is very important for those programmers who want to be active community developers, fixing issues and adding new functionalities.
As we have already discussed, jBPM was built and managed with Maven. For this reason, we will find a file called pom.xml inside our working copy of the official JBoss SVN repository that represents the project as a whole. If we run Maven goals to this project, all the framework will be built. As we have seen in the previous section, all the project modules were built. Look at the previous screenshot that informs us that, by default, the modules Core, Identity, Enterprise, Examples, and Simulation are built when we run the clean install goals to the main project. With the install goal too, the generated jar files are copied to our local Maven repository, so we can use it in our applications by only referencing the local Maven repository.
So, the idea here is to see in detail what exactly these modules include. If you open the modules directory that is located inside your working copy, you will see the following sub-directories:
In the next few sections, we will talk about the most important modules that developers need to know in order to feel comfortable with the framework. Take this as a quick, deep introduction to becoming a JBoss jBPM community member.
The most important module of the jBPM framework is the core module. This module contains all the framework functionality. Here we will find the base classes that we will use in our applications. If you open this directory, you will find the pom.xml file that describes this project. The important thing to notice from this file is that it gives us the Maven ArtifactID name and the GroupID. We will use this information to build our applications, because in our applications, we will need to specify the jBPM dependency in order to use the framework classes.
The following image will show us only the first section of the pom.xml file located inside the modules/core/directory. This file will describe the project name, the group id that it belongs to, and also the relationship with its parent (the main project).
If you open this file, you will notice that all the dependencies that this project (jar archive) needs, in order to be built, will be described in the next section. This is also interesting when you want to know exactly which libraries the framework will need to have in the classpath in order to run. You need to remember that Maven will take care of all the transitory dependencies, meaning that in this project file, only the first order dependencies will be described. So, for example, in the dependencies section of the pom.xml file, we will see the Hibernate dependency, but you won't see all the artifacts needed to build and run Hibernate—Maven will take care of all these second order dependencies.
If we build only the Core module project by running the clean install goal (mvn clean install -Dmaven.test.skip), we will get three new JAR archives in the target directory. These archives will be:
- jbpm-jpdl-3.2.6.SP1.jar : The core functionality of the framework—you will need this JAR in all your applications that use jBPM directly. Remember, if you are using Maven, you will need to add this artifact dependency to your project and not this archive.
- jbpm-jpdl-3.2.6.SP1-config.jar : Some XML configurations that the framework needs. This confi guration will be used if you need your process to persist in some relational database.
- jbpm-jpdl-3.2.6.SP1-sources.jar : This JAR will contain all the sources that were used to build the main jar file. This can be helpful to debug our application and see how the core classes interact with each other when our processes are in the execution stage.
You will also find a few directories that were used as temporary directories to build these three JAR files.
This module is in charge of building the different database schemes to run jBPM needed by the different vendors that support Hibernate. If you build this module in the target directory of the project (generated with the clean install of maven goals).
This is only a module created with specific goals to build and create the binary installer, which can be downloaded from jBPM's official page. If you want to get a modified installer of this framework, you will need to build this module. But it is rarely used by development teams.
This module will contain extra features for high-availability environments, including a command service to interact with the framework's APIs, an enterprise messages solution for asynchronous execution, and enterprise-ready timers.
If we build this module, we will get three JAR fies. The main one will be jbpm-enterprise-3.2.6.SP1.jar, the source code and the configuration files that these classes will need.
This is a very interesting module, because it contains some basic examples about how the framework could be used. If you open this module, you will find different packages with JUnit tests that show us how to use the framework APIs to achieve some common situations. These tests are used only for a learning purpose and try to introduce the most common classes that all developers will use. Feel free to play with these tests, modify them, and try to understand what is going on there.
This module contains a proof of concept model to use out of the box when we start creating applications that handle human interactions. The basic idea here is to have a simple model to represent how the process users are structured in our company. As you can imagine, depending on the company structure, we need to be able to adapt this model to our business needs. This is just a basic implementation that you will probably replace for your own customized implementation.
This module includes some use cases for simulating our process executions. The idea here is to know how to obtain reports that help us to improve our process executions, measuring times, and costs for each execution.
User Guide module
This module will let you build the official documentation from scratch. It is not built when the main project is built, just to save us time. You can build all the documentation in three formats—HTML file separated, one single and long HTML file, or PDF.
Knowing this structure will help us to decide where to make changes and where to look for a specific functionality inside the framework sources. Try to go deep inside the src directory for each project to see how the sources are distributed for each project in more detail.
Building real world applications
In this section, we are going to build two example applications—both similar in content and functionalities, but built with different methodologies. The first one will be created using the Eclipse Plugin provided by the jBPM framework. This approach will give us a quick structure that lets us create our first application using jBPM. On the other hand, in the second application that we will build, we will use Maven to describe and manage our project, simulating a more realistic situation where complex applications could be built by mixing different frameworks.
Eclipse Plugin Project/GPD Introduction
In this section, we will build an example application that uses jBPM using the Eclipse plugin, which provides us with the jBPM framework. The idea here is to look at how these kinds of projects are created and what the structure proposed by the plugin. The outcome of this section will be a Process Archive (PAR) file generated by the GPD plugin, which contains a process definition and all the technical details needed to run in an execution environment.
To achieve this, I have set up my workspace in the directory projects inside the software directory. And by having the jBPM plugin installed, you will be able to create new jBPM projects. You can do this by going to File | New | Other and choosing the New type of project called Process Project.
Then you must click on the Next button to assign a new name to this project. I chose FirstProcess for the project name (I know, a very original one!) and click on Next again.
The first time that you create some of these projects, Eclipse will ask you to choose the jBPM Runtime that you want. This means that you can have different runtimes (different versions of jBPM to use with this plugin) installed.
To configure the correct runtime, you will need to locate the directory that the installer creates—it's called jbpm-3.2.6.SP1—then assign a name to this runtime. A common practice here is to put the name with the correct version, this will help us to identify the runtime with which we are configuring our process projects.
Then you should click on the Finish button at the bottom of the window. This will generate our first process project called FirstProcess.
If you have problems creating a new jBPM project, this can be noticed because you'll have a red cross placed in your project name in the Project Explorer window. You could see the current problems in the Problems window (Windows | Show View | Problems). If the problem is that a JAR file called activation.jar is missing, you should do a workaround to fix this situation. To fix this, you should go to your jBPM installation directory—in this case, software/programs/jbpm-3.2.6.SP1 on my desktop, and then go to src/resources/gpd and open a file called version.info.xml and remove the line that makes the reference to the file called activation.jar. Then you should restart the IDE and the problem will disappear. If you create the process project and the sample process definition is not created (under src/main/jpdl), you could use the project created inside this article's code directory called FirstProcess.
GPD Project structure
Once you have created the project, we could take a look at the current structure proposed by the plugin.
This image show us the structure proposed by the GPD plugin. Four source directories will be used to contain different types of resources that our project will use the first one src/main/java will contain all the Java sources that our process uses in order to execute custom Java logic. Here we will put all the classes that will be used to achieve custom behaviors at runtime. When you create a process project, a sample process and some classes are generated. If you take a look inside this directory, you will find a class called MessageActionHandler.java. This class represents a technical detail that the process definition will use in order to execute custom code when the process is being executed.
The src/main/config directory will contain all the resources that will be needed to configure the framework.
In the src/main/jpdl directory, you will find all the defined processes. When you create a sample process with your project, a process called simple is created.
And in src/test/ java, you will find all the tests created to ensure that our processes behave in the right way when they get executed. When the sample process is created, a test for this process is also created. It will give us a quick preview of the APIs that we will use to run our processes.
For the sample process, a test called SimpleProcessTest is created. This test creates a process execution and runs it to test whether the process will behave in the way in which it is supposed to work. Be careful if you modify the process diagram, because this test will fail. Feel free to play with the diagram and with this test to see what happens. Here we will see a quick introduction about what this test does.
This test is automatically created when you create a jBPM process project with a sample process. If you open this class located in the src/test/java directory of the project, you will notice that the behavior of the test is described with comments in the code. Here we will try to see step by step what the test performs and how the test uses the jBPM APIs to interact with the process defined using the Graphical Process Editor.
This test class, like every JUnit tests class will extend the class TestCase (for JUNIT 3.x). It then defines each test inside methods that start with the prefix test*. In this case, the test is called testSimpleProcess(). Feel free to add your own test in other methods that use the prefix test* in the name of the method.
If we see the testSimpleProcess() method, we will see that the first line of code will create an object called processDefinition of the ProcessDefinition type using the processdefinition.xml file.
ProcessDefinition processDefinition = ProcessDefinition.
At this point, we will have our process definition represented as an object. In other words, the same structure that was represented in the XML file, is now represented in the Java Object.
Using the APIs provided by JUnit, we will check that the ProcessDefinition object is correctly created.
assertNotNull("Definition should not be null", processDefinition);
Then we need to create a process execution that will run based on the process definition object. In the jBPM language, this concept of execution is represented with the word instance. So, we must create a new ProcessInstance object that will represent one execution of our defined process.
ProcessInstance instance = new ProcessInstance(processDefinition);
Then the only thing we need to do is interact with the process and tell the process instance to jump from one node to the next using the concept of a signal, which represents an external event. It tells the process that it needs to continue the execution to the next node.
If you take a look at all the assert methods used in the code, they only confirm that the process is in the node in which it is supposed to be.
Another thing that this test checks is that the Actions attached to the process change the value of a process variable. Try to figure out what is happening with that variable and where the process definition changes this variable's value.
The following assert can give you a small clue about it:
assertEquals("Message variable contains message",
getVariable("message"), "Going to the first state!");
To run this test, you just need to right click on the source of this class and go to Run As, and then choose JUnit Test.
You should check whether the test succeeded in the JUnit panel (a green light will be shown if all goes well).
Graphical Process Editor
In this section, we will analyze the most used GPD windows, giving a brief introduction to all the functionality that this plugin provides us. We already see the project structure and the wizard to create new jBPM projects.
The most frequently used window that GPD proposes to us is the Graphical Process Editor, which lets us draw our processes in a very intuitive way.
This editor contains four tabs that gives us different functionalities for different users/roles.
The Diagram tab
This tab will let us draw our business process. Basically, we only need to drag-and-drop the basic nodes proposed in the palette and then join them with transitions. This is a very useful tool for business analysts who want to express business processes in a very intuitive way with help from a developer. This will improve the way that business analysts communicate with developers when they need to modify or create a new business process.
The Deployment tab
This tab is exclusively for developers who know and understand the environment in which the process will be deployed. This tab will help us to create and deploy process archives. These special archives will contain all the information and technical details that the process will need in order to run. In order to get our process archive ready for deployment, first we need to select the resources and the Java classes that will be included in this process archive, and then check the Save Process Archive locally option. Now, we provide a correct path to store it and then click on Save Without Deploying. Feel free to inspect the process archive generated—it's just a ZIP file with the extension changed to .par with all the classes compiled and ready to run.
The Source tab
This tab will show us all the jPDL XML generated by the Diagram tab and will keep all the changes that can be made in both tabs in sync. Try not to change the graph structure from this view, because sometimes, you could break the parser that is checking the changes in this view, all the time, to sync it with the diagram view. For that situation, when you know what you are doing, I don't recommend the use of the plugin—just create a new XML file and edit it without opening the file as a process. This will allow us to be IDE agnostic and also know exactly what we are doing, and not depend on any tool to know what is happening with our processes.
This panel is used in conjunction with the Graphical Process Editor window, as it gives us all the information about all the elements displayed in our processes definitions. If you can't see this panel, you should go to Window | Show View | Properties.
This panel will help you to add extra information to your diagrammed process and customize each element inside it.
This panel will show different sections and information for each element typed inside our process. If you look at the following screenshot, you will see that it represents all the properties allowed to be set in the process definition element. In other words, these properties are applied to the process definition and not to any particular element defined inside the process. The selected element is shown at the top of the panel with the element type and icon. In this case, the Process Definition element is selected.
To see the global process definition information, you should click on the white background of the GPD designer window that has no elements selected.
Also, you should notice the additional tabs for each element. In this case, we could add Global Exceptions handlers, Global Tasks definitions, Global Actions, Swimlanes and Global Events to our process.
If you select another element of the process, you will notice that this panel will change and show another type of information to be filled in and other tabs for selection, depending on the selected element type. The following image shows a selected state node in our process. As we have discussed earlier, it is important to notice that the tabs allowed for the state node will let us add another type of information and all of this information will be related only with the state node.
As we mentioned before, the outcome of this section is only a PAR generated with the Deployment tab of the GPD Designer window. Feel free to look at and modify the sample process provided by the plugin and regenerate the PAR to see what has changed.
The idea of this section is to build an application using Maven to describe the project structure. Meaning that we will need to write the pom.xml file from scratch. For this example, we will use the same code that tested our process defined with the GPD plugin. In this case, to create a console application that uses the jBPM API.
The outcome of this section will be a template for a project that could be used to create any project that you want, which will contain the jBPM library to manage and use business processes.
The only thing that you will need for this is a text editor and a console to create the directory structure. The directory structure is needed by Maven to know where our project sources are located in order to build them.
If you prefer, you could also use the Eclipse Q4E Maven plugin and Maven archetypes to create this structure. In both situations, the plugin or by hand, we need to have the following structure in order to have a standard project structure:
Inside both src/main/java and src/test/java, you could start adding Java classes structured in packages like you normally do in all of your projects.
The most common goals that you will use to build and manage your projects will be:
- clean: This goal will erase all the already compiled code located in the target directory.
- package: It will build and package our project following the declared packaging structure in the pom.xml file. The resulting jar file could be located in the target directory if the build succeeds. If the compilation of just one class can't be done, all the goals will fail.
- test: This goal will run all the tests that are inside our project (located in the src/main/test directory). If just one of these test fails, all the test goals fail. If this goal is called from another goal, for example the install goal, when just one test fails, the install goal will also fail.
- install: This will run the package goal followed by the test goal, and if both succeed, the outcome located in the target directory will be copied to the local Maven 2 repository.
It is very helpful to know that you can chain these goals together in order to run them together, for example mvn clean install. This will clean your target directory and then package and test the compiled code. If all these goals succeed, the outcome will be copied to the local Maven2 repository.
Sometimes, in the development stage, you know that some tests are failing, but want to compile and install your project for testing. In these situations, you could use the following flag to skip the tests in the install goal: mvn clean install -Dmaven. test.skip.
The main points to notice in the pom.xml file will be the project description with the artifact ID, the group ID properties, and of course the packaging tag with the jar value that specifies the outcome when we build our project.
With the Q4E plugin from Maven 2 in Eclipse, we could create this project by following the next few steps described further in the section.
If you have installed the Q4E plugin in your Eclipse IDE, you should go to the New Project wizard and then choose Maven 2 Project | Maven 2 Project Creation Wizard, then click on Next and enter a new name for the project. I chose FirstMavenProcess, because it is the name of the root directory shown in the previous image. Inside this directory, all the standard directory structure needed by Maven will be created. Once you enter the name and click on Next, the following screen will appear:
In this screen, we will choose the Maven Archetype that we want for our project. These archetypes specify what kind of structure Maven will use to create our project. This maven-archetype-quickstart represents the most basic structure for a JAR file.
If you browse the list, you will also find the archetype called maven-archetypewebapp that is used for creating the standard structure for web-based applications.
At this point, you can click on Finish and the corresponding project structure, and the pom.xml file will be created.
If we create this file manually, or using the Q4E plugin, it should look like the following image:
Now, for telling Maven that this project will use jBPM, we only need to add the reference to the jBPM artifact in the dependency section:
This will ensure that Maven takes care of the jBPM artifact and all of their required dependencies.
You can now open the project called FirstMavenProcess located in the code directory. However, because Eclipse needs some special files to recognize that this directory is a Maven project, you will need to open a console, go to the directory called FirstMavenProcess, check the pom.xml file that is inside the directory, and then run the mvn eclipse:eclipse maven goal, which will generate all the Eclipse needed files (project.xml and other files).
Then you will be able to open the project inside Eclipse. Take a look at the added classes and the App.java class that contains a similar code for the tests generated by the GPD plugin.
The last thing that you need to understand here is how to package your project source code into a binary JAR file for running and distributing your application.
You can do that by running the mvn package goal from the console—this will generate a JAR file called FirstMavenProcess-1.0-SNAPSHOT.jar.
If you run the App.java class (with Run As... | Java Application), you will see the following output on the console:
Process Instance Created
We are in the 'start' Node
We Signal the process instance to continue to the next Node
At this point the variable message value is = Going to the first state!
Now we are in the 'first' Node
We Signal the process instance to continue to the next Node
Now we are in the 'end' Node ending the process
Now the variable message value is = About to finish!
If you see some warnings before that output, don't worry about them.
In this article, we've learnt about all the tooling that we will use everyday in a jBPM project implementation. At the end of this article, we saw how to create two basic applications that include and use the jBPM framework, just to see how all the pieces fit together. With the use of Maven, we gained some important features including dependency management, the use of standard project structures, and IDE independence.
Also, the Graphic Process Designer was introduced. This jBPM plugin for the Eclipse IDE will let us draw our processes in a very intuitive way. Just dragging and dropping our process activities and then joining them with connections will result in our process definitions. This plugin also allows us to write all the technical details that our process will need in order to run in a runtime environment.