2014/02/06

jBPM 6 - store your process variables anywhere

Most of jBPM users is aware of how jBPM stores process variable but let's recap it here again just for completeness.

NOTE: this article covers jBPM that uses persistence as without persistence process variables are kept in memory only.

 jBPM puts single requirement on the objects that are used as process variables:
  • object must be serializable (simply must implement java.io.Serializable interface)
with that jBPM engine is capable to store all process variables as part of process instance using marshaling mechanism that is backed by Google Protocol Buffers. That means actual instances are marshaled into bytes and stored in data base. This is not always desired especially in case of objects that are actually not owned by the process instance. For example:
  • JPA entities of another system
  • documents stored in document/content management system 
  • etc
Luckily, jBPM has a solution to that as well called pluggable Variable Persistence Strategy. Out of the box jBPM provides two strategies:
  • serialization based, mentioned above that actually works on all object types as long as they are serializable (org.drools.core.marshalling.impl.SerializablePlaceholderResolverStrategy)
  • JPA based that works on objects that are entities (org.drools.persistence.jpa.marshaller.JPAPlaceholderResolverStrategy)
Let's spend some time on the JPA based strategy as it might become rather useful in many cases where jBPM is used in embedded mode. Consider following scenario where our business process uses entities as process variables. The same entities might be altered from outside of the process and we would like to keep them up to date within the process as well. To do so, we need to use JPA based strategy for variable persistence that is capable of storing entities in data base and then retrieving them back.
To configure variable persistence strategy you need to place it into the environment that is the used when creating knowledge sessions. Note that the order of the strategies is important as they will be evaluated which one will be used in the order they are given. best practice is to always set the serialization based strategy to be the last one. 
An example how you can use it with RuntimeManager:


// create entity manager factory
EntityManagerFactory emf = Persistence.createEntityManagerFactory("org.jbpm.sample");

RuntimeEnvironment environment = 
     RuntimeEnvironmentBuilder.Factory.get().newDefaultBuilder()
     .entityManagerFactory(emf) 
     .addEnvironmentEntry(EnvironmentName.OBJECT_MARSHALLING_STRATEGIES, 
          new ObjectMarshallingStrategy[]{
// set the entity manager factory for jpa strategy so it 
// know how to store and read entities     
               new JPAPlaceholderResolverStrategy(emf),
// set the serialization based strategy as last one to
// deal with non entities classes
               new SerializablePlaceholderResolverStrategy( 
                          ClassObjectMarshallingStrategyAcceptor.DEFAULT  )
         })  
     .addAsset(ResourceFactory.newClassPathResource("cmis-store.bpmn"), 
               ResourceType.BPMN2)
     .get();
// create the runtime manager and start using entities as part of your process  RuntimeManager manager = 
     RuntimeManagerFactory.Factory.get().newSingletonRuntimeManager(environment);

Once we know how to configure it, let's take some time to understand how it actually works. First of all, every process variable on the time when it's going to be persisted will be evaluated on the strategy and it's up to the strategy to accept or reject given variable, if accepted only that strategy will be used to persist the variable, if rejected other strategies will be consulted.

Note: make sure that you add your entity classes into persistence.xml that will be used by the jpa strategy

JPA will accept only classes that declares a field with @Id annotation (javax.persistence.Id) that allows us to ensure we will have an unique id to be used when retrieving the variable.
Serialization based one simply accepts all variables by default and thus it should be the last strategy inline. Although this default behavior can be altered by providing other acceptor implementation.

Once the strategy accepts the variable it performs marshaling operation to store the variable and unmarshaling to retrieve the variable from the back end store (of the type it supports).

In case of JPA, marshaling will check if entity is already stored entity - has id set - and:

  • if not, it will persist the entity using entity manager factory that was assigned to it
  • if yes, it will merge it with the persistence context to make sure up to date information is stored
when unmarshaling it will use the unique id of the entity to load it from the database and provide as process variable. It's that simple :)

With that, we quickly covered the default (serialization based) strategy and JPA based strategy. But the title of this article says we can store variables anywhere, so how's that possible?
It's possible because of the nature of variable persistence strategies - they are pluggable. We can create our own and simply add it to the environment and process variables that meets the acceptance criteria of the strategy will be persisted by that given strategy. To not leave you with empty hands let's look at another implementation I created for purpose of this article (although when working on it I believe it will become more than just example for this article).

Implementing variable persistence strategy is actually very simple, it's a matter of implementing single interface: org.kie.api.marshalling.ObjectMarshallingStrategy

public interface ObjectMarshallingStrategy {
    
    public boolean accept(Object object);

    public void write(ObjectOutputStream os,
                      Object object) throws IOException;
    
    public Object read(ObjectInputStream os) throws IOException, ClassNotFoundException;
    

    public byte[] marshal( Context context,
                           ObjectOutputStream os,
                           Object object ) throws IOException;
    
    public Object unmarshal( Context context,
                             ObjectInputStream is,
                             byte[] object,
                             ClassLoader classloader ) throws IOException, ClassNotFoundException;

    public Context createContext();
}

the most important methods for us are:

  • accept - decides if this strategy will be responsible for persistence of given object
  • marshal - performs operation to store process variable
  • unmarshal - performs operation to retrieve process variable
the other remaining are for backward compatibility reasons with old marshaling framework prior to protobuf, so it's not mandatory to be implemented but it's worth to put the logic there too as most likely it will be same as for marshal (write) and unmarshal (read).

So the mentioned example implementation is for storing and retrieving process variables as document from Content/Document management systems that support access to the repository using CMIS. I used Apache Chemistry as the integration component that can easily talk to CMIS enabled systems like for example Alfresco.


So first bit of requirements:

  • process variables must be of certain type to be stored in the content repository
  • documents (process variables stored in cms) can be:
    • created
    • updated (with versioning)
    • read
  • process variables must be kept up to date
so all these sounds simple and of course that's the point to keep it simple at this point. CMS can be used for much more but we wanted to get started and then enhance it if needed. So the implementation of strategy org.jbpm.integration.cmis.impl.OpenCMISPlaceholderResolverStrategy supports following:
  • when marshaling
    • create new documents if it does not have object id assigned yet
    • update document if it has already object id assigned
      • by overriding existing content
      • by creating new major version of the document 
      • by creating new minor version of the document
  • when unmarshaling
    • load the content of the document based on given object id
So you can actually use this strategy for:
  • creating new documents from the process based on custom content
  • update existing documents with custom content
  • load existing documents into process variable based on object id only
These are very high level details but let's look at the actual code that does that "magic", let's start with marshal logic - note that is bit simplified for readability here and complete code can be found in github.


public byte[] marshal(Context context, ObjectOutputStream os, Object object) throws IOException {
 Document document = (Document) object;
 // connect to repository
 Session session = getRepositorySession(user, password, url, repository);
 try {
  if (document.getDocumentContent() != null) {
   // no object id yet, let's create the document
   if (document.getObjectId() == null) {
    Folder parent = ... // find folder by path
    if (parent == null) {
     parent = .. // create folder
    }
    // now we are ready to create the document in CMS
   } else {
      // object id exists so time to update     
   }
  }
 // now nee need to store some info as part of the process instance
 // so we can later on look up, in this case is the object id and class
 // that we use as process variable so we can recreate the instance on read
     ByteArrayOutputStream buff = new ByteArrayOutputStream();
     ObjectOutputStream oos = new ObjectOutputStream( buff );
     oos.writeUTF(document.getObjectId());
     oos.writeUTF(object.getClass().getCanonicalName());
     oos.close();
     return buff.toByteArray();
 } finally {
  // let's clear the session in the end
  session.clear();
 }
}

so as you can see, it first deals with the actual storage (in this case CMIS based repository) and then save some small details to be able to recreate the actual object instance on reading. It stores objectId and fully qualified class name of the process variable. And that's it. Process variable of type Document will be stored inside content repository.

Then let's look at the unmarshal method:


public Object unmarshal(Context context, ObjectInputStream ois, byte[] object, ClassLoader classloader) throws IOException, ClassNotFoundException {
 DroolsObjectInputStream is = new DroolsObjectInputStream( new ByteArrayInputStream( object ), classloader );
 // first we read out the object id and class name we stored during marshaling
 String objectId = is.readUTF();
 String canonicalName = is.readUTF();
 // connect to repository
 Session session = getRepositorySession(user, password, url, repository);
 try {
  // get the document from repository and create new instance ot the variable class
  CmisObject doc = .....
  Document document = (Document) Class.forName(canonicalName).newInstance();
  // populate process variable with meta data and content
  document.setObjectId(objectId);
  document.setDocumentName(doc.getName());   
  document.setFolderName(getFolderName(doc.getParents()));
  document.setFolderPath(getPathAsString(doc.getPaths()));
  if (doc.getContentStream() != null) {
   ContentStream stream = doc.getContentStream();
   document.setDocumentContent(IOUtils.toByteArray(stream.getStream()));
   document.setUpdated(false);
   document.setDocumentType(stream.getMimeType());
  }
  return document;
 } catch(Exception e) {
  throw new RuntimeException("Cannot read document from CMIS", e);
 } finally {
  // do some clean up...
  is.close();
  session.clear();
 }
}

nothing more that the logic to get ids and class name so the instance can be recreated and load the document from cms repository and we're done :)

Last but not least, the accept method.


public boolean accept(Object object) {
    if (object instanceof Document) {
 return true;
    }
    return false;
}

and that is all that is needed to actually implement your own variable persistence strategy. The only thing left is to register the strategy on the environment so it will be evaluated when storing/retrieving variables. It's done the same way as described for JPA based on.

Complete source code with some tests showing complete usage case from process can be found here. Enjoy and feel free to provide feedback, maybe it's worth to start producing repository of such strategies so we can have rather rich set of strategies to be used...

2014/02/01

how to deploy processes in jBPM 6?

After release of 6.0 of jBPM, there were number of questions coming from community about how processes can be deployed into the new and shiny jbpm console?

So let's start with short recap on how the deployment model look like in jBPM 6. In version 5.x processes were stored in so called packages produced by Guvnor and next downloaded by jbpm console for execution using KnowledgeAgent. Alternatively one could drop their process files (bpmn2 files) into a predefined directory that was scanned on the jbpm console start. That was it.

That enforces users to always use Guvnor when dynamic deployment was needed. Although there is nothing wrong with it, actually that was recommended approach but not everyone was happy with that setup.

Version 6, on the other hand moves away from proprietary packages in favor of, well known and mature, Apache Maven based packaging - known as knowledge archives - kjar. What does that mean? First of all, processes, rules etc (aka business assets) are now part of a simple jar file built and managed by Maven. Along the business assets, java classes and other file types are stored in the jar file too. Moreover, as any other maven artifact, kjar can have defined dependencies on other artifacts including other kjars.
What makes the kjar special when compared with regular jars? It is a single descriptor file kept inside META-INF directory of the kjar - kmodule.xml. That descriptor allows to define:

  • knowledge bases and their properties
  • knowledge sessions and their properties
  • work item handlers
  • event listeners
By default, this descriptor is empty (just kmodule root element) and is considered as marker file. Whenever a runtime component (such as jbpm console) is about to process kjar it looks up kmodule.xml to build its runtime representation. See documentation for more details about kmodule.xml and kjars.

Alright, now we know bit more about what is actually placed on runtime environment - kjar. So how we can deploy kjar into running jbpm console? There are several ways:

Design and build your kjar inside jbpm console

The easiest way is to actually use jbpm console to completely build the kjar. For that purpose there is entire perspective available - Authoring perspective - that consist of quite big set of editors tailored for various asset types.

First, you have to have repository created where your projects (after they are built they become kjars) will be stored. When running the demo setup of jbpm console (installed by jbpm installer), you will have two repositories already available - jbpm-playground and uf-playground. You can use any of these or create new repository.
Once you have repository available, create new item - a project - you need to specify GAV (GroupId, ArtifactId, Version) to name your project.
Next you create business assets in it, like business processes, rules, data model, forms, etc. And now we are at the stage where we should build and deploy our project into runtime. Nothing simpler than that - just press "Build & Deploy" button and you're ready to rock!

Is that really that simple?! In most of the cases, yes, it is really that simple. But you need to be aware of several rules (convention over configuration) that drive the build and deploy. First rule is that everything needs to be properly designed - processes, rules, etc - that is the build phase that catches any compilation or validation errors and provides feedback to the user via Problems Panel.
Assuming, all assets are built successfully, the deploy phase comes into the picture. Deploy phase is actually a two step process:
  • Maven phase - 
    • it installs build project (now it's kjar already) into Maven local repository (usually ~/.m2/repository but it can be configured with standard maven way - settings.xml)
    • deploys built project into jbpm console embedded Maven repository - it's a remote repository accessible over http and can be declared in pom.xml, settings.xml as any other maven repository
  • Runtime phase
    • once Maven phase is completed successfully, jbpm console will attempt to deploy the kjar into runtime environment for execution. Here are few requirements to make this happen:
      • kmodule.xml needs to be empty - which it is by default unless you edited it via Project Editor
      • kmodule.xml must have at least one knowledge base and stateful knowledge session defined and marked as default
When both phases are successfully completed, your kjar is deployed to runtime environment and ready for execution. Simply go to Process Management --> Process Definitions to examine what's there and start executing your just deployed processes.

So that's first and the easiest way to get started with deployments in jBPM 6.

Build project in IDE and push to console for build and deploy

Another approach would be when you prefer to do the heavy work in your IDE like Eclipse (since the modeling capabilities - bpmn2 modeler - is only available in Eclipse).  So you do pretty much similar steps, although no need to create repository here but clone an existing one from jbpm console instead.  So you first start with cloning of an existing repository. 

git clone ssh://{jbpmconsole-host}:{port}/{repository-name}

Then create Maven project - you can actually do that with jBPM Project wizard in eclipse, that creates simple Maven project with sample business process and executable class in it to get you started much faster. 

Note: make sure you place the project in the cloned repository structure so it can be later on pushed back.

It declares dependencies to jbpm-test module to be able to execute the sample process.
Once you have a mavenized project, you're ready to start working on your business assets, data model and more. 
When done, you're ready to push your project into jbpm console so it can be built and deployed to runtime environment. To do so, you need to use any GIT tool that allows you to pull and push changes from your working copy into the master repository. To add all files in your working copy into commit index:

git add -A

then examine if you haven't added too much like the target folder, if so create or edit .gitignore file to exclude unneeded files. And commit:

git commit -m "my first jbpm project"

once committed, push it to origin

git push origin master

now go into jbpm console Authoring perspective, and you should see you project in the repository, it's ready to be build and deployed. Just follow same step from the first approach to build and deploy it. 
That was second approach to deploying business assets into jbpm console version 6. Somehow in between developers and business users. Might also be seen as collaboration way - where initially business users create high level processes, rules etc and then developers step in and add implementation details and some "glue code" to make it fully executable.

Build and deploy to Maven from IDE

This one focuses completely on developers and allows to actually do the work without being too much aware of jbpm console. So here developers build regular maven projects that include business assets, java classes, forms and then add the kmodule.xml to make the jar become kjar. Everything is done in IDE of developer choice. Same goes for version control system, it does not have to be git any more, in this case. That is because, jbpm console won't be used as source management tool for these projects but it will be used only for pure execution capabilities.

Once you're done with development, you simply build the project with maven (mvm clean install). That makes it directly available for any other components that would like to use it on your local machine. So if you're running jbpm console on your machine you can directly skip to section deployment (three paragraphs below ;))

When jbpm console is running on remote host, you have two ways to make it aware of your artifacts built externally:
  • deploy (using maven) your projects into jbpm console Maven repository - as this is like any other repository you can use maven deploy goal after you have defined that repository either in your pom.xml or settings.xml
  • make jbpm console maven installation aware of any external maven repositories it should consider while deploying kjars
The first one, deploy to maven repository, does not have anything special, it's as simple as defining the repository in settings.xml so it can be successfully contacted and the artifact can be stored when running mvm clean install deploy.
Then the second approach is again standard maven way. On the machine (and user) that jbpm console is running, you need to add your main maven repository into settings.xml so whenever jbpm console will attempt to deploy the kjar it will look up for it in your maven repository.

With all these steps, jbpm console is now capable of finding the kjars that are outside of it's local maven repository so it can download them when needed. You can now go to jbpm console Deploy --> Deployments perspective where you can add new deployment units manually.
It's as simple as providing GAV of the project you want to deploy and optionally knowledge base and knowledge session names if you defined more than what is there by default.
In addition to that, you can select runtime strategy that fits your requirements for that given kjar - chose one from Singleton, Per Request or Per Process instance.

That concludes deployment options available in jBPM version 6. It promotes well known standards defined by maven and allow various ways of integrating with the jbpm console functionality. You, as a user, are in the control how you work with the tooling where you can leverage it's full power to do everything over the web, integrate with GIT server, to do everything externally and use it only for execution.

Hope that puts some light on the way you can use jBPM 6 out of the box and empowers your day to day work. As usual, ending with the same sentence: all comments and ideas are more than welcome.






2014/01/20

jBPM 6 with spring

As some of you might noticed jBPM got quite few improvements for version 6.0, to just name few:

  • RuntimeManager
  • enhanced timer service
  • new deployment model - based on kjar and maven
  • brand new tooling 
  • see release notes for more
there is (as always) still room for improvements. After 6.0 went out, we started to look at how we could ease the usage of jBPM in Spring based applications on top of the new API. Lots of the API is now based on the concept of fluent API which is not really Spring friendly.
Before we dive into details of the API and how it can be used in Spring let's look at possible usage scenarios that users might be interested in:

  • Self managed process engine
This is the standard (and the simplest) way to get up and running with jBPM in your application. You only configure it once and run as part of the application. With the RuntimeManager usage, both process engine and task service will be managed in complete synchronization, meaning there is no need from end user to deal with "plumbing" code to make these two work together. 
  • Shared task service
There could be a need in certain situations, that a single instance of a TaskService is used. This approach give more flexibility in configuring the task service instance as it's not behind RuntimeManager. Once configured it's then used by the RuntimeManager when requested. RuntimeManager in such situation will not create new instances of task service as it's done with self managed process engine approach.

To provide spring based way of setting up jBPM, few factory beans where added:

org.kie.spring.factorybeans.RuntimeEnvironmentFactoryBean


Factory responsible for producing instances of RuntimeEnvironment that are consumed by RuntimeManager upon creation. It allows to create following types of RuntimeEnvironment (that mainly means what is configured by default):
  • DEFAULT - default (most common) configuration for RuntimeManager
  • EMPTY - completely empty environment to be manually populated
  • DEFAULT_IN_MEMORY - same as DEFAULT but without persistence of the runtime engine
  • DEFAULT_KJAR - same as DEFAULT but knowledge asset are taken from KJAR identified by releaseid or GAV
  • DEFAULT_KJAR_CL - build directly from classpath that consists kmodule.xml descriptor
Mandatory properties depends on the selected type but knowledge information must be given for all types. That means that one of the following must be provided:
  • knowledgeBase
  • assets
  • releaseId
  • groupId, artifactId, version
Next for DEFAULT, DEFAULT_KJAR, DEFAULT_KJAR_CL persistence needs to be configured:
  • entity manager factory
  • transaction manager
Transaction Manager must be Spring transaction manager as based on its presence entire persistence and transaction support is configured.  Optionally EntityManager can be provided to be used instead of always creating new one from EntityManagerFactory - e.g. when using shared entity manager from Spring. All other properties are optional and are meant to override the default given by type of the environment selected.

org.kie.spring.factorybeans.RuntimeManagerFactoryBean

FactoryBean responsible for creation of RuntimeManager instances of given type based on provided runtimeEnvironment. Supported types:
  • SINGLETON
  • PER_REQUEST
  • PER_PROCESS_INSTANCE
where default is SINGLETON when no type is specified.  Every runtime manager must be uniquely identified thus identifier is a mandatory property. All instances created by this factory are cached to be able to properly dispose them using destroy method (close()).

org.kie.spring.factorybeans.TaskServiceFactoryBean

Creates instance of TaskService based on given properties. Following are mandatory properties that must be provided:
  • entity manager factory
  • transaction manager
Transaction Manager must be Spring transaction manager as based on its presence entire persistence and transaction support is configured. Optionally EntityManager can be provided to be used instead of always creating new one from EntityManagerFactory - e.g. when using shared entity manager from Spring. In addition to above there are optional properties that can be set on task service instance:
  • userGroupCallback - implementation of UserGroupCallback to be used, defaults to MVELUserGroupCallbackImpl
  • userInfo - implementation of UserInfo to be used, defaults to DefaultUserInfo
  • listener - list of TaskLifeCycleEventListener that will be notified upon various operations on tasks
This factory creates single instance of task service only as it's intended to be shared across all other beans in the system.


Now we know what components we are going to use, so it's time to look at how we could actually configure our spring application to take advantage on jBPM version 6. We start with the simple self managed approach where we configure single runtime manager with inline resources (processes) added.

1. First we setup entity manager factory and transaction manager:

  <bean id="jbpmEMF" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceUnitName" value="org.jbpm.persistence.spring.jta"/>
  </bean>

  <bean id="btmConfig" factory-method="getConfiguration" class="bitronix.tm.TransactionManagerServices">
  </bean>

  <bean id="BitronixTransactionManager" factory-method="getTransactionManager"
        class="bitronix.tm.TransactionManagerServices" depends-on="btmConfig" destroy-method="shutdown" />
  
  <bean id="jbpmTxManager" class="org.springframework.transaction.jta.JtaTransactionManager">
    <property name="transactionManager" ref="BitronixTransactionManager" />
    <property name="userTransaction" ref="BitronixTransactionManager" />
  </bean>
with this we have ready persistence configuration that gives us:
  • JTA transaction manager (backed by bitronix - for unit tests or servlet containers)
  • entity manager factory for persistence unit named org.jbpm.persistence.spring.jta
2. Next we configure resource that we are going to use - business process

<bean id="process" factory-method="newClassPathResource" class="org.kie.internal.io.ResourceFactory">
  <constructor-arg>
    <value>jbpm/processes/sample.bpmn</value>
  </constructor-arg>
</bean>
this configures single process that will be available for execution - sample.bpmn that will be taken from class path. This is the simplest way to get your processes included when trying out jbpm.

3. Then we configure RuntimeEnvironment with our infrastructure (entity manager, transaction manager, resources)


<bean id="runtimeEnvironment" class="org.kie.spring.factorybeans.RuntimeEnvironmentFactoryBean">
  <property name="type" value="DEFAULT"/>
  <property name="entityManagerFactory" ref="jbpmEMF"/>
  <property name="transactionManager" ref="jbpmTxManager"/>
  <property name="assets">
    <map>
      <entry key-ref="process"><util:constant static-field="org.kie.api.io.ResourceType.BPMN2"/></entry>
    </map>
  </property>
</bean>
that gives us default runtime environment ready to be used to create instance of a RuntimeManager.

4. And finally we create RuntimeManager with the environment we just setup

<bean id="runtimeManager" class="org.kie.spring.factorybeans.RuntimeManagerFactoryBean" destroy-method="close">
  <property name="identifier" value="spring-rm"/>
  <property name="runtimeEnvironment" ref="runtimeEnvironment"/>
</bean>

with just four steps you are ready to execute your processes with Spring and jBPM 6, utilizing EntityManagerFactory and JTA transaction manager.

As an optional step, especially useful when testing you can create AuditLogService to get history information of your process executions.


<bean id="logService" class="org.jbpm.process.audit.JPAAuditLogService">
  <constructor-arg>
    <ref bean="jbpmEMF"/>
  </constructor-arg>
</bean>

Complete spring configuration file can be found here.

This is just one configuration setup that jBPM 6 supports - JTA transaction manager and EntityManagerFactory, others are:
  • JTA and SharedEntityManager
  • Local Persistence Unit and EntityManagerFactory
  • Local Persistence Unit and SharedEntityManager
What is important to note here is that there is no need to setup TaskService at all, some part of it like user group callback, can be configured via RuntimeEnvironment but the whole setup is done automatically by RuntimeManager. No need to worry about that.

Although if you need more control over TaskService instance you can set it up yourself and let RuntimeManager use it instead of creating its own instances.

To do so, you start the same as for self managed process engine case, follow step 1 and 2. Next we configure task service

<bean id="taskService" class="org.kie.spring.factorybeans.TaskServiceFactoryBean" destroy-method="close">
    <property name="entityManagerFactory" ref="jbpmEMF"/>
    <property name="transactionManager" ref="jbpmTxManager"/>
    <property name="listeners">
      <list>
        <bean class="org.jbpm.services.task.audit.JPATaskLifeCycleEventListener" />
      </list>
    </property>
  </bean>
with that we add an extra task life cycle listener to save all task operations as log entires.

Then, step 3 needs to be slightly enhanced to set task service instance in the runtime environment so RuntimeManager can make use of it


<bean id="runtimeEnvironment" class="org.kie.spring.factorybeans.RuntimeEnvironmentFactoryBean">
  <property name="type" value="DEFAULT"/>
  <property name="entityManagerFactory" ref="jbpmEMF"/>
  <property name="transactionManager" ref="jbpmTxManager"/>
  <property name="assets">
    <map>
      <entry key-ref="process"><util:constant static-field="org.kie.api.io.ResourceType.BPMN2"/></entry>
    </map>
   </property>
   <property name="taskService" ref="taskService"/>
 </bean>
that will disable task service creation by RuntimeManager and always use this single shared instance.
Step 4 (creating RuntimeManager) is exactly the same.

Look at the example configuration files and test cases for more details on how they are utilized.

Please also note that factory beans for spring integration are currently scheduled to be released with 6.1.0 version of jBPM but I would like to encourage you to give it a try before so in case something is not working or missing we will have time to fix it and let it out with 6.1.0.Final. So all hands on board and let's spring it :)

2013/11/22

jBPM 6 first steps

This post is about to give a very quick introduction to how users can take their first steps in jBPM 6. Using completely web tooling to build up:

  • processes
  • rules
  • process and task forms
  • data model
With just three simple examples you will learn how easy and quickly you can start with BPM. So let's start.

The simples process

First process is illustrating how you move around in KIE workbench web application. Where to:
  • create repository
  • create project
  • configure Knowledge Base, KnowledgeSession
  • create process
  • build and deploy
  • execute process and work with user task



Custom data and forms

Next let's explore more and start with bit advanced features like:

  • building custom data model that will be used as process variable
  • make use of process variables in user task
  • define custom forms for process and tasks
  • edit and adjust your process and task forms


Make use of business rules and decisions in your process

At the end let's make the process be more efficient by applying business rules in the process and then use gateways as deception points. This example introduces:

  • use of business rule task
  • define business rules with Drools
  • use XOR gateway to split between different paths in the process


Important to note that business rule task can automatically insert and retract process variables using data input and output of business rule task. When defining them make sure that both data input and output are named exactly the same to allow engine to properly retract the facts on business rule task completion.

That would be all for the first steps with jBPM 6. Stay tuned for more examples and videos!

As usual comments more than welcome.


2013/10/07

jBPM 6 workshops

I would like to inform that there will be some workshops regarding upcoming jBPM version 6 where you can gather some insight into what's in it for you.

There are currently two workshops scheduled:

  • 12 of October in Warsaw, Poland
  • 23-24 of October in London, UK

Workshop in Poland will be carried as part of Warsjava 2013 conference where besides "Introduction to jBPM 6" a lot more can be found. Unfortunately the conference is by default in Polish but I guess when there will be any non polish speaking attendees there won't be any issues to take it in English. I'll be giving the presentation and workshop for jBPM 6 at this year's Warsjava.

Workshops in London will be taken obviously in English and there will be lot of possibilities to learn a lot about the development in the projects. Presented by Mauricio "Salaboy" Salatino and Michael Anstis so an event you can't miss.

Please take a look at the content and register as places are limited.

2013/10/01

jBPM empowers Magnolia CMS

I am glad to inform that Magnolia CMS uses jBPM 5 as their default work flow engine in version 5. Just two weeks ago I had a pleasure to talk about jBPM (both v5 and v6) at Magnolia conference in Basel, Switzerland. This was a great event that I recommend everyone that is interested in CMS.

Together with Espen from Magnolia team, we made a really nice presentation about both jBPM and Magnolia Workflow that utilizes jBPM.

Here you can find the presentation and as soon as recording will be available I'll link it here as well.

Stay tuned for more updates and information about jBPM :)

2013/09/02

jBPM6 samples with RuntimeManager

jBPM6 introduces new module - jbpm-runtime-manager - that aims at significantly simplify management of:

  • KnowledgeBase (KieBase)
  • KnowledgeSession (KieSession)
Moreover it allows to use predefined strategies for handling knowledge sessions and its relation to process instance. By default jBPM6 comes with three strategies:
  • Singleton - single knowledge session that will execute all process instances
  • Per Request - every request (which is in fact call to getRuntimeEngine) will get new knowledge session
  • Per Process Instance - every process instance will have its dedicated knowledge session for the entire life time
To make use of the strategy it's enough to create proper type of RuntimeManager. jBPM6 allows to obtain instance of the RuntimeManager in various ways, this article will provide hands on information on how it can be achieved. 
With jBPM6 a whole new way of building application has been provided - Context and Dependency Injection is now available for users to build application and bring the power of jBPM to next level. Obviously CDI is not the only way to make use of jBPM - the regular API based approach is still available and fully functional.

CDI integration

jBPM6 tooling (like jbpm console or kie-wb) is built on CDI and thanks to that set of services has been provided to ease the development for custom applications that are based on CDI. These services are bundled as part of jbpm-kie-services and provides compact solution to most of the required operations to put BPM into your application:
  • deployment service - deploys and undeploys units (kjars) into the process engine
  • runtime service - gives access to state of the process engine, like retrieve process definitions, process instances, history log, etc
  • bpmn2 data service - gives access to details of the process definition taken from BPMN2 xml
  • form provider service - gives access to forms for processes and tasks
So whenever custom application is built with CDI these services are recommended way to go to get most of the power of CDI and jBPM. Moreover it's the safest way too as it is used in jBPM tooling so it got fair amount of testing to secure it does what is expected.

Using jbpm-kie-services is not a mandatory to be able to use jBPM6 in CDI environment but it does have some advantages:
- allow to maintain multiple RuntimeManagers within single execution environment
- allow independent deploy and undeploy of units (kjar) without server/application restart
- allow to select different strategies for different units

See jbpm-sample-cdi-services project for details.

while these are all appealing add-ons they are not always needed, especially if application requires only single RuntimeManager instance to be included in the application. If that's the case we can let CDI container to create the RuntimeManager instance for us. That is considered second approach to CDI integration where only single instance of RuntimeManager is active and it's managed completely by the CDI container. Application needs to provide environment that RuntimeManager will be based on. 

See jbpm-sample-cdi project for details.

API approach

Last but not least is the regular API based approach to jBPM6 and RuntimeManager. It expects to be built by the application and in fact provides all configuration options. Moreover this is the simplest way to extend the functionality of RuntimeManager that comes out of the box.

See jbpm-sample project for details.

This article is just an introduction to the way jBPM6 and RuntimeManager can be used. More detailed articles will follow to provide in-depth information on every option given here (cdi with services, pure cdi, api).

If you have any aspects that you would like to see in next articles (regarding runtime manager and CDI) just drop a comment here and I'll do by best to include them.