Activiti工作流框架:ProcessEngines.getDefaultProcessEngine()为null解决方案

解决Activiti工作流框架ProcessEngines.getDefaultProcessEngine()为null问题
本文介绍了当使用Activiti工作流框架遇到`ProcessEngines.getDefaultProcessEngine()`返回null时的可能原因和解决方案,包括配置文件错误、jar包缺失以及数据库配置和初始化问题。通过检查配置文件名称、路径、jar依赖、数据库连接以及流程定义文件,可以解决此问题。

可能原因1:Activiti的配置文件名称或路径出错

通过如下方法获取的流程引擎对象,需要保证Activiti配置文件名称为"activiti.cfg.xml"并且位于classpath下(可参考Activiti源码)。
// 创建流程引擎
 ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
如图所示为java project的目录结构,按照某些教程把activiti.cfg.xml放在了新建的resource文件夹下,但是resource并不是资源文件夹也是会出错,这时应该右键resource文件夹->build path->use as source folder指定为资源目录(右上角出现"#"图案)。


可能原因2:jar包缺失

只简单添加了activiti/libs 目录下的所有jar包以及log4j、slf4j相关包

缺少mysql驱动包
缺少spring-beans、spring-core相关包
缺少mybatis相关包
缺少commons-xxx相关包
缺少juel相关包
缺少jackson相关包
...
建议将activiti/wars/中的某个war包解压,导入其中lib下的所有Jar包,缺少包会报ClassNotFoundException,再根据情况添包。附上lib图:



其它原因:配置文件内容有误或没有事先建立配置文件指向的数据库(数据库服务要开启)

(1)在activiti.cfg.xml配置文件中,添加了<property name="jobExecutorActivate" value="false" /> 去掉该属性试试。
(2)检查databaseSchemaUpdate配置是否与数据库表存在冲突?

测试源代码

package com.bo.activiti;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.task.Task;

public class First {
	public static void main(String[] args){
		// 创建流程引擎
 		ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//		ProcessEngine processEngine = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml").buildProcessEngine();
		System.out.println(processEngine);
		// 得到流程存储服务组件
		RepositoryService repositoryService = processEngine.getRepositoryService();
		// 得到运行时服务组件
		RuntimeService runtimeService = processEngine.getRuntimeService();
		// 获取流程任务组件
		TaskService taskService = processEngine.getTaskService();
		// 部署流程定义文件
		repositoryService.createDeployment().addClasspathResource("bpmn/first.bpmn").deploy();
		// 启动流程
		runtimeService.startProcessInstanceByKey("myProcess");
		// 查询第一个任务
		Task task = taskService.createTaskQuery().singleResult();
		System.out.println("第一个任务完成前,当前任务名称:"+task.getName());
		// 完成第一个任务
		taskService.complete(task.getId());
		// 查询第二个任务
		task = taskService.createTaskQuery().singleResult();
		System.out.println("第二个任务完成前,当前任务名称:"+task.getName());
		// 完成第二个任务(流程结束)
		taskService.complete(task.getId());
		task = taskService.createTaskQuery().singleResult();
		System.out.println("流程结束后,查找任务:" + task);
		
	}
}

流程定义配置文件:first.bpmn

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
  <process id="myProcess" name="My process" isExecutable="true">
    <startEvent id="startevent1" name="Start"></startEvent>
    <userTask id="usertask2" name="Handle Request"></userTask>
    <userTask id="usertask3" name="Expense Request"></userTask>
    <endEvent id="endevent1" name="End"></endEvent>
    <sequenceFlow id="flow1" sourceRef="usertask2" targetRef="endevent1"></sequenceFlow>
    <sequenceFlow id="flow2" sourceRef="usertask3" targetRef="usertask2"></sequenceFlow>
    <sequenceFlow id="flow3" sourceRef="startevent1" targetRef="usertask3"></sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_myProcess">
    <bpmndi:BPMNPlane bpmnElement="myProcess" id="BPMNPlane_myProcess">
      <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
        <omgdc:Bounds height="35.0" width="35.0" x="170.0" y="220.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2">
        <omgdc:Bounds height="55.0" width="105.0" x="380.0" y="210.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="usertask3" id="BPMNShape_usertask3">
        <omgdc:Bounds height="55.0" width="105.0" x="240.0" y="210.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
        <omgdc:Bounds height="35.0" width="35.0" x="520.0" y="220.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
        <omgdi:waypoint x="485.0" y="237.0"></omgdi:waypoint>
        <omgdi:waypoint x="520.0" y="237.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
        <omgdi:waypoint x="345.0" y="237.0"></omgdi:waypoint>
        <omgdi:waypoint x="380.0" y="237.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
        <omgdi:waypoint x="205.0" y="237.0"></omgdi:waypoint>
        <omgdi:waypoint x="240.0" y="237.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

流程定义设计图:


Activiti配置文件:

<?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">
	
	<!-- Activiti的引擎配置管理器 -->
	<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
		<!-- 指定数据源 -->
		<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/activiti" />
		<property name="jdbcDriver" value="com.mysql.jdbc.Driver" />
		<property name="jdbcUsername" value="root" />
		<property name="jdbcPassword" value="root" />
		<property name="databaseSchemaUpdate" value="true" />
	</bean>
	
</beans>

程序运行结果:

log4j:WARN No appenders could be found for logger (org.activiti.engine.ProcessEngines).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
org.activiti.engine.impl.ProcessEngineImpl@11e32b6
第一个任务完成前,当前任务名称:Expense Request
第二个任务完成前,当前任务名称:Handle Request
流程结束后,查找任务:null

程序运行后数据库自动生成的28张表:





在 Spring Boot 3 中整合 Activiti 后,如果 `ProcessEngines.getDefaultProcessEngine()` 返回 `null`,通常是因为 **Activiti 的自动配置未正确初始化** 或 **Spring 上下文未正确加载 ProcessEngine**。以下是详细分析和解决方案: --- ### **1. 错误分析** #### **关键原因** 1. **未启用 Activiti 自动配置**: - Spring Boot 3 的自动配置可能未生效,导致 `ProcessEngine` 未创建。 2. **依赖缺失或版本冲突**: - Activiti 相关依赖未正确引入,或与 Spring Boot 3 不兼容。 3. **手动初始化冲突**: - 如果手动调用了 `ProcessEngines.init()` 或 `ProcessEngines.destroy()`,可能会干扰 Spring 的自动配置。 4. **配置缺失**: - 缺少必要的 Activiti 配置(如数据源、异步执行器等)。 #### **典型日志表现** - 无 `Activiti` 相关日志输出。 - `ProcessEngine` Bean 未被 Spring 容器管理。 --- ### **2. 解决方案** #### **方案 1:确保依赖正确** 在 `pom.xml` 中添加 **Activiti Spring Boot Starter**(兼容 Spring Boot 3): ```xml <dependency> <groupId>org.activiti</groupId> <artifactId>activiti-spring-boot-starter</artifactId> <version>7.1.0.M6</version> <!-- 或最新版本 --> </dependency> ``` **注意**: - 避免直接使用 `activiti-engine`,因为它不会自动集成 Spring。 - 检查依赖冲突(如 `spring-context`、`spring-tx` 版本)。 #### **方案 2:检查自动配置** 确保主类或配置类上有 `@EnableActiviti`(部分版本需要): ```java @SpringBootApplication @EnableActiviti // 如果存在该注解 public class MyApplication { public static void main(String[] args) { SpringApplication.run(MyApplication.class, args); } } ``` #### **方案 3:验证 ProcessEngine Bean** 通过 Spring 注入 `ProcessEngine`,而非直接调用 `ProcessEngines`: ```java @Autowired private ProcessEngine processEngine; // 由 Spring 管理 @Test void testProcessEngine() { assertNotNull(processEngine); // 验证 Bean 是否存在 System.out.println(processEngine.getName()); } ``` **为什么?** `ProcessEngines.getDefaultProcessEngine()` 是 Activiti 原生 API,而 Spring Boot 整合后应通过依赖注入获取。 #### **方案 4:检查数据源配置** Activiti 需要数据源(如 H2、MySQL)存储流程定义和历史数据。确保 `application.yml` 中配置了数据源: ```yaml spring: datasource: url: jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000 driver-class-name: org.h2.Driver username: sa password: activiti: database-schema-update: true # 自动创建表 ``` #### **方案 5:调试自动配置** 启用调试日志,检查 `ProcessEngine` 是否被创建: ```yaml logging: level: org.activiti: DEBUG org.springframework.boot.autoconfigure: DEBUG ``` 搜索日志中的关键信息: ```log DEBUG o.a.s.a.AbstractAutoConfiguration - Creating ProcessEngine with configuration DEBUG o.a.s.SpringProcessEngineConfiguration - Configuring ProcessEngine ``` #### **方案 6:排除冲突的自动配置** 如果存在多个 `DataSource` 或 `PlatformTransactionManager`,可能需要排除冲突: ```java @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class, // 如果使用自定义数据源 TransactionAutoConfiguration.class }) public class MyApplication { ... } ``` --- ### **3. 常见问题排查** #### **Q1:如何手动初始化 ProcessEngine?** 如果必须使用原生 API,可以在 Spring 初始化完成后手动初始化: ```java @Configuration public class ActivitiConfig { @Bean public ProcessEngine processEngine(DataSource dataSource, PlatformTransactionManager transactionManager) { SpringProcessEngineConfiguration config = new SpringProcessEngineConfiguration(); config.setDataSource(dataSource); config.setTransactionManager(transactionManager); config.setDatabaseSchemaUpdate("true"); return config.buildProcessEngine(); } } ``` 然后通过 `@Autowired` 注入 `ProcessEngine`。 #### **Q2:为什么 `ProcessEngines.init()` 无效?** - Spring Boot 会自动初始化 `ProcessEngine`,手动调用 `ProcessEngines.init()` 可能导致冲突。 - 确保没有在代码中显式调用 `ProcessEngines.destroy()`。 #### **Q3:如何验证 Activiti 表是否生成?** 检查数据库中是否存在以下表(以 H2 为例): ```sql SELECT * FROM ACT_RE_PROCDEF; -- 流程定义表 SELECT * FROM ACT_RU_TASK; -- 运行时任务表 ``` 如果表不存在,说明 `database-schema-update` 配置未生效。 #### **Q4:如何自定义 ProcessEngine 配置?** 通过 `SpringProcessEngineConfiguration` 覆盖默认配置: ```java @Bean public ProcessEngineConfiguration processEngineConfiguration( DataSource dataSource, PlatformTransactionManager transactionManager ) { SpringProcessEngineConfiguration config = new SpringProcessEngineConfiguration(); config.setDataSource(dataSource); config.setTransactionManager(transactionManager); config.setDatabaseSchemaUpdate("true"); config.setAsyncExecutorActivate(true); // 启用异步执行器 return config; } ``` --- ### **4. 完整示例** #### **配置类** ```java @Configuration @EnableTransactionManagement public class ActivitiConfig { @Bean public ProcessEngineConfiguration processEngineConfiguration( DataSource dataSource, PlatformTransactionManager transactionManager ) { SpringProcessEngineConfiguration config = new SpringProcessEngineConfiguration(); config.setDataSource(dataSource); config.setTransactionManager(transactionManager); config.setDatabaseSchemaUpdate("true"); config.setMailServerHost("localhost"); // 可选:邮件服务配置 return config; } } ``` #### **测试代码** ```java @SpringBootTest public class ProcessEngineTest { @Autowired private ProcessEngine processEngine; @Test void testProcessEngineNotNull() { assertNotNull(processEngine); RepositoryService repositoryService = processEngine.getRepositoryService(); assertNotNull(repositoryService); } } ``` --- ### **5. 总结** | 问题类型 | 解决方案 | 关键检查点 | |----------|----------|------------| | 依赖缺失 | 添加 `activiti-spring-boot-starter` | 检查 Maven 依赖树 | | 自动配置失败 | 启用 `@EnableActiviti` 或检查日志 | 搜索 `AbstractAutoConfiguration` 日志 | | 数据源问题 | 配置 `spring.datasource` 和 `spring.activiti` | 验证数据库连接和表生成 | | 手动初始化冲突 | 避免调用 `ProcessEngines.init()` | 使用 Spring 注入替代 | **推荐操作**: 1. **优先通过依赖注入获取 `ProcessEngine`**(而非 `ProcessEngines` API)。 2. **启用调试日志**,确认自动配置是否生效。 3. **检查数据库表**,验证 Activiti 是否成功初始化。 ---
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值