jbpm_工作流框架笔记

1. 工作流基础

1.1. 工作流相关概念

工作流(Workflow),就是“业务过程的部分或整体在计算机应用环境下的自动化”,它主要解决的是“使在多个参与者之间按照某种预定义的规则传递文档、信息或任务的过程自动进行,从而实现某个预期的业务目标,或者促使此目标的实现”。

通俗的说,流程就是多个人在一起合作完成某件事情的步骤,把步骤变成计算机能理解的形式就是工作流。

 

 

工作流管理系统(WfMS,Workflow Management System)的主要功能是通过计算机技术的支持去定义、执行和管理工作流,协调工作流执行过程中工作之间以及群体成员之间的信息交互。工作流需要依靠工作流管理系统来实现。工作流管理系统是定义、创建、执行工作流的系统,应能提供以下三个方面的功能支持:

1. 定义工作流:包括具体的活动、规则等

2. 运行控制功能:在运行环境中管理工作流过程,对工作流过程中的活动进行调度

3. 运行交互功能:指在工作流运行中,WfMS与用户(活动的参与者)及外部应用程序工具交互的功能。

 

一、 定义工作流

二、 执行工作流

 

采用工作流管理系统的优点

1. 提高系统的柔性,适应业务流程的变化 

2. 实现更好的业务过程控制,提高顾客服务质量

3. 降低系统开发和维护成本

 

工作流框架有:Jbpm、OSWorkflow、ActiveBPEL、YAWL等

 

OA(办公自动化)主要技术之一就是工作流。

1.2. 开源工作流jBPM4.4介绍

jBPM 即java Business Process Management,是基于java的业务流程管理系统。jBPM是市面上相当流行的一款开源工作流引擎,引擎底层基于Active Diagram模型。jBPM4.4使用了hibernate(3.3.1版),因此可以很好的支持主流数据库。jBPM4.4共有18张表。

jBPM官方主页:http://www.jboss.org/jbpm

2. 准备jBPM4.4环境

2.1. jBPM4.4所需环境

jBPM requires a JDK (standard java) version 5 or higher. http://java.sun.com/javase/downloads/index.jsp 

To execute the ant scripts, you'll need apache ant version 1.7.0 or higher: http://ant.apache.org/bindownload.cgi

2.2. 下载相关资源

1, jBPM下载地址:http://sourceforge.net/projects/jbpm/files/

2, Eclipse下载地址( Eclipse IDE for Java EE Developers (163 MB),Version:3.5 ):http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/galileo

2.3. 安装流程设计器(GPD,Eclipse插件)

GPD(Graphical Process Designer)是一个Eclipse插件。

安装方法说明(jBPM4.4User Guide, 2.11.2. Install the GPD plugin into eclipse):

 Help --> Install New Software... 

 Click Add... 

 In dialog Add Site dialog, click Archive... 

 Navigate to install/src/gpd/jbpm-gpd-site.zip and click 'Open' 

 Clicking OK in the Add Site dialog will bring you back to the dialog 'Install' 

 Select the jPDL 4 GPD Update Site that has appeared 

 Click Next... and then Finish 

 Approve the license 

 Restart eclipse when that is asked

 

 

 

查看是否成功安装了插件:WindowàPreference中是否有Jboss jBPM项。

2.4. 在Eclipse中添加jPDL4.4 Schema校验

流程定义文件的xsd文件的路径为:JBPM_HOME/src/jpdl-4.4.xsd。

添加到Eclipse中的方法为(jBPM4.4 User Guide, 2.11.5. Adding jPDL 4 schema to the catalog):

 Click Window --> Preferences 

 Select XML --> XML Catalog 

 Click 'Add...' 

 The 'Add XML Catalog Entry' dialog opens 

 Click the button with the map-icon next to location and select 'File System...' 

 In the dialog that opens, select file jpdl-4.4.xsd in the src directory of the jBPM installation root. 

 Click 'Open' and close all the dialogs

 

2.5. 准备jBPM4.4的开发环境

2.5.1. 添加jBPM4.4的jar包

1. ${JBPM_HOME}/jbpm.jar(核心包)

2. JBPM_HOME/lib/*.jar,不添加以下jar包:servlet-api.jar, junit.jar。其中junit.jar一定不要添加,因为是3.8.2版本,与我们使用的junit4有冲突。

3. 所使用的数据库对应的驱动的jar包(第2步所添加的jar包中已包含mysql的jdbc驱动jar包)。

2.5.2. 添加并定制配置文件

1. 配置文件可以从JBPM_HOME/examples/src/中拷贝:
jbpm.cfg.xml、
logging.properties、
jbpm.hibernate.cfg.xml。

2. 修改logging.properties中的日志输出级别为WARNING: java.util.logging.ConsoleHandler.level=WARNING

3. 修改jbpm.hibernate.cfg.xml中的数据库连接信息。如果使用MySql,使用的方言一定要是org.hibernate.dialect.MySQL5InnoDBDialect。

4. 数据库连接编码一定要是UTF-8。否则可能会在部署含有中文字符的流程定义时会抛异常,说sql语法错误。

 

 

说明:如果要改变jbpm.hibernate.cfg.xml的文件名称,需要做:

1、从JBPM_HOME/src/中拷贝jbpm.tx.hibernate.cfg.xml放到工程的src/下,然后进行修改。

2、修改jbpm.tx.hibernate.cfg.xml中的hibernate主配置文件的路径配置(指定的是相对于classpath的相对路径)。

 

2.5.3. 初始化数据库

1, 方法一:执行sql脚本文件${JBPM4.4_HOME}/install/src/db/create/jbpm.*.create.sql

2, 方法二:使用Hibernate的自动建表,在jbpm.hibernate.cfg.xml中配置:hibernate.hbm2ddl.auto=update。

3. 核心概念与相关API(Service API)

3.1. 概念:Process definition, process instance ,  execution

3.1.1. Process definition

ProcessDefinition,流程定义:

一个流程的步骤说明。如一个请假流程、报销流程、借款流程等,是一个规则。

例:

 

3.1.2. Process instance

ProcessInstance,流程实例:

代表流程定义的一次执行。如张三昨天按请假流程请了一次假。一个流程实例包括了所有运行阶段, 其中最典型的属性就是跟踪当前节点的指针。

 

3.1.3. Execution

Execution,执行:

一般情况下,一个流程实例是一个执行树的根节点。 

使用树状结构的原因在于, 这一概念只有一条执行路径, 使用起来更简单。 业务API不需要了解流程实例和执行之间功能的区别。 因此, API里只有一个执行类型来引用流程实例和执行。

 

 

假设汇款和存档可以同时执行,那么主流程实例就包含了2个用来跟踪状态的子节点:

 

 

4.1. ProcessEngine与Service API

4.1.1. Configuration与ProcessEngine

Interacting with jBPM occurs through services. The service interfaces can be obtained from the ProcessEngine which is build from a Configuration. A ProcessEngine is thread safe and can be stored in a static member field.

 

使用默认的配置文件(jbpm.cfg.xml)生成Configuration并构建ProcessEngine:

ProcessEngine processEngine = new Configuration()

.buildProcessEngine();

或是使用如下代码获取使用默认配置文件的、单例的ProcessEngine对象:

ProcessEngine processEngine = Configuration.getProcessEngine();

或是使用指定的配置文件(要放到classPath下):

ProcessEngine processEngine = new Configuration()

      .setResource("my-own-configuration-file.xml")

      .buildProcessEngine();

 

4.1.2. jBPM Service API

jBPM所有的操作都是通过Service完成的,以下是获取Service的方式:

RepositoryService repositoryService = processEngine

.getRepositoryService();

ExecutionService executionService = processEngine

.getExecutionService();

TaskService taskService = processEngine

.getTaskService();

HistoryService historyService = processEngine

.getHistoryService();

ManagementService managementService = processEngine

.getManagementService();

 

各个Service的作用:

RepositoryService

管理流程定义

ExecutionService

管理执行的,包括启动、推进、删除Execution等操作

TaskService

管理任务的

HistoryService

历史管理(执行完的数据管理,主要是查询)

IdentityService

jBPM的用户、组管理

ManagementService

 

4.1.3. API风格

方法调用链

 

每一个方法都是流程有关的一个业务操作,默认是一个独立的事务。

4.1.4. 查询的有关API(风格)

功能说明

相应的查询API

查询“流程定义”

ProcessDefinitionQuery processDefinitionQuery = 

processEngine.getRepositoryService()

.createProcessDefinitionQuery();

查询“执行对象”

(流程实例)

ProcessInstanceQuery processInstanceQuery = 

processEngine.getExecutionService() //

.createProcessInstanceQuery();

查询“任务”

TaskQuery taskQuery = //

processEngine.getTaskService()//

.createTaskQuery();

查询“执行历史”

(流程实例历史)

HistoryProcessInstanceQuery historyProcessInstanceQuery = 

processEngine.getHistoryService()

.createHistoryProcessInstanceQuery();

查询“任务历史”

HistoryTaskQuery historyTaskQuery = 

processEngine.getHistoryService()

.createHistoryTaskQuery();

 

以上列出的Query对象有:

1. ProcessDefinitionQuery

2. ProcessInstanceQuery

3. TaskQuery

4. HistoryProcessInstanceQuery

5. HistoryTaskQuery

 

这些Query对象的使用方法都是一致的,如下所示:

1, 添加过滤条件:调用其中的有关方法指定条件即可。如:

a) processDefinitionQuery.processDefinitionKey("请假")是指定查询key为”请假”的流程定义;

b) taskQuery.assignee("张三")是指定办理人为”张三”的任务。

2, 添加排序条件:

a) 调用 xxQuery.orderAsc(property),表示按某属性升序排列

b) 调用 xxQuery.orderDesc(property),表示按某属性降序排列

c) 可指定多个排序条件,就是代表第1顺序,第2顺序…等。

d) 属性名在各自的Query对象(接口)中有常量定义,如:

i. ProcessDefinitionQuery.PROPERTY_ID

ii. ProcessDefinitionQuery.PROPERTY_KEY

iii. TaskQuery.PROPERTY_NAME

iv. TaskQuery.PROPERTY_ASSIGNEE

3, 指定分页有关信息:

a) 调用方法xxQuery.page(firstResult, maxResults);

b) 这是指定first与max的值(就是Hibernate中的Query.setFirstResult()与Query.setMaxResults())

c) 如果没有调用这个方法,代表要查询出符合条件的所有记录。

4, 查询得到结果:

a) 调用方法xxQuery.list(); 表示查询列表

b) 调用方法 xxQuery.uniqueResult(); 表示查询唯一的结果

c) 调用方法xxQuery.count(); 表示查询符合条件的记录数量

 

 

 

5. 管理流程定义

没有更新功能

5.1. 部署流程定义

注意区分Deployment与ProcessDefinition

5.1.1. 示例代码1:流程定义有关文件在classpath中

String deploymentId = processEngine.getRepositoryService()

.createDeployment()

.addResourceFromClasspath("process/test.jpdl.xml")

.addResourceFromClasspath("process/test.png")

.deploy();

5.1.2. 示例代码2:一次添加多个流程定义有关文件(要先打成zip包)

String deploymentId = processEngine.getRepositoryService()

.createDeployment()

.addResourcesFromZipInputStream(zipInputStream)

.deploy();

5.1.3. 说明

1, .addResourceFromClasspath(resource); 可以调用多次以添加多个文件。文件重复添加也不会报错。

2, .addResourceFromInputStream(resourceName, inputStream)添加一个文件(使用InputStream)

3, .addResourcesFromZipInputStream(zipInputStream)添加多个文件,里面也可以有文件夹。

4, 以上方法可以在一起调用。

 

5.2. 删除流程定义

5.2.1. 示例代码1:删除流程定义,如果有关联的流程实例信息则报错

repositoryService.deleteDeployment(deploymentId);

5.2.2. 示例代码2:删除流程定义,并删除关联的流程实例与历史信息

repositoryService.deleteDeploymentCascade(deploymentId);

5.3. 查询流程定义

5.3.1. 相关查询API说明:ProcessDefinitionQuery

RepositoryService.createProcessDefinitionQuery()

 

5.3.2. 示例代码1:查询所有流程定义

// 1,构建查询

ProcessDefinitionQuery pdQuery = processEngine.getRepositoryService() 

.createProcessDefinitionQuery()// 

.orderAsc(ProcessDefinitionQuery.PROPERTY_NAME)//

.orderDesc(ProcessDefinitionQuery.PROPERTY_VERSION);

 

// 2,查询出总数量与数据列表

long count = pdQuery.count();

List<ProcessDefinition> list = pdQuery.page(0, 100).list();// 分页:取出前100条记录

 

// 3,显示结果

System.out.println(count);

for (ProcessDefinition pd : list) {

System.out.println("id=" + pd.getId()//

+ ",deploymentId=" + pd.getDeploymentId()//

+ ",name=" + pd.getName()//

+ ",version=" + pd.getVersion()//

+ ",key=" + pd.getKey()); //

}

5.3.3. 示例代码2:查询所有最新版本的流程定义列表

// 1,查询,按version升序排序,则最大版本排在最后面

List<ProcessDefinition> all = processEngine.getRepositoryService()//

.createProcessDefinitionQuery()//

.orderAsc(ProcessDefinitionQuery.PROPERTY_VERSION)

.list();

// 2,过滤出所有不同Key的最新版本(因为最大版本在最后面)

Map<String, ProcessDefinition> map = new HashMap<String, ProcessDefinition>(); // map的key是流程定义的key,map的vlaue是流程定义对象

for (ProcessDefinition pd : all) {

map.put(pd.getKey(), pd);

}

Collection<ProcessDefinition> result = map.values();

// 3,显示结果

for (ProcessDefinition pd : result) {

System.out.println("deploymentId=" + pd.getDeploymentId()// 

+ ",\t id=" + pd.getId()// 流程定义的id,格式:{key}-{version}

+ ",\t name=" + pd.getName()

+ ",\t key=" + pd.getKey()

+ ",\t version=" + pd.getVersion());

}

5.4. 获取部署对象中的文件资源内容

// 资源的名称,就是 jbpm4_lob 表中的 NAME_ 列表值

String deploymentId = "90001";

String resourceName = "test.png"; 

InputStream in = processEngine.getRepositoryService()

.getResourceAsStream(deploymentId, resourceName);

5.5. 获取流程图中某活动的坐标

String processDefinitionId = "test-1"; // 流程定义的id

String activityName = "start1"; // 活动的名称

 

ActivityCoordinates c = processEngine.getRepositoryService()

.getActivityCoordinates(processDefinitionId, activityName);

System.out.println("x=" + c.getX() 

+ ",y=" + c.getY() 

+ ",width=" + c.getWidth() 

+ ",height=" + c.getHeight());

 

6. 执行流程实例

6.1. 启动流程实例

说明:流程实例创建后,直接就到开始活动后的第一个活动,不会在开始活动停留。

6.1.1. 示例代码1:使用指定key的最新版本的流程定义启动流程实例

ProcessInstance pi = processEngine.getExecutionService()

.startProcessInstanceByKey(processDefinitionKey);

6.1.2. 示例代码2:使用指定key的最新版本的流程定义启动流程实例,并设置一些流程变量

// 准备流程变量

Map<String, Object> variables = new HashMap<String, Object>();

variables.put("申请人", "张三");

variables.put("报销金额", 1000.00);

 

// 启动流程实例,并设置一些流程变量

ProcessInstance pi = processEngine.getExecutionService()

.startProcessInstanceByKey(processDefinitionKey, variables);

6.2. 向后执行一步(Signal)

6.2.1. 示例代码1:向后执行一步,使用唯一的outcome离开活动

processEngine.getExecutionService().signalExecutionById(executionId);

6.2.2. 示例代码2:向后执行一步,使用唯一的outcome离开活动,并设置一些流程变量

Map<String, Object> variables = new HashMap<String, Object>();

variables.put("审批结果", "同意");

 

processEngine.getExecutionService()

.signalExecutionById(executionId, variables);

 

6.2.3. 示例代码3:向后执行一步,使用指定的outcome离开活动

String outcome= "to end1";

processEngine.getExecutionService()

.signalExecutionById(executionId, outcome);

6.2.4. 示例代码4:向后执行一步,使用指定的outcome离开活动,并设置一些流程变量

String outcome= "to end1";

Map<String, Object> variables = new HashMap<String, Object>();

variables.put("审批结果", "同意");

processEngine.getExecutionService()

.signalExecutionById(executionId, outcome, variables);

 

6.3. 查询任务

6.3.1. 查询个人任务列表

方式1:TaskService.findPersonalTasks(userId);

 

方式2:List<Task> list = taskService.createTaskQuery()

.assignee(userId)

.list();

 

// 显示任务信息

for (Task task : taskList) {

System.out.println("id=" + task.getId()// 任务的id

+ ",name=" + task.getName()// 任务的名称

+ ",assignee=" + task.getAssignee()// 任务的办理人

+ ",createTime=" + task.getCreateTime() // 任务的创建(生成)的时间

+ ",executionId=" + task.getExecutionId());// 任务所属流程实例的id

}

6.3.2. 查询组任务列表

方式1: taskService.findGroupTasks(userId);

方式2: List<Task> list = processEngine.getTaskService()//

.createTaskQuery()//

.candidate(userId)//

.list();

6.4. 完成任务

6.4.1. 正常完成任务(也可以同时设置一些流程变量)

String taskId = "420001";

processEngine.getTaskService().completeTask(taskId);

processEngine.getTaskService().completeTask(taskId, outcome);

 

processEngine.getTaskService().completeTask(taskId, outcome, variables);

 

6.4.2. 自行控制任务完成后是否可向后流转

String taskId = "420001";

 

// 1,设置为false代表:办理完任务后不向后移动(默认为true)

TaskImpl taskImpl = (TaskImpl) processEngine

.getTaskService().getTask(taskId);

taskImpl.setSignalling(false); 

// 2,办理完任务

processEngine.getTaskService().completeTask(taskId);

6.5. 拾取任务

1, TaskService.takeTask(taskId, userId),拾取组任务到个人任务列表中,如果任务有assignee,则会抛异常。

2, processEngine.getTaskService().assignTask(taskId, userId),转交任务给其他人,(如果任务有assignee,则执行这个方法代表重新分配。也可以把assignee设为null表示组任务没有人办理了)

6.6. 设置与获取流程变量

6.6.1. 设置流程变量

6.6.1.1. 方式1:根据 executionId 设置或获取流程变量

ExecutionService.setVariable(executionId, name, value);

Object obj = executionService.getVariable(executionId, "请假人");

6.6.1.2. 方式2:根据 taskId 设置或获取流程变量

TaskService.setVariables(taskId, variables); // 一次设置多个变量

 

Object obj = executionService.getVariable(executionId, "请假人");

6.6.1.3. 流程变量所支持的值的类型(jBPM User Guide,7.2. Variable types)

7.2. Variable types

jBPM supports following Java types as process variables:

 java.lang.String 

 java.lang.Long 

 java.lang.Double 

 java.util.Date 

 java.lang.Boolean 

 java.lang.Character 

 java.lang.Byte 

 java.lang.Short 

 java.lang.Integer 

 java.lang.Float 

 byte[] (byte array) 

 char[] (char array) 

 hibernate entity with a long id 

 hibernate entity with a string id 

 serializable

For persistence of these variable, the type of the variable is checked in the order of this list. The first match will determine how the variable is stored. 

6.7. 直接结束流程实例(自己手工结束)

String processInstanceId = "test.10001";

processEngine.getExecutionService()

.endProcessInstance(processInstanceId, ProcessInstance.STATE_ENDED);

7. jBPM4.4的流程定义语言(设计流程)

7.1. process(流程)

是.jpdl.xml的根元素,可以指定的属性有:

属性名

作用说明

name

流程定义的名称,用于显示。

key

流程定义的key,用于查询。

如未指定,则默认为name的值。

version

版本,如果指定,则不能与已有的流程定义的版本重复;如未指定,则此key的流程定义的第1个为版本1,以后的是版本递增(每次加1)

  

 

7.2. transition(连线、转移)

1, 一个活动中可以指定一个或多个Transition(Start中只能有一个,End中没有)。

a) 开始活动中只能有一个Transition。

b) 结束活动中没有Transition。

c) 其他活动中有1条或多条Transition

2, 如果只有一个,则可以不指定名称(名称是null);如果有多个,则要分别指定唯一的名称。

7.3. 流转控制活动

7.3.1. start(开始活动)

代表流程的开始边界,一个流程有且只能有一个Start活动。开始活动只能指定一个Transition。在流程实例启动后,会自动的使用这个唯一的Transition离开开始活动,到一下个活动。

7.3.2. end、end-error、end-cancel(结束活动)

代表流程的结束边界,可以有多个,也可以没有。如果有多个,则到达任一个结束活动,整个流程就都结束了;如果没有,则到达最后那个没有Transition的活动,流程就结束了。

7.3.3. state(状态活动)

功能:等待。

7.3.4. task(任务活动)

分配任务:

1, actor=#{String型的变量}

2, AssignmentHandler,需要在<task>元素中写<assignment-handler class="AssignmentHandlerImpl"/>子元素。

a) 指定的类要实现AssignmentHandler接口

b) 在其中可以使用Assignable.setAssignee(String),分配个人任务。

 

7.3.5. decision(判断活动)

1,使用expression,如:expr="#{'to state2'}"

2,使用Handler,要实现DecisionHandler接口

3,如果同时配置了expression与Handler,则expression有效,忽略Handler。

 

7.3.6. fork、join(分支/聚合活动)

这是多个分支并行(同时)执行的,并且所有的分支Execution都到Join活动后才离向后执行。

7.4. 自定义活动(Custom)

1,在<custom>元素中指定class属性为指定的类。

2,这个类要实现ExternalActivityBehaviour接口,其中有两个方法:

1,execute(ActivityExecution),节点的功能代码

2,signal(ActivityExecution, String, Map),在当前节点等待时,外部发信号时的行为

3,在execute()方法中,可以调用以下方法对流程进行控制

1,ActivityExecution.waitForSignal(),在当前节点等待。

2,ActivityExecution.takeDefaultTransition(),使用默认的Transition离开,当前节点中定义的第一个为默认的。

3,ActivityExecution.take(String transitionName),使用指定的Transition离开

4,ActivityExecution.end(),结束流程实例

4,也可以实现ActivityBehaviour接口,只有一个方法execute(ActivityExecution),这样就不能等待,否则signal时会有类转换异常。

 

7.5. 事件

1, 在根元素中,或在节点元素中,使用<on event="">元素指定事件,其中event属性代表事件的类型。

2, 在<on>中用子元素<event-listener class="EventListenerImpl" />,指定处理的类,要求指定的类要实现EventListener接口

3,  事件类型:

a) <on>元素放在根元素(<process>)中,可以指定event为start或end,表示流程的开始与结束。

b) <on>元素放在节点元素中,可以指定event为start或end,表示节点的进入与离开

c) 在Start节点中只有end事件,在End节点中只有start事件。

d) 在<transition>元素中直接写<event-listener class="">,就是配置事件。(因为在这里只有一个事件,所以不用写on与类型)

e) 在<task>元素中还可以配置assign事件,是在分配任务时触发的。

 

8. jBPM4.4应用

8.1. 与Spring集成(jBPM4.4 Developers Guide, Chapter 17. Spring Integration)

8.1.1. 在jbpm.cfg.xml中

1,删除配置:<import resource="jbpm.tx.hibernate.cfg.xml" />

2,增加配置:<import resource="jbpm.tx.spring.cfg.xml" />

8.1.2. 在applicationContext.xml中配置

<!-- 配置ProcessEngine(整合jBPM4) -->

<!-- jbpmCfg是相对于classpath的相对路径,默认值为jbpm.cfg.xml -->

<bean id="springHelper" 

class="org.jbpm.pvm.internal.processengine.SpringHelper">

<property name="jbpmCfg" value="jbpm.cfg.xml"></property>

</bean>

<bean id="processEngine" factory-bean="springHelper" 

factory-method="createProcessEngine" />

8.1.3. 测试

@Test // 测试ProcessEngine

public void testProcessEngine() {

ProcessEngine processEngine = (ProcessEngine)ac.getBean("processEngine");

Assert.assertNotNull(processEngine);

}

 

8.1.4. 注意事项

如果做了JBPM4.4与Spring整合(使用了jbpm.tx.spring.cfg.xml),则在程序中就一定要使用Spring注入ProcessEngine,千万不能使用Configuration.getProcessEngine()生成ProcessEngine,因为这时内部的代码有以下逻辑:如果整合了Spring但没有ApplicationContext,就默认读取applicationContext.xml创建ApplicationContext实例并从中获取名为”ProcessEngine”的对象。而这时如果把pe = Configuration.getProcessEngine()写成某Spring中管理的bean的初始化代码,就会有无限循环,不停的创建ApplicationContext了!

8.2. 自行控制事务

1, 修改 jbpm.tx.hibernate.cfg.xml

a) 不让jBPM自行管理事务:去掉<standard-transaction-interceptor />

b) 让Jbpm使用SessionFactory.getCurrentSession():修改为 <hibernate-session current="true" />

2, 配置可以使用SessionFactory.getCurrentSession(),在jbpm.hibernate.cfg.xml 中配置:<property name="hibernate.current_session_context_class">thread</property>

3, 要使用同一个SessionFactory,且都要使用 SessionFactory.getCurrentSession() 获取 Session:

a) 同一个SessionFactory:SessionFactory sf = processEngine.get(SessionFactory.class)

b) 在 BaseDaoImpl 中增加:

i. getSession() { return HibernateUtils.getSessionFactory().getCurrentSession(); }

ii. getProcessEngine(){ return org.jbpm.api.Configuration.getProcessEngine(); }

4, 统一的打开与提交或回滚事务:使用 OpenSessionInViewFilter 控制事务。

 

8.3. 启动Tomcat后,访问JSP时(使用的是MyEclipse自带的Tomcat,是6.0的版本),报错:   Caused by: java.lang.LinkageError: loader constraints violated when linking javax/el/ExpressionFactory class

at org.apache.jsp.WEB_002dINF.jsp.UserAction.loginUI_jsp._jspInit(loginUI_jsp.java:39)

at org.apache.jasper.runtime.HttpJspBase.init(HttpJspBase.java:52)

at org.apache.jasper.servlet.JspServletWrapper.getServlet(JspServletWrapper.java:159)

at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:329)

at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:320)

at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266)

... 40 more

 

说明:原因是Jbpm的juel.jar, juel-engine.jar, juel-impl.jar包和Tomcat6.0中的el-api.jar包冲突了。

有三个解决办法:

1,方法一:在MyEclipse的Preferences -> MyEclipse -> Application Servers -> Tomcat -> .. -> Paths 中配置 Append to classpath,选中 juel.jar, juel-engine.jar, juel-impl.jar 这三个jar包就可以了。

2,方法二:将 juel.jar, juel-engine.jar, juel-impl.jar 这三个包复制到tomcat6下 lib/ 中,并删除原来的el-api.jar,

切记还要把工程中 WEB-INF\lib 下的 juel.jar, juel-engine.jar, juel-impl.jar 删除,不然还是要冲突。

3,方法三:换成tomcat5.5,就没有问题了。

 

8.4. 完成流程实例中的最后一个任务时报错(任务实例结束时),或删除流程定义级联删除流程实例时,报错如下:

com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (`itcastoa_20100909/jbpm4_execution`, CONSTRAINT `FK_EXEC_INSTANCE` FOREIGN KEY (`INSTANCE_`) REFERENCES `jbpm4_execution` (`DBID_`))

 

解决办法:把方言设为 MySQL5InnoDBDialect,不能是 MySQLDialect。

JBOSS jBPM 工作流管理系统简介 jBPM,全称是Java Business Process Management,是一种基于J2EE的轻量级工作流管理系统。jBPM是公开源代码项目,它使用要遵循 Apache License。jBPM在2004年10月18日,发布了2.0版本,并在同一天加入了JBoss,成为了JBoss企业中间件平台的一个组成部分,它的名称也改成JBoss jBPM。随着jBPM加入JBoss组织,jBPM也将 阅读详情

相关推荐

jupyter-workflow:使用Jupyter Notebook进行分布式工作流设计和执行

Jupyter工作流程 Jupyter Workflow框架使Jupyter Notebooks能够描述复杂的工作流程,并在混合HPC-Cloud基础架构上以分布式方式执行它们。 Jupyter Workflow依靠 WMS作为其底层运行时支持。 安装Jupyter工作流程 Jupyter Workflow IPython内核在上可用,因此您可以使用pip进行安装。 pip install jupyter-workflow 然后,您可以通过运行以下命令将其安装在Jupyter Notebook服务器上。 python -m jupyter_workflow.ipython.install 请注意,Jupyter Workflow需要python >= 3.8 。 然后,您可以将Jupyter Notebook与新安装的内核关联。 可以在的examples文件夹下找到一些示例。 Ju

Acticiti中startProcessInstanceByKey方法在variable表中的如何存储

在varinst中存储的方式为如下图所示,从下图得知activiti将list集合类型的数据序列化到。当JAVA类中存在如下类型的属性如List等引用类型。发起流程时,需要将业务数据存入。

qq_31745863的博客 5066

U2Net网络实战:从原理到代码实现(附背景去除应用)

本文深入解析了U2Net网络的原理与代码实现,重点剖析了其独特的嵌套U型结构(RSU模块)和显著图融合机制。通过实战演示,指导读者如何加载预训练模型并应用于精准的图像背景去除任务,为电商、摄影等领域提供高效的自动化抠图解决方案。

nn3456的博客 491

Activiti启动流程实例,runtimeService.startProcessInstanceByKey

/** * 启动流程实例,添加进businessKey * * 本质:act_ru_execution表中的businessKey的字段要存入业务标识 */ public class BusinessKeyAdd { public static void main(String[] args) { //1.得到ProcessEngine对象 ProcessEngine processEngine = ProcessEngines.getDefaultP

可控的事情要谨慎,不可控的事情要乐观。 1万+

深入解析SOC芯片设计中DFT OCC与ATPG的协同优化策略

本文深入探讨了在复杂SOC芯片设计中,DFT(可测试性设计)的核心组件OCC(片上时钟控制器)与ATPG(自动测试向量生成)的协同优化策略。文章从基本原理出发,分析了OCC作为测试时钟管理者的关键作用,以及ATPG作为故障检测引擎的工作机制,并重点阐述了二者在测试架构选择、参数对齐、低功耗测试等场景下的协同方法与实战技巧,旨在实现更高的测试覆盖率与更低的测试成本。

efc123456的博客 1035

【亲测好用】解决Windows系统Vscode终端无法使用yarn报错无法加载文件

我明明使用`npm i -g yarn ` 安装成功了 甚至在文件夹处 CMD 也可以看到yarn 的版本 甚至在Vscode中又重新安装了一遍yarn 为什么还是报错呢?

Aeporn的博客 888

flowable流程实例笔记(1)

RuntimeService 运行服务类 支持启动的方式 流程定义: 从这里获取资源文件. 执行实例: 流程实例中执行的每个环节. 流程实例: 一个流程实例包括所有运行的节点,一个流程中流程实例只有一个. 启动一个实例: public void startProcessInstanceByKey() { ...

weixin_42310146的博客 4874

基于深度学习的AI生成式人脸图像鉴别

AIGC(AI内容生成)技术的快速发展确实为创作者提供了高效生产力工具,但同时也引发了一些问题和挑战。这些技术可以生成以假乱真的图像、视频换脸等,给不法分子提供了滥用的机会。其中,一些不法分子可能利用AIGC技术制造虚假新闻、违反版权、绕过活体身份验证、散布谣言和诽谤他人、进行敲诈勒索等非法活动,以谋取不当利益。这些行为给社会造成了严重的负面影响,破坏了信息的真实性和可信度。因此,我们需要认识到AIGC技术的潜在风险,并采取相应的措施来应对。

mingo_敏 4498

学习 activiti_Service(二)RuntimeService

activiti 版本号 7.0.0.SR1 一、API /** * 创建一个{@link ProcessInstanceBuilder},它允许设置启动流程实例的各种选项,作为各种startProcessInstanceByXX方法的替代方法. */ ProcessInstanceBuilder createProcessInstanceBuilder(); /** * 使用给定的键在最新版本的流程定义中启动新的流程实例. * * @param p.

PiP虾 快跑 快跑 1142

【ComfyUI】Wan2.2 Rapid-AIO-Mega 二次元文生视频

通过 SD3 采样体系与 Wan 系列专用的 **WanVaceToVideo** 视频生成节点,整个流程从模型加载、文案编码、潜空间采样到视频合成一气呵成,能够稳定输出画面精致、角色统一、光影氛围鲜明的动态画面。这套工作流重点整合了视频长度、帧率、分辨率等核心参数控制,并结合 KSampler 的细节生成能力,旨在让用户能在 ComfyUI 中快速生成高质量的二次元叙事视频。

Mr数据杨 1987

第一百三十九回 介绍三个BLE包

本章回中主要介绍了Flutter中BLE的概念和操作方法,主要介绍了三个BLE包的功能和差异,以方便大家在BLE操作中选择不同的包。

talk_8的专栏 574

activiti之通过key发起流程的问题

若流程定义processDefinition定义了tenantId,则必须使用:startProcessInstanceByKeyAndTenantId进行流程发起,不能直接使用 startProcessInstanceByKey,否则会报:no processes deployed with key的问题 ...

weixin_39102174的博客 3518

6-Halcon-- var_threshold 函数功能(用于基于局部统计特性的动态阈值分割的算子)

var_threshold 是 HALCON 中用于基于局部统计特性的动态阈值分割的算子,特别适用于处理低对比度图像或纹理均匀但包含细微差异的场景。与 dyn_threshold 不同,它不依赖预处理生成的参考图像,而是直接在局部区域内计算灰度值的统计特性(均值和标准差),从而自适应调整阈值。

weixin_45590420的博客 1328

JAVA的jBPM工作流框架

工作流(Workflow)是指将一个工作过程分解成一系列有序的任务、活动或操作,并定义它们之间的关系和依赖,以实现对工作流程的管理、控制和优化。在 Java 中,工作流通常是指使用 Java 技术来实现和管理工作流程的系统或框架。工作流 Java 可以用于管理和自动化各种类型的业务流程,如审批流程、订单处理流程、报销流程等。它可以帮助组织和企业实现业务流程的自动化、标准化和优化,提高工作效率和质量。

m0_65037354的博客 3490

基于深度学习的心律失常的自动分类

基于深度学习的心律失常的自动分类 作者:禅与计算机程序设计艺术 1. 背景介绍 1.1 心律失常的危害与检测的重要性 心律失常是一种常见的心血管疾病,严重威胁着人们的健康和生命。据统计,全球每年有数百万人因心律失

AI架构师小马 1148

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

工作流JBPM笔记:了解JBPM

JBPM,全称是Java Business Process Management(业务流程管理),它是覆盖了业务流程管理、工作流、服务协作等领域的一个开源的、灵活的、易扩展的可执行流程语言框架。jBPM是公开源代码项目,使用它要遵循 ASL(Apache License Version 2.0)和EULA(JBoss End User License Agreement)协议。

一个老码农 2214

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

工作流 jbpm概述

JBPM(Java Business Process Model)是一个开源的基于 Java 的工作流引擎,用于管理业务流程和决策逻辑。它允许开发人员创建、执行和管理业务流程,从而提高组织的效率和灵活性。

莫等闲 白了少年头 空悲切 1310

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

JBPM工作流

1.     概要jBPM,全称是Java Business Process Management,是一种基于J2EE的轻量级工作流管理系统。JBPM也是一款非常好的开源工作流引擎。现在这里从技术角度来分析jbpm的优点和缺点,简单罗列几个大家都容易看见的:2.优点a.       自带工作流引擎,思路清晰,编写代码减少;b.       采用JBPL语言建立工作流程图,可方便

hitlermen的专栏 6410

什么是JBPM工作流

1 什么是工作流 BPM,全称是Java Business Process Management(业务流程管理),它是覆盖了业务流程管理、工作流、服务协作等领域的一个开源的、灵活的、易扩展的可执行流程语言框架。jBPM是公开源代码项目,使用它要遵循 ASL(Apache License Version 2.0)和EULA(JBoss End User License Agreement)协议。 ...

Nice118的博客 2216

java jbpm工作流_jbpm工作流

一、JBPM(java business process manager)1、工作流管理流程O--->定义工作流(使用流程设计器生成,png和xml文件,分别面向用户和系统)--->执行工作流(核心对象:流程引擎ProcessEngine)--->连接数据库(jbpm18张表,jbpm4_deploymen,jbpm4_deployprop,jbpm4_execution,jbp...

weixin_33464488的博客 1362

常见的工作流框架 Activity JBPM

常用工作流框架有Activity、JBPM、OSWorkFlow、WorkFlow 一、BPMN2.0规范 BPMN(Business Process Model and Notation)--业务流程模型与符号。 BPMN是一套流程建模的标准,主要目标是被所有业务用户容易理解的符号,支持从创建流程轮廓的业务分析到这些流程的最终实现,知道最终用户的管理监控。 通俗一点其实就是一套规范,画流程模型的规范。流程模型包括:流程图、协作图、编排图、会话图。详细信息请google。 Activi..

ejinxian的专栏 2020

宅急送 项目第八天 JBPM工作流框架

项目第八天和项目第九天 学习 JBPM 理论部分 项目第十天 权限管理模块 项目第十一天 项目第十二天 JBPM 应用 1. 工作流框架概述1.1. 什么是工作流工作流(Workflow),就是“业务过程的部分或整体在计算机应用环境下的自动化” 工作流技术 是 OA 系统中最关键的一环 !!! 简单的说,就是将工作的流程通过程序管理起来,以表单审核和任务办理为主体,实现办公自动化工作流开发

优快云_AF的博客 2047

jbpm工作流

前言       之前做.net的时候,工作流用过.net的workflow。在java中,用到的工作流框架有Jbpm、OSWorkflow、ActiveBPEL、YAWL等,下面就简单介绍一下Jbpm框架实现的工作流。   工作流       工作流就是业务过程的部分或整体在计算机应用环境下的自动化,它主要解决的是使在多个参与者之间按照某种预定义的规则传递文档、信息或任务的过程自动进...

Coder Yasmine 1519
上一篇: Apache + Tomcat 负载均衡及Session绑定的实现
下一篇: 如何恢复被破坏的PowerDesigner pdm文件
yufei_java
博客等级 码龄10年 18粉丝 60原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值