Reuse your business assets with jBPM 6

As described in the article about deployment model in jBPM 6, business assets are included in so called knowledge archives - kjars. Kjar is nothing more than regular jar file with knowledge descriptor - kmodule.xml that is under control of Apache Maven. But there is more in this...

Since kjars are managed by maven one kjar can declare other kjar as its dependency. Which means that assets included in the dependent one will be available for execution as well. That is all available when working with jbpm console (aka kie workbench). So to provide more information on this let's look at an example.

Use case definition

There is a need to prepare a simple registration process that will ask user who starts the process for basic personal information like name, age. Then there will be some business rules that will evaluate if that person is adult or a teenager. Once completed it will be presented to reviewer to see the details of the evaluation. Last but not least is to proceed with actual registration in the system. So we can see that there is part of this logic that might be a very well considered a reusable - part that is responsible for gathering information about a person.

So let's design it this way:

  • first project - reusable project - will actually deal only with gathering personal information and presenting that to verifying personnel after business rules were evaluated.
           As you can see, besides business assets data model is included in reusable-project so it can
           be used by projects that declare it as dependency, same as with any other Maven based project.
  • second project - top project - will provide additional process logic on top of the common collect info procedure and do registration stuff.
So, this is the structure of the projects we are going to use to support the case described.

What must be actually done to make this work? First of all the reusable project needs to be created as it will be a dependency of the top project so it must exists. In the reusable project we need to define knowledge base and knowledge session to disable auto deploy, as we don't want to have it on runtime as a standalone project but included in top project.  With that said we create:
  • one knowledge base (kbase) - ensure it's not marked as default
  • one stateful knowledge session (ksession) - ensure it's not marked as default
  • include all packages - use * wildcard for it
Note: we do this to illustrate what configuration options we have here and to ensure that auto deployment to runtime environment will not be possible - no default knowledge base and knowledge session.

Let's create this collect info process that could look like this:
a simple process, two user tasks and business rule task. So what will it do:
  • Enter person details will collect personal information from a user - name and age
  • Evaluate will execute business rules that are responsible for marking given person as adult if (s)he is older than 21
  • Verify simply presents the results of the process
Both rule and user tasks operate on data model, to be more specific org.jbpm.test.Person class. It was created using Data Modeler and places inside the kjar.
Next process and tasks forms are generated and altered to ask for the right information only. Person class includes three properties:
  • name - string
  • age - integrer
  • adult - boolean
Since we have business rules for evaluating if user is adult or teenager we don't want to ask for it via forms. So these are removed from the "Enter person details" task.
With all that we are ready to build the project so it can be used as dependency. So, just hit the build and deploy button in Project Editor and observe Problems Panel. If everything went ok, it will display single error saying that deployment failed because it cannot find defaultKBase. That is expected as we defined knowledge base and knowledge session that is not marked as default and thus auto deploy fails. But the kjar is available in maven repository so it can be used as dependency.

Next we create top project and add single dependency to it of reusable-project. This is done in Project Editor in Dependencies list section. You can add it from repository as it's already built. Next we need to define knowledge base and knowledge session:
  • one knowledge base (kbase-top) - ensure it's marked as default
  • one stateful knowledge session (ksession-top) - ensure it's marked as default
  • include all packages - use * wildcard for it
  • include kbase defined in reusable project - kbase
Note: make sure that names do no collide between kjars as that will result in failing compilation of knowledge base.

Now we are ready to create our top level process that could look like this:

Again simple process, that will:

  • log incoming request for registration using script task - Log registration
  • invoke common part to collect info - Collect Info - by invoking the reusable project process, rules, forms etc
  • and lastly will show the outcome of the collection process for approval
The most important part here is that Collect Info activity will use process (and other assets) from another kjar thanks to usage of maven dependencies and kbase inclusion.

To examine this example in details you can clone the repository in your jbpm console (kie workbench) and build both projects - first reusable project and then top project. 

This illustrates only the top of the mountain that is provided by maven dependencies and knowledge inclusion in jBPM 6. I would like to encourage you to explore this possibilities and look at options to reuse your knowledge in structured and controlled way - remember this is all standardized by maven so things like versioning are supported as well.

This is a feature that will be available in 6.1.0 so feel free to jump into the wild right away by making use of it in nightly builds. Comments and feedback are welcome.


  1. Do dependencies work with custom work item handlers? I tried to split my project into main project (process definitions), model (dependency of main project, contains Program class) and another .jar with custom work item handler (installed into WEB-INF/lib of jbm-console). The handler calls JSON webservice and maps response to Program class. Unfortunately I am getting ClassNotFoundException in the handler - it cannot find Program class. Maybe I am structuring it in a wrong way.

  2. they do work but they must be on the same classloader hierarchy level - same as for any other classes. If you add your model to the project dependencies then handler must be there too. If you place handler on WEB-INF/lib it won't be able to see any child classloaders and their classes. So make sure to apply one of following approaches:
    - model jar in WEB-INF/lib
    - handler as project dependency

  3. This comment has been removed by the author.

  4. Hi... thanks for tutorial.
    I tried to follow it but in my case i have multiple processes to call by CallActivity so my main process should include many other kbase.
    There is an easy way to declare a group of processes in the same kbase?


  5. Hi Maceij,

    I have followed the steps but i got the below error while compiling the top project

    2018-06-04 14:23:37,766 ERROR [org.kie.workbench.common.services.backend.builder.core.BuildHelper] (default task-17) null: java.lang.NullPointerException
    at org.kie.scanner.KieModuleMetaDataImpl.indexKieModule(KieModuleMetaDataImpl.java:97)
    at org.kie.scanner.KieModuleMetaDataImpl.(KieModuleMetaDataImpl.java:85)
    at org.kie.scanner.KieModuleMetaData$Factory.newKieModuleMetaData(KieModuleMetaData.java:60)
    at org.kie.workbench.common.services.backend.builder.core.Builder.getKieModuleMetaDataIgnoringErrors(Builder.java:589)
    at org.kie.workbench.common.services.backend.builder.core.Builder.build(Builder.java:270)
    at org.kie.workbench.common.services.backend.builder.core.BuildHelper.build(BuildHelper.java:92)
    at org.kie.workbench.common.services.backend.builder.core.BuildHelper$Proxy$_$$_WeldClientProxy.build(Unknown Source)
    at org.kie.workbench.common.services.backend.builder.ala.LocalBuildExecConfigExecutor.apply(LocalBuildExecConfigExecutor.java:64)
    at org.kie.workbench.common.services.backend.builder.ala.LocalBuildExecConfigExecutor.apply(LocalBuildExecConfigExecutor.java:32)
    at org.kie.workbench.common.services.backend.builder.ala.LocalBuildExecConfigExecutor$Proxy$_$$_WeldClientProxy.apply(Unknown Source)
    at org.guvnor.ala.pipeline.execution.PipelineExecutor.lambda$continuePipeline$0(PipelineExecutor.java:95)
    at org.guvnor.ala.pipeline.StageUtil$1.execute(StageUtil.java:40)
    at org.guvnor.ala.pipeline.StageUtil$1.execute(StageUtil.java:35)
    at org.guvnor.ala.pipeline.execution.PipelineExecutor.continuePipeline(PipelineExecutor.java:83)
    at org.guvnor.ala.pipeline.execution.PipelineExecutor.execute(PipelineExecutor.java:71)
    at org.kie.workbench.common.services.backend.builder.ala.BuildPipelineInvoker.invokeLocalBuildPipeLine(BuildPipelineInvoker.java:84)
    at org.kie.workbench.common.services.backend.builder.ala.BuildPipelineInvoker$Proxy$_$$_WeldClientProxy.invokeLocalBuildPipeLine(Unknown Source)

    Can you please help me out in this ?
    thanks in advance :)