Overview
To enable Activiti in our JEE project the following steps are needed:
- Add the maven dependencies — include spring-context
- Add log4j configuration
- Add the activiti configuration for CDI integration activiti.cfg.xml
- Add your first activiti workflow
- Add an activiti compatible data source to your container
- Deploy and run it
Eclipse Plugin
To install the activiti designer just add the following update site to eclipse: http://docs.alfresco.com/5.2/tasks/wf-install-activiti-designer.html for more details just check the documentation.
Add activity maven dependencies
For JEE we want not only to add the normal dependencies for the core lib but also the CDI integration which allows us later on to access our CDI or EJB beans. In addition, we need one more dependency to have the JNDI bean.
<!-- activiti --> <dependency> <groupId>org.activiti</groupId> <artifactId>activiti-engine</artifactId> <version>6.0.0</version> </dependency> <dependency> <groupId>org.activiti</groupId> <artifactId>activiti-cdi</artifactId> <version>6.0.0</version> </dependency> <!-- to get org.springframework.jndi.JndiObjectFactoryBean, same version as used by activiti --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.2.5.RELEASE</version> </dependency> <!-- Needed to see the log --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>${slf4j.version}</version> </dependency>
Add log4j configuration
Before we start with activiti we should add the log4j.xml configuration into src/main/resources which would allow us to see any error in activiti, otherwise, we are blind.
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration debug="true" xmlns:log4j='http://jakarta.apache.org/log4j/'> <appender name="console" class="org.apache.log4j.ConsoleAppender"> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n" /> </layout> </appender> <root> <level value="INFO" /> <appender-ref ref="console" /> </root> </log4j:configuration>
Add activiti configuration
Add to the src/main/resources
folder the default activiti.cfg.xml
configuration which is picked up automatically by the activiti CDI integration to create the process engine.
TransactionManager
and the ThreadFactory
to ensure threads and the transaction is managed by the JEE container. You may also provide the executor which is configured in the JEE container by you. As the ManagedAsyncJobExecutor
is just creating a ThreadPoolExecutor
under the hood.
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- lookup the JTA-Transaction manager --> <bean id="transactionManager" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="java:appserver/TransactionManager" /> <property name="resourceRef" value="true" /> </bean> <!-- using the JEE container thread factory for the managed executor service --> <bean id="asyncExecutor" class="org.activiti.engine.impl.asyncexecutor.ManagedAsyncJobExecutor"> <property name="threadFactory"> <bean class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="java:comp/DefaultManagedThreadFactory" /> <property name="resourceRef" value="true" /> </bean> </property> </bean> <!-- process engine configuration --> <bean id="processEngineConfiguration" class="org.activiti.cdi.CdiJtaProcessEngineConfiguration"> <property name="dataSourceJndiName" value="jdbc/postgresql" /> <property name="transactionManager" ref="transactionManager" /> <property name="asyncExecutor" ref="asyncExecutor" /> <!-- using externally managed transactions --> <property name="transactionsExternallyManaged" value="true" /> <!-- will create the activiti DB schema automatically as needed --> <property name="databaseSchemaUpdate" value="true" /> </bean> </beans>
Deploy a workflow
Overall where to ways to deploy your workflows. Either using XML or programmatically. Here I will use the last to demonstrate the injection and usage in a very simple (not production-ready) way:
@Singleton @Startup public class SampleProcessDeployerBA { @Inject RepositoryService repositoryService; @PostConstruct void start() { // this will deploy the same process over and over again ... Deployment deploy = repositoryService.createDeployment() .name("SampleProcess") .key("SampleProcess") // note this has no effect, the ID of the bpmn file is used "myProcess" .addClasspathResource("org/sterl/jee/activiti/impl/sample/control/SampleProcess.bpmn") .deploy(); System.out.println("Deployed process ID: " + deploy.getId() + " KEY " + deploy.getKey()); } }
Start a workflow
bpmn
file.
@Named // that activiti finds this EJB @Singleton // show that this is a singleton public class HelloWorldBF { @Inject RuntimeService runtimeService; public void startProcess() { // use here the id you defined in the process designer ProcessInstance process = runtimeService.startProcessInstanceByKey("myProcess"); System.out.println("Process " + process.getName() + " started with ID: " + process.getId()); } }
Activiti support currently following DB
Add to your JEE container one JNDI data source of one of the following supported database types. In this sample we name it jdbc/activiti
.
This list is taken from version 6.0.
- H2
- HSQL
- MYSQL
- ORACLE
- POSTGRES
- MSSQL
- DB2
Information: 2017-08-31 20:49:49 ERROR ProcessEngines:169 - Exception while initializing process engine: couldn't deduct database type from database product name 'Apache Derby' org.activiti.engine.ActivitiException: couldn't deduct database type from database product name 'Apache Derby' at org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl.initDatabaseType(ProcessEngineConfigurationImpl.java:963) at org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl.initDataSource(ProcessEngineConfigurationImpl.java:907) at org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl.init(ProcessEngineConfigurationImpl.java:689) at org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl.buildProcessEngine(ProcessEngineConfigurationImpl.java:664) at org.activiti.engine.ProcessEngines.buildProcessEngine(ProcessEngines.java:189) at org.activiti.engine.ProcessEngines.initProcessEngineFromResource(ProcessEngines.java:162) at org.activiti.engine.ProcessEngines.init(ProcessEngines.java:94) at org.activiti.engine.ProcessEngines.getProcessEngine(ProcessEngines.java:223)