JBoss.org Community Documentation

- Prev
- Next

## Chapter 11. Integration with Spring

## 11.1. Important Changes for Drools 6.0

Drools Spring integration has undergone a complete makeover inline with the changes for Drools 6.0. The following are some of the major changes

- The recommended prefix for the Drools Spring has changed from 'drools:' to 'kie:'

- New Top Level Tags in 6.0

  - kie:kmodule

- The following tags are no longer valid as top level tags.

  - kie:kbase - A child of the kie:kmodule tag.

  - kie:ksession - A child of the kie:kbase tag.

- Removed Tags from previous versions Drools 5.x

  - drools:resources

  - drools:resource

  - drools:grid

  - drools:grid-node

## 11.2. Integration with Drools Expert

In this section we will explain the kie namespace.

### 11.2.1. KieModule

The <kie:kmodule> defines a collection of KieBase and associated KieSession's. The kmodule tag has one MANDATORY parameter 'id'.

Table 11.1. Sample

Attribute | Description | Required
--- | --- | ---
id | Bean's id is the name to be referenced from other beans. Standard Spring ID semantics apply. | Yes

A kmodule tag can contain only the following tags as children.

- kie:kbase

Refer to the documentation of kmodule.xml in the Drools Expert documentation for detailed explanation of the need for kmodule.

### 11.2.2. KieBase

#### 11.2.2.1. <kie:kbase>'s parameters as attributes:

Table 11.2. Sample

Attribute | Description | Required
--- | --- | ---
name | Name of the KieBase | Yes
packages | Comma separated list of resource packages to be included in this kbase | No
includes | kbase names to be included. All resources from the corresponding kbase are included in this kbase. | No
default | Default kbase | No
default | Boolean (TRUE/FALSE). Default kbase, if not provided, it is assumed to be FALSE | No
scope | . | No
eventProcessingMode | Event Processing Mode. Valid options are STREAM, CLOUD | No
equalsBehavior | Valid options are IDENTITY, EQUALITY | No
declarativeAgenda | Valid options are enabled, disabled, true, false | No

#### 11.2.2.2. A kbase tag can contain only the following tags as children.

- kie:ksession

#### 11.2.2.3. <kie:kbase>'s definition example

A kmodule can contain multiple (1..n) kbase elements.

Example 11.1. kbase definition example

    <kie:kmodule id="sample_module">

       <kie:kbase name="kbase1" packages="org.drools.spring.sample">

         ...

       </kie:kbase>

    </kie:kmodule>

    <bean id="kiePostProcessor"

              class="org.kie.spring.KModuleBeanFactoryPostProcessor"/>

### 11.2.3. IMPORTANT NOTE

For proper initialization of the kmodule objects (kbase/ksession), it is mandatory for a bean of type `org.kie.spring.KModuleBeanFactoryPostProcessor` be defined.

Example 11.2. kie-spring post processorbean definition

    <bean id="kiePostProcessor"

              class="org.kie.spring.KModuleBeanFactoryPostProcessor"/>

## Note

Without the org.kie.spring.KModuleBeanFactoryPostProcessor bean definition, the kie-spring integration will not work.

### 11.2.4. KieSessions

<kie:ksession> element defines KieSessions. The same tag is used to define both Stateful (org.kie.api.runtime.KieSession) and Stateless (org.kie.api.runtime.StatelessKieSession) sessions.

#### 11.2.4.1. <kie:ksession>'s parameters as attributes:

Table 11.3. Sample

Attribute | Description | Required
--- | --- | ---
name | ksession's name. | Yes
type | is the session stateful or stateless?. If this attribute is empty or missing, the session is assumed to be of type Stateful. | No
default | Is this the default session? | no
scope | . | no
clockType | REALTIME or PSEUDO | no
listeners-ref | Specifies the reference to the event listeners group (see 'Defining a Group of listeners' section below). | no

Example 11.3. ksession definition example

    <kie:kmodule id="sample-kmodule">

      <kie:kbase name="drl_kiesample3" packages="drl_kiesample3">

        <kie:ksession name="ksession1" type="stateless"/>

        <kie:ksession name="ksession2"/>

      </kie:kbase>

    </kie:kmodule>

    <bean id="kiePostProcessor"

              class="org.kie.spring.KModuleBeanFactoryPostProcessor"/>

### 11.2.5. Event Listeners

Drools supports adding 3 types of listeners to KieSessions - AgendaListener, WorkingMemoryListener, ProcessEventListener

The kie-spring module allows you to configure these listeners to KieSessions using XML tags. These tags have identical names as the actual listener interfaces i.e., <kie:agendaEventListener....>, <kie:ruleRuntimeEventListener....> and <kie:processEventListener....>.

kie-spring provides features to define the listeners as standalone (individual) listeners and also to define them as a group.

#### 11.2.5.1. Defining Stand alone Listeners:

##### 11.2.5.1.1. Attributes:

Table 11.4. Sample

Attribute | Required | Description
--- | --- | ---
ref | No | A reference to another declared bean.

Example 11.4. Listener configuration example - using a bean:ref.

    <bean id="mock-agenda-listener" class="mocks.MockAgendaEventListener"/>

    <bean id="mock-rr-listener" class="mocks.MockRuleRuntimeEventListener"/>

    <bean id="mock-process-listener" class="mocks.MockProcessEventListener"/>

    <kie:kmodule id="listeners_kmodule">

      <kie:kbase name="drl_kiesample" packages="drl_kiesample">

        <kie:ksession name="ksession2">

          <kie:agendaEventListener ref="mock-agenda-listener"/>

          <kie:processEventListener ref="mock-process-listener"/>

          <kie:ruleRuntimeEventListener ref="mock-rr-listener"/>

        </kie:ksession>

      </kie:kbase>

    </kie:kmodule>

    <bean id="kiePostProcessor"

              class="org.kie.spring.KModuleBeanFactoryPostProcessor"/>

##### 11.2.5.1.2. Nested Elements:

- bean

  - class = String

  - name = String (optional)

Example 11.5. Listener configuration example - using nested bean.

    <kie:kmodule id="listeners_module">

      <kie:kbase name="drl_kiesample" packages="drl_kiesample">

       <kie:ksession name="ksession1">

          <kie:agendaEventListener>

          <bean class="mocks.MockAgendaEventListener"/>

          </kie:agendaEventListener>

        </kie:ksession>

      </kie:kbase>

    </kie:kmodule>

    <bean id="kiePostProcessor"

              class="org.kie.spring.KModuleBeanFactoryPostProcessor"/>

##### 11.2.5.1.3. Empty Tag : Declaration with no 'ref' and without a nested bean

When a listener is defined without a reference to a implementing bean and does not contain a nested bean, <drools:ruleRuntimeEventListener/> the underlying implementation adds the Debug version of the listener defined in the API.

The debug listeners print the corresponding Event toString message to System.err.

Example 11.6. Listener configuration example - defaulting to the debug versions provided by the Knowledge-API .

    <bean id="mock-agenda-listener" class="mocks.MockAgendaEventListener"/>

    <bean id="mock-rr-listener" class="mocks.MockRuleRuntimeEventListener"/>

    <bean id="mock-process-listener" class="mocks.MockProcessEventListener"/>

    <kie:kmodule id="listeners_module">

     <kie:kbase name="drl_kiesample" packages="drl_kiesample">

        <kie:ksession name="ksession2">

          <kie:agendaEventListener />

          <kie:processEventListener />

          <kie:ruleRuntimeEventListener />

        </kie:ksession>

     </kie:kbase>

    </kie:kmodule>

    <bean id="kiePostProcessor"

              class="org.kie.spring.KModuleBeanFactoryPostProcessor"/>

##### 11.2.5.1.4. Mix and Match of different declaration styles

The drools-spring module allows you to mix and match the different declarative styles within the same KieSession. The below sample provides more clarity.

Example 11.7. Listener configuration example - mix and match of 'ref'/nested-bean/empty styles.

    <bean id="mock-agenda-listener" class="mocks.MockAgendaEventListener"/>

    <bean id="mock-rr-listener" class="mocks.MockRuleRuntimeEventListener"/>

    <bean id="mock-process-listener" class="mocks.MockProcessEventListener"/>

    <kie:kmodule id="listeners_module">

      <kie:kbase name="drl_kiesample" packages="drl_kiesample">

        <kie:ksession name="ksession1">

          <kie:agendaEventListener>

              <bean class="org.kie.spring.mocks.MockAgendaEventListener"/>

          </kie:agendaEventListener>

        </kie:ksession>

        <kie:ksession name="ksession2">

          <kie:agendaEventListener ref="mock-agenda-listener"/>

          <kie:processEventListener ref="mock-process-listener"/>

          <kie:ruleRuntimeEventListener ref="mock-rr-listener"/>

        </kie:ksession>

      </kie:kbase>

    </kie:kmodule>

    <bean id="kiePostProcessor"

              class="org.kie.spring.KModuleBeanFactoryPostProcessor"/>

##### 11.2.5.1.5. Defining multiple listeners of the same type

It is also valid to define multiple beans of the same event listener types for a KieSession.

Example 11.8. Listener configuration example - multiple listeners of the same type.

    <bean id="mock-agenda-listener" class="mocks.MockAgendaEventListener"/>

    <kie:kmodule id="listeners_module">

      <kie:kbase name="drl_kiesample" packages="drl_kiesample">

        <kie:ksession name="ksession1">

          <kie:agendaEventListener ref="mock-agenda-listener"/>

          <kie:agendaEventListener>

              <bean class="org.kie.spring.mocks.MockAgendaEventListener"/>

          </kie:agendaEventListener>

        </kie:ksession>

      </kie:kbase>

    </kie:kmodule>

    <bean id="kiePostProcessor"

              class="org.kie.spring.KModuleBeanFactoryPostProcessor"/>

#### 11.2.5.2. Defining a Group of listeners:

drools-spring allows for grouping of listeners. This is particularly useful when you define a set of listeners and want to attach them to multiple sessions. The grouping feature is also very useful, when we define a set of listeners for 'testing' and then want to switch them for 'production' use.

##### 11.2.5.2.1. Attributes:

Table 11.5. Sample

Attribute | Required | Description
--- | --- | ---
ID | yes | Unique identifier

##### 11.2.5.2.2. Nested Elements:

- drools:agendaEventListener...

- drools:ruleRuntimeEventListener...

- drools:processEventListener...

## Note

The above mentioned child elements can be declared in any order. Only one declaration of each type is allowed in a group.

##### 11.2.5.2.3. Example:

Example 11.9. Group of listeners - example

    <bean id="mock-agenda-listener" class="mocks.MockAgendaEventListener"/>

    <bean id="mock-rr-listener" class="mocks.MockRuleRuntimeEventListener"/>

    <bean id="mock-process-listener" class="mocks.MockProcessEventListener"/>

    <kie:kmodule id="listeners_module">

      <kie:kbase name="drl_kiesample" packages="drl_kiesample">

        <kie:ksession name="statelessWithGroupedListeners" type="stateless"

                 listeners-ref="debugListeners"/>

      </kie:kbase>

    </kie:kmodule>

      <kie:eventListeners id="debugListeners">

      <kie:agendaEventListener ref="mock-agenda-listener"/>

      <kie:processEventListener ref="mock-process-listener"/>

      <kie:ruleRuntimeEventListener ref="mock-rr-listener"/>

    </kie:eventListeners>

    <bean id="kiePostProcessor"

              class="org.kie.spring.KModuleBeanFactoryPostProcessor"/>

### 11.2.6. Loggers

Drools supports adding 2 types of loggers to KieSessions - ConsoleLogger, FileLogger.

The kie-spring module allows you to configure these loggers to KieSessions using XML tags. These tags have identical names as the actual logger interfaces i.e., <kie:consoleLogger....> and <kie:fileLogger....>.

#### 11.2.6.1. Defining a console logger:

A console logger can be attached to a KieSession by using the <kie:consoleLogger/> tag. This tag has no attributes and must be present directly under a <kie:ksession....> element.

Example 11.10. Defining a console logger - example

    <kie:kmodule id="loggers_module">

      <kie:kbase name="drl_kiesample" packages="drl_kiesample">

        <kie:ksession name="ConsoleLogger-statefulSession" type="stateful">

          <kie:consoleLogger/>

        </kie:ksession>

      </kie:kbase>

    </kie:kmodule>

    <bean id="kiePostProcessor"

              class="org.kie.spring.KModuleBeanFactoryPostProcessor"/>

#### 11.2.6.2. Defining a file logger:

A file logger can be attached to a KieSession by using the <kie:fileLogger/> tag. This tag has the following attributes and must be present directly under a <kie:ksession....> element.

Table 11.6. Sample

Attribute | Required | Description
--- | --- | ---
ID | yes | Unique identifier
file | yes | Path to the actual file on the disk
threaded | no | Defaults to false. Valid values are 'true'or 'false'
interval | no | Integer. Specifies the interval for flushing the contents from memory to the disk.

Example 11.11. Defining a file logger - example

    <kie:kmodule id="loggers_module">

      <kie:kbase name="drl_kiesample" packages="drl_kiesample">

        <kie:ksession name="ConsoleLogger-statefulSession" type="stateful">

          <kie:fileLogger id="fl_logger" file="#{ systemProperties['java.io.tmpdir'] }/log1"/>

          <kie:fileLogger id="tfl_logger" file="#{ systemProperties['java.io.tmpdir'] }/log2"

                              threaded="true" interval="5"/>

        </kie:ksession>

      </kie:kbase>

    </kie:kmodule>

    <bean id="kiePostProcessor"

              class="org.kie.spring.KModuleBeanFactoryPostProcessor"/>

##### 11.2.6.2.1. Closing a FileLogger

To prevent leaks, it is advised to close the <kie:fileLogger ...> programatically.

    LoggerAdaptor adaptor = (LoggerAdaptor) context.getBean("fl_logger");

    adaptor.close();

### 11.2.7. Defining Batch Commands

A <kie:batch> element can be used to define a set of batch commands for a given ksession.This tag has no attributes and must be present directly under a <kie:ksession....> element. The commands supported are

- insert-object

  - ref = String (optional)

  - Anonymous bean

- set-global

  - identifier = String (required)

  - reg = String (optional)

  - Anonymous bean

- fire-all-rules

  - max : n

- fire-until-halt

- start-process

  - parameter

    - identifier = String (required)

    - ref = String (optional)

    - Anonymous bean

- signal-event

  - ref = String (optional)

  - event-type = String (required)

  - process-instance-id =n (optional)

Figure 11.1. Initialization Batch Commands

Example 11.12. Batch commands - example

    <kie:kmodule id="batch_commands_module">

      <kie:kbase name="drl_kiesample" packages="drl_kiesample">

        <kie:ksession name="ksessionForCommands" type="stateful">

          <kie:batch>

            <kie:insert-object ref="person2"/>

            <kie:set-global identifier="persons" ref="personsList"/>

            <kie:fire-all-rules max="10"/>

          </kie:batch>

        </kie:ksession>

      </kie:kbase>

    </kie:kmodule>

    <bean id="kiePostProcessor"

              class="org.kie.spring.KModuleBeanFactoryPostProcessor"/>

### 11.2.8. Persistence

- jpa-persistence

  - transaction-manager

    - ref = String

  - entity-manager-factory

    - ref = String

Figure 11.2. Persistence Configuration Options

Example 11.13. ksession JPA configuration example

    <kie:kstore id="kstore" /> <!-- provides KnowledgeStoreService implementation -->

    <bean id="myEmf"

           class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">

       <property name="dataSource" ref="ds" />

       <property name="persistenceUnitName"

           value="org.drools.persistence.jpa.local" />

    </bean>

    <bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">

       <property name="entityManagerFactory" ref="myEmf" />

    </bean>

    <kie:kmodule id="persistence_module">

      <kie:kbase name="drl_kiesample" packages="drl_kiesample">

        <kie:ksession name="jpaSingleSessionCommandService">

          <kie:configuration>

             <kie:jpa-persistence>

               <kie:transaction-manager ref="txManager"/>

               <kie:entity-manager-factory ref="myEmf"/>

             </kie:jpa-persistence>

          </kie:configuration>

        </kie:ksession>

      </kie:kbase>

    </kie:kmodule>

    <bean id="kiePostProcessor"

              class="org.kie.spring.KModuleBeanFactoryPostProcessor"/>

## 11.3. Integration with jBPM Human Task

This chapter describes the infrastructure used when configuring a human task server with Spring as well as a little bit about the infrastructure used when doing this.

### 11.3.1. How to configure Spring with jBPM Human task

The jBPM human task server can be configured to use Spring persistence. Example 11.14, “Configuring Human Task with Spring” is an example of this which uses local transactions and Spring's thread-safe EntityManager proxy.

The following diagram shows the dependency graph used in Example 11.14, “Configuring Human Task with Spring”.

Figure 11.3. Spring Human Task integration injection dependencies

A `TaskService` instance is dependent on two other bean types: a drools `SystemEventListener` bean as well as a `TaskSessionSpringFactoryImpl` bean. The `TaskSessionSpringFactoryImpl` bean is howerver not injected into the `TaskService` bean because this would cause a circular dependency. To solve this problem, when the `TaskService` bean is injected into the `TaskSessionSpringFactoryImpl` bean, the setter method used secretly injects the `TaskSessionSpringFactoryImpl` instance back into the `TaskService` bean and initializes the `TaskService` bean as well.

The `TaskSessionSpringFactoryImpl` bean is responsible for creating all the internal instances in human task that deal with transactions and persistence context management. Besides a `TaskService` instance, this bean also requires a transaction manager and a persistence context to be injected. Specifically, it requires an instance of a `HumanTaskSpringTransactionManager` bean (as a transaction manager) and an instance of a `SharedEntityManagerBean` bean (as a persistence context instance).

We also use some of the standard Spring beans in order to configure persistence: there's a bean to hold the `EntityManagerFactory` instance as well as the `SharedEntityManagerBean` instance. The `SharedEntityManagerBean` provides a shared, thread-safe proxy for the actual `EntityManager`.

The `HumanTaskSpringTransactionManager` bean serves as a wrapper around the Spring transaction manager, in this case the `JpaTransactionManager`. An instance of a `JpaTransactionManager` bean is also instantiated because of this.

Example 11.14. Configuring Human Task with Spring

    <?xml version="1.0" encoding="UTF-8"?>

    <beans xmlns="http://www.springframework.org/schema/beans"

           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

           xmlns:jbpm="http://drools.org/schema/drools-spring"

           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

           http://drools.org/schema/drools-spring org/drools/container/spring/drools-spring-1.2.0.xsd">

      <!-- persistence & transactions-->

      <bean id="htEmf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">

        <property name="persistenceUnitName" value="org.jbpm.task" />

      </bean>

      <bean id="htEm" class="org.springframework.orm.jpa.support.SharedEntityManagerBean">

        <property name="entityManagerFactory" ref="htEmf"/>

      </bean>

      <bean id="jpaTxMgr" class="org.springframework.orm.jpa.JpaTransactionManager">

        <property name="entityManagerFactory" ref="htEmf" />

        <!-- this must be true if using the SharedEntityManagerBean, and false otherwise -->

        <property name="nestedTransactionAllowed" value="true"/>

      </bean>

      <bean id="htTxMgr" class="org.drools.container.spring.beans.persistence.HumanTaskSpringTransactionManager">

        <constructor-arg ref="jpaTxMgr" />

      </bean>

      <!-- human-task beans -->

      <bean id="systemEventListener" class="org.drools.SystemEventListenerFactory" factory-method="getSystemEventListener" />

      <bean id="taskService" class="org.jbpm.task.service.TaskService" >

        <property name="systemEventListener" ref="systemEventListener" />

      </bean>

      <bean id="springTaskSessionFactory" class="org.jbpm.task.service.persistence.TaskSessionSpringFactoryImpl"

            init-method="initialize" depends-on="taskService" >

        <!-- if using the SharedEntityManagerBean, make sure to enable nested transactions -->

        <property name="entityManager" ref="htEm" />

        <property name="transactionManager" ref="htTxMgr" />

        <property name="useJTA" value="false" />

        <property name="taskService" ref="taskService" />

      </bean>

    </beans>

When using the `SharedEntityManagerBean` instance, it's important to configure the Spring transaction manager to use nested transactions. This is because the `SharedEntityManagerBean` is a transactional persistence context and will close the persistence context after every operation. However, the human task server needs to be able to access (persisted) entities after operations. Nested transactions allow us to still have access to entities that otherwise would have been detached and are no longer accessible, especially when using an ORM framework that uses lazy-initialization of entities.

Also, while the `TaskSessionSpringFactoryImpl` bean takes an “useJTA” parameter, at the moment, JTA transactions with Spring have not yet been fully tested.

- PrevChapter 10. CDI
- Top of page
- Front page
- NextChapter 12. Apache Camel Integration