activiti 部署模型 提示空指针
activiti 版本为5.15.1
大致报错是这样的:
java.lang.NullPointerException
at org.activiti.bpmn.BpmnAutoLayout.generateSequenceFlowDiagramInterchangeElements(BpmnAutoLayout.java:315)
at org.activiti.bpmn.BpmnAutoLayout.generateDiagramInterchangeElements(BpmnAutoLayout.java:272)
at org.activiti.bpmn.BpmnAutoLayout.layout(BpmnAutoLayout.java:139)
at org.activiti.bpmn.BpmnAutoLayout.execute(BpmnAutoLayout.java:87)
at com.simple.activiti.test.bpm.BpmDefinitionTest.testDynamicDeploy(BpmDefinitionTest.java:168)
我得测试类代码:
----测试超类,运行可创建表
package com.simple.activiti.test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;
import org.springframework.transaction.annotation.Transactional;
/**
* 加载activiti的23张表的运行例子
* @author AnCan
*
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring-activiti.xml"})
@TransactionConfiguration(transactionManager="transactionManager", defaultRollback=false)
@Transactional
public class BaseTestCase extends AbstractTransactionalJUnit4SpringContextTests{
@Test
/**
* 运行此方法,加载activiti的数据库表信息
*/
public void test(){
System.out.println ("test");
}
}
---子测试类
package com.simple.activiti.test.bpm;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resource;
import org.activiti.bpmn.BpmnAutoLayout;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.EndEvent;
import org.activiti.bpmn.model.ExclusiveGateway;
import org.activiti.bpmn.model.FlowElement;
import org.activiti.bpmn.model.ImplementationType;
import org.activiti.bpmn.model.Process;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.bpmn.model.ServiceTask;
import org.activiti.bpmn.model.StartEvent;
import org.activiti.bpmn.model.UserTask;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.commons.io.FileUtils;
import org.junit.Assert;
import org.junit.Test;
import com.simple.activiti.test.BaseTestCase;
public class BpmDefinitionTest extends BaseTestCase{
@Resource
private RepositoryService repositoryService;
@Resource
private RuntimeService runtimeService;
@Resource
TaskService taskService;
@Test
public void testDeploy() throws IOException{
InputStream is=readXmlFile();
Assert.assertNotNull(is);
//发布流程
Deployment deployment=repositoryService.createDeployment().addInputStream("bpmn20.xml", is).name("holidayRequest").deploy();
Assert.assertNotNull(deployment);
System.out.println("deployId:" + deployment.getId());
//查询流程定义
ProcessDefinition processDefinition=repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).singleResult();
Long businessKey=new Double(1000000*Math.random()).longValue();
//启动流程
runtimeService.startProcessInstanceById(processDefinition.getId(),businessKey.toString());
//查询任务实例
List<Task> taskList=taskService.createTaskQuery().processDefinitionId(processDefinition.getId()).list();
Assert.assertNotNull(taskList==null);
Assert.assertTrue(taskList.size()>0);
for(Task task:taskList){
System.out.println("task name is " + task.getName() + " ,task key is " + task.getTaskDefinitionKey());
}
}
public InputStream readXmlFile() throws IOException{
String filePath="holidayRequest.bpmn";
return Class.class.getClass().getResource("/"+filePath).openStream();
}
@Test
public void testDynamicDeploy() throws Exception {
//创建bpmn模型
BpmnModel model = new BpmnModel();
org.activiti.bpmn.model.Process process = new org.activiti.bpmn.model.Process();
model.addProcess(process);
process.setId("my-process");
//创建bpmn元素
process.addFlowElement(createStartEvent());
process.addFlowElement(createUserTask("task1", "First task", "fred"));
process.addFlowElement(createUserTask("task2", "Second task", "john"));
process.addFlowElement(createEndEvent());
process.addFlowElement(createSequenceFlow("start", "task1"));
process.addFlowElement(createSequenceFlow("task1", "task2"));
process.addFlowElement(createSequenceFlow("task2", "end"));
// 2.生成BPMN自动布局
new BpmnAutoLayout(model).execute();
// 3. 部署这个BPMN模型
Deployment deployment = repositoryService.createDeployment()
.addBpmnModel("dynamic-model.bpmn", model).name("Dynamic process deployment")
.deploy();
// 4. 启动流程实例
ProcessInstance processInstance = runtimeService
.startProcessInstanceByKey("my-process");
// 5 发起任务
List<Task> tasks = taskService.createTaskQuery()
.processInstanceId(processInstance.getId()).list();
Assert.assertEquals(1, tasks.size());
Assert.assertEquals("First task", tasks.get(0).getName());
Assert.assertEquals("fred", tasks.get(0).getAssignee());
// 6. 保存bpmn流程图
InputStream processDiagram = repositoryService
.getProcessDiagram(processInstance.getProcessDefinitionId());
FileUtils.copyInputStreamToFile(processDiagram, new File("target/diagram.png"));
// 7. 保存为bpmn.xml的xml类型文件
InputStream processBpmn = repositoryService
.getResourceAsStream(deployment.getId(), "dynamic-model.bpmn");
FileUtils.copyInputStreamToFile(processBpmn,
new File("target/process.bpmn20.xml"));
}
@Test
public void testDynamicDeploy2() throws Exception {
System.out.println(".........start...");
// 1. Build up the model from scratch
BpmnModel model = new BpmnModel();
org.activiti.bpmn.model.Process process=new org.activiti.bpmn.model.Process();
model.addProcess(process);
final String PROCESSID ="process8888888888";
final String PROCESSNAME ="测试0100000";
process.setId(PROCESSID);
process.setName(PROCESSNAME);
process.addFlowElement(createStartEvent());
process.addFlowElement(createUserTask("task1", "节点01", "candidateGroup1"));
process.addFlowElement(createExclusiveGateway("createExclusiveGateway1"));
process.addFlowElement(createUserTask("task2", "节点02", "candidateGroup2"));
process.addFlowElement(createExclusiveGateway("createExclusiveGateway2"));
process.addFlowElement(createUserTask("task3", "节点03", "candidateGroup3"));
process.addFlowElement(createExclusiveGateway("createExclusiveGateway3"));
process.addFlowElement(createUserTask("task4", "节点04", "candidateGroup4"));
process.addFlowElement(createEndEvent());
process.addFlowElement(createSequenceFlow("startEvent", "task1", "", ""));
process.addFlowElement(createSequenceFlow("task1", "task2", "", ""));
//
process.addFlowElement(createSequenceFlow("task2", "createExclusiveGateway1"));
process.addFlowElement(createSequenceFlow("createExclusiveGateway1", "task1", "不通过", "${pass=='2'}"));
process.addFlowElement(createSequenceFlow("createExclusiveGateway1", "task3", "通过", "${pass=='1'}"));
process.addFlowElement(createSequenceFlow("task3", "createExclusiveGateway2"));
process.addFlowElement(createSequenceFlow("createExclusiveGateway2", "task2", "不通过", "${pass=='2'}"));
process.addFlowElement(createSequenceFlow("createExclusiveGateway2", "task4", "通过", "${pass=='1'}"));
process.addFlowElement(createSequenceFlow("task4", "createExclusiveGateway3"));
process.addFlowElement(createSequenceFlow("createExclusiveGateway3", "task3", "不通过", "${pass=='2'}"));
process.addFlowElement(createSequenceFlow("createExclusiveGateway3", "end", "通过", "${pass=='1'}"));
try {
// 2. Generate graphical information
new BpmnAutoLayout(model).execute();
} catch (Exception e) {
e.printStackTrace();
}
// 3. Deploy the process to the engine
Deployment deployment = repositoryService.createDeployment().addBpmnModel(PROCESSID+".bpmn", model).name(PROCESSID+"_deployment").deploy();
// 4. Start a process instance
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(PROCESSID);
// 5. Check if task is available
List<Task> tasks = taskService.createTaskQuery().processInstanceId(processInstance.getId()).list();
Assert.assertEquals(1, tasks.size());
// 6. Save process diagram to a file
InputStream processDiagram = repositoryService.getProcessDiagram(processInstance.getProcessDefinitionId());
FileUtils.copyInputStreamToFile(processDiagram, new File("target/"+PROCESSID+".png"));
// 7. Save resulting BPMN xml to a file
InputStream processBpmn = repositoryService.getResourceAsStream(deployment.getId(), PROCESSID+".bpmn");
FileUtils.copyInputStreamToFile(processBpmn,new File("target/"+PROCESSID+".bpmn.xml"));
System.out.println(".........end...");
}
//创建task
protected UserTask createUserTask(String id, String name, String assignee) {
UserTask userTask = new UserTask();
userTask.setName(name);
userTask.setId(id);
userTask.setAssignee(assignee);
List<String> candidateUsers = new ArrayList<String>();
candidateUsers.add("xiaoli");
candidateUsers.add("xiaoli1");
candidateUsers.add("xiaoli2");
candidateUsers.add("xiaoli3");
userTask.setCandidateUsers(candidateUsers);
return userTask;
}
//创建箭头
protected SequenceFlow createSequenceFlow(String from, String to) {
SequenceFlow flow = new SequenceFlow();
flow.setSourceRef(from);
flow.setTargetRef(to);
return flow;
}
protected StartEvent createStartEvent() {
StartEvent startEvent = new StartEvent();
startEvent.setId("start");
return startEvent;
}
/**
* 排他网关
*/
protected static ExclusiveGateway createExclusiveGateway(String id) {
ExclusiveGateway exclusiveGateway = new ExclusiveGateway();
exclusiveGateway.setId(id);
return exclusiveGateway;
}
protected EndEvent createEndEvent() {
EndEvent endEvent = new EndEvent();
endEvent.setId("end");
return endEvent;
}
/*连线*/
protected static SequenceFlow createSequenceFlow(String from, String to,String name,String conditionExpression) {
SequenceFlow flow = new SequenceFlow();
flow.setSourceRef(from);
flow.setTargetRef(to);
flow.setName(name);
if(null!=conditionExpression&&!"".equals(conditionExpression)){
flow.setConditionExpression(conditionExpression);
}
return flow;
}
protected FlowElement createServiceTask(String name){
ServiceTask stask = new ServiceTask();
stask.setId("sid");
stask.setName(name);
stask.setImplementation("activitiTest.PrintVariables");
String implementationType = ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION;
stask.setImplementationType(implementationType );
return stask;
}
}
我的activiti配置文件,只集成了spring,所以没有其他的配置文件,目录如下:
配置文件内容:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
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
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<!--
ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration();
//连接数据库的配置
processEngineConfiguration.setJdbcDriver("com.mysql.jdbc.Driver");
processEngineConfiguration.setJdbcUrl("jdbc:mysql://localhost:3306/itcast0711activiti?useUnicode=true&characterEncoding=utf8");
processEngineConfiguration.setJdbcUsername("root");
processEngineConfiguration.setJdbcPassword("root");
/**
public static final String DB_SCHEMA_UPDATE_FALSE = "false";不能自动创建表,需要表存在
public static final String DB_SCHEMA_UPDATE_CREATE_DROP = "create-drop";先删除表再创建表
public static final String DB_SCHEMA_UPDATE_TRUE = "true";如果表不存在,自动创建表
*/
processEngineConfiguration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
<!-- 连接数据的配置 -->
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/activiti?useUnicode=true&characterEncoding=utf8"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</bean>
<!-- 配置数据源事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/> <!-- 引用上面的数据源 -->
</bean>
<!-- 配置流程引擎配置类 注意:这是用 org.activiti.spring.SpringProcessEngineConfiguration 这个类-->
<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
<property name="dataSource" ref="dataSource"/>
<property name="transactionManager" ref="transactionManager" />
<property name="databaseSchemaUpdate" value="true" />
<property name="jobExecutorActivate" value="false" />
<property name="createDiagramOnDeploy" value="true" /> <!-- 是否生成流程定义图片 -->
<!-- 生成流程图的字体不设置会乱码 -->
<property name="activityFontName" value="宋体"/>
<property name="labelFontName" value="宋体"/>
</bean>
<!-- 配置流程引擎工厂 -->
<bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
<property name="processEngineConfiguration" ref="processEngineConfiguration" />
</bean>
<!-- 配置注入一些服务 -->
<bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService"/>
<bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService"/>
<bean id="taskService" factory-bean="processEngine" factory-method="getTaskService" />
<bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService" />
<bean id="managementService" factory-bean="processEngine" factory-method="getManagementService" />
</beans>
--------------为什么会报错,大家细看,完全是因为我大意,这一行 process.addFlowElement(createSequenceFlow("startEvent", "task1", "", "")); 就因为多谢了一个Event,导致我查了大半天。所以记下来。另外附带了解决activiti动态生成流程图的中文乱码问题。配置文件有注释。
---------------正确的开始和结束姿势应是这样的
process.addFlowElement(createSequenceFlow("start", "task1", "", ""));
process.addFlowElement(createSequenceFlow("createExclusiveGateway3", "end", "", ""));
------此例子也是动态生成流程文件的实例,希望对大家有帮助