Chapter 14. Integration with Spring
14.1. Configuring Red Hat JBoss BPM Suite with Spring
The jboss-bpms-engine.zip file contains the Spring module, which is called kie-spring-VERSION-redhat-MINOR_VERSION.jar.
You can configure the Spring modules:
- As a Self Managed Process Engine
-
If you require a single runtime manager instance, use the
RuntimeManagerAPI. TheRuntimeManagerAPI synchronizes the process engine and task service internally. - As a Shared Task Service
- If you require multiple runtime manager instances, use the jBPM services.
Do not use the shared task service if you use Spring and your process is instantiated using the per process or per request runtime strategy.
14.1.1. Integrating Spring with Runtime Manager API
To integrate Spring with the Runtime Manager API, include the following factory beans:
-
org.kie.spring.factorybeans.RuntimeEnvironmentFactoryBean -
org.kie.spring.factorybeans.RuntimeManagerFactoryBean -
org.kie.spring.factorybeans.TaskServiceFactoryBean
TaskServiceFactoryBean is required only for shared task service.
RuntimeEnvironmentFactoryBean
RuntimeEnvironmentFactoryBean produces RuntimeEnvironment instances consumed by RuntimeManager.
You can create the following types of RuntimeEnvironment instances:
-
DEFAULT: The default type. -
EMPTY: An empty environment. -
DEFAULT_IN_MEMORY: Same asDEFAULTwith no persistence of the runtime engine. -
DEFAULT_KJAR: Same asDEFAULTwith knowledge assets taken from kJAR and identified byreleaseIDor GAV (Group, Artifact, Version). -
DEFAULT_KJAR_CL: Built from class path that consists of akmodule.xmldescriptor.
Knowledge information is required for all the RuntimeEnvironment types. Provide one or more of the following:
-
knowledgeBase -
assets -
releaseId -
groupId,artifactId,version
For the DEFAULT, DEFAULT_KJAR, DEFAULT_KJAR_CL types, configure persistence using entity manager factory or transaction manager.
RuntimeManagerFactoryBean
RuntimeManagerFactoryBean creates RuntimeManager instances based on runtimeEnvironment. You can create the following runtimeEnvironment instances:
-
SINGLETON(default) -
PER_REQUEST -
PER_PROCESS_INSTANCE
Every RuntimeManager instance must have a unique ID. You can dispose of any RuntimeManager instance created by RuntimeManagerFactoryBean by calling the close() method.
TaskServiceFactoryBean
TaskServiceFactoryBean creates TaskService instance based on the given properties. Creates a single instance only.
Properties required:
-
entity manager factory -
transaction manager
When using the TaskServiceFactoryBean, provide the Spring transaction manager. When using a shared entity manager from Spring, you can also provide EntityManager instance instead of entity manager factory.
Optional properties:
-
userGroupCallback:MVELUserGroupCallbackImplby default. -
userInfo:DefaultUserInfoby default. -
listener: List ofTaskLifeCycleEventListenerinstances.
Sample RuntimeManager Configuration with Spring
To create a single runtime manager Spring configuration:
Configure the entity manager factory and the transaction manager, for example:
<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>This configuration provides:
- JTA transaction manager, backed by Bitronix for unit tests or servlet containers.
-
The
org.jbpm.persistence.spring.jtaentity manager factory for persistence unit.
Configure resources you use, for example a business process:
<bean id="process" factory-method="newclass pathResource" class="org.kie.internal.io.ResourceFactory"> <constructor-arg> <value>jbpm/processes/sample.bpmn</value> </constructor-arg> </bean>The
sample.bpmnprocess is included from the class path.Configure
RuntimeEnvironmentusing your entity manager, transaction manager, and 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>Create
RuntimeManager:<bean id="runtimeManager" class="org.kie.spring.factorybeans.RuntimeManagerFactoryBean" destroy-method="close"> <property name="identifier" value="spring-rm"/> <property name="runtimeEnvironment" ref="runtimeEnvironment"/> </bean>
An example of complete configuration:
<?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:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">
<import resource="classpath:jbpm/configuration-template/assets.xml" />
<bean id="jbpmEMF" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="org.jbpm.persistence.spring.jta"/>
<property name="persistenceXmlLocation" value="classpath:jbpm/persistence-jta.xml"/>
</bean>
<bean id="btmConfig" factory-method="getConfiguration" class="bitronix.tm.TransactionManagerServices"/>
<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>
<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" ref="assets"/>
</bean>
<bean id="logService" class="org.jbpm.process.audit.JPAAuditLogService" depends-on="runtimeEnvironment">
<constructor-arg value="#{runtimeEnvironment.environment}" />
<constructor-arg value="STANDALONE_JTA" />
</bean>
</beans>14.1.2. Spring and jBPM Services
If you require multiple runtime managers, you can use jBPM services directly in your application. Due to the dynamic nature of jBPM services, processes and other assets can be added and removed without restarting your application.
To configure jBPM services:
Add the
kie-springMaven dependency into yourpom.xml:<dependencies> ... <dependency> <groupId>org.kie</groupId> <artifactId>kie-spring</artifactId> <version>6.5.0.Final-redhat-2</version> </dependency> ... </dependencies>For the current Maven artifact version, see chapter Supported Component Versions of the Red Hat JBoss BPM Suite Installation Guide.
Depending on your implementation, other dependencies may be necessary, for example spring-security.
Implement the
IdentityProviderinterface:import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.kie.internal.identity.IdentityProvider; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; public class SpringSecurityIdentityProvider implements IdentityProvider { public String getName() { Authentication auth = SecurityContextHolder.getContext().getAuthentication(); if (auth != null && auth.isAuthenticated()) { return auth.getName(); } return "system"; } public List<String> getRoles() { Authentication auth = SecurityContextHolder.getContext().getAuthentication(); if (auth != null && auth.isAuthenticated()) { List<String> roles = new ArrayList<String>(); for (GrantedAuthority ga : auth.getAuthorities()) { roles.add(ga.getAuthority()); } return roles; } return Collections.emptyList(); } public boolean hasRole(String role) { return false; } }
To configure jBPM services in a Spring application:
Configure the transaction manager:
<context:annotation-config /> <tx:annotation-driven /> <tx:jta-transaction-manager /> <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" />
Configure JPA and persistence:
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" depends-on="transactionManager"> <property name="persistenceXmlLocation" value="classpath:/META-INF/jbpm-persistence.xml" /> </bean>
Configure security providers:
<util:properties id="roleProperties" location="classpath:/roles.properties" /> <bean id="userGroupCallback" class="org.jbpm.services.task.identity.JBossUserGroupCallbackImpl"> <constructor-arg name="userGroups" ref="roleProperties"></constructor-arg> </bean> <bean id="identityProvider" class="org.jbpm.spring.SpringSecurityIdentityProvider"/>
Configure the runtime manager factory:
<bean id="runtimeManagerFactory" class="org.kie.spring.manager.SpringRuntimeManagerFactoryImpl"> <property name="transactionManager" ref="transactionManager"/> <property name="userGroupCallback" ref="userGroupCallback"/> </bean> <bean id="transactionCmdService" class="org.jbpm.shared.services.impl.TransactionalCommandService"> <constructor-arg name="emf" ref="entityManagerFactory"></constructor-arg> </bean> <bean id="taskService" class="org.kie.spring.factorybeans.TaskServiceFactoryBean" destroy-method="close"> <property name="entityManagerFactory" ref="entityManagerFactory"/> <property name="transactionManager" ref="transactionManager"/> <property name="userGroupCallback" ref="userGroupCallback"/> <property name="listeners"> <list> <bean class="org.jbpm.services.task.audit.JPATaskLifeCycleEventListener"> <constructor-arg value="true"/> </bean> </list> </property> </bean>The runtime manager factory is Spring context aware and can interact with Spring containers.
Configure jBPM services as Spring beans:
<!-- definition service --> <bean id="definitionService" class="org.jbpm.kie.services.impl.bpmn2.BPMN2DataServiceImpl"/> <!-- runtime data service --> <bean id="runtimeDataService" class="org.jbpm.kie.services.impl.RuntimeDataServiceImpl"> <property name="commandService" ref="transactionCmdService"/> <property name="identityProvider" ref="identityProvider"/> <property name="taskService" ref="taskService"/> </bean> <!-- -- deployment service --> <bean id="deploymentService" class="org.jbpm.kie.services.impl.KModuleDeploymentService" depends-on="entityManagerFactory" init-method="onInit"> <property name="bpmn2Service" ref="definitionService"/> <property name="emf" ref="entityManagerFactory"/> <property name="managerFactory" ref="runtimeManagerFactory"/> <property name="identityProvider" ref="identityProvider"/> <property name="runtimeDataService" ref="runtimeDataService"/> </bean> <!-- process service --> <bean id="processService" class="org.jbpm.kie.services.impl.ProcessServiceImpl" depends-on="deploymentService"> <property name="dataService" ref="runtimeDataService"/> <property name="deploymentService" ref="deploymentService"/> </bean> <!-- user task service --> <bean id="userTaskService" class="org.jbpm.kie.services.impl.UserTaskServiceImpl" depends-on="deploymentService"> <property name="dataService" ref="runtimeDataService"/> <property name="deploymentService" ref="deploymentService"/> </bean> <!-- register runtime data service as listener on deployment service so it can receive notification about deployed and undeployed units --> <bean id="data" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean" depends-on="deploymentService"> <property name="targetObject" ref="deploymentService"></property> <property name="targetMethod"><value>addListener</value></property> <property name="arguments"> <list> <ref bean="runtimeDataService"/> </list> </property> </bean>

Where did the comment section go?
Red Hat's documentation publication system recently went through an upgrade to enable speedier, more mobile-friendly content. We decided to re-evaluate our commenting platform to ensure that it meets your expectations and serves as an optimal feedback mechanism. During this redesign, we invite your input on providing feedback on Red Hat documentation via the discussion platform.