您的位置:首页 > 产品设计 > 产品经理

jBPM开发入门指南(3)

2009-03-20 15:17 351 查看



5

 安装

jBPM



Eclipse

开发插件

有个辅助工具开发起来方便一点,只不过现在
jBPM
的开发工具插件功能还不算太强,也就一个“项目创建向导”的功能,让你:

(1)不用再去配置
classpath
库的引用了

(2)直接得到了一个
jBPM
的项目初始结构

其实吧,开发
jBPM
也不需要什么插件工具,在熟练了以后,库引用了项目初始结构都可以手工创建。

插件不用再去下载了,
jbpm-starters-kit-3.1.1
包里就有,目录地址如下:

D:/jbpm-starters-kit-3.1.1/jbpm-designer/jbpm-gpd-feature/eclipse

,插件的安装方式是链接式还是直接复制式,任选吧。不懂的就去看看《
Eclipse
从入门精通》这本书,在前面章节都有讲到。另外,注明一下
Eclipse
的版本我是用
3.2
,插件和
Eclispe
版本相关的,要注意了。

如果安装成功,则
Eclipse
首选项里多了一个
JBoss jBPM
,另外我们也需要到这个
jBPM
的首选项里做一些配置工作――指定
jBPM
的安装路径(如下图所示)。这个配置主要是为了找到
jbpm
下的各种
jar
包,好让
Eclipse
设置项目的库引用。本文指向路径是
d:/jbpm-starters-kit-3.1.1/jbpm.3





6

 

jBPM



Hello World



6.1 新建jBPM项目

主菜单“文件->新建->项目”,在弹出的对话框里,有“
Process Project
”项,如下图所示:



选上好,单击“下一步”,起个名“
myjbpm
”,然后就可以单击“完成”了。然后就生成了如下图所示的一个项目结构:



这个项目和通常
Eclipse
的项目结构有点不同,不过这是一个现在非常流行的项目结构,
src/java
存放源文件,
test/java
存放相应的
JUnit
单元测试代码。如果你用
Maven
来编译构建项目,对这种目录结构一定不陌生。

项目创建起了,介绍一下里面的文件吧:

l

MessageActionHandler
,自动生成的一个
ActionHandler
。不想要可以删掉。

l

ehcache.xml cache
的配置文件,里面有很详解的英文说明。没有必要可以不用改它。

l

hibernate.cfg.xml
 
jBPM
是用
Hibernate
进行工作流的数据存储的,这个就是
Hibernate
的配置文件。后面我们将讲到如何配置这个文件。

l

jbpm.cfg.xml
 
jbpm
本身的配置文件。现在是空的,它用的是缺省配置,你想知道有哪些配置就去看这个文件
D:/jbpm-starters-kit-3.1.1/jbpm.3/src/java.jbpm/org/jbpm/default.jbpm.cfg.xml

l

log4j.properties
 这个是日志
API

log4j
的配置文件,用过
log4j
的都知道。

l

SimpleProcessTest.java
 这个是对最重要的流程配置文件的
processdefinition.xml
单元测试代码。这里表扬一点,
jBPM
的优良设计使得它的可测试性非常之高,喜欢写
t
单元测试的人有福了。

l

gpd.xml
 用于生成流程图的定义文件。都是一些方框的坐标和长宽

l

processdefinition.xml
 这个是对最重要的流程配置文件,以后写流程要经常和它打交道。

l

processimage.jpg
 一个流程图

从项目结构来看,我们没有看到
JSP
网页程序,也没有看到
GUI
客户端程序,这些代码都是要我们以后开发中来写的。但本文不准备用
JSP

GUI

Swing

SWT
)来做示例,而是用
JUnit
代码来做使用
jBPM
客户端来演示。因为
jBPM
实际上是一个后台框架,至于前台是
JSP
还是
Swing
还是无界面的
java.class
都是无关紧要的。在教程里用无界面的
java.class
来做客户端则更方便一些,如果进一步采用
JUnit
,则这样的
java.class
同时还具备了单元测试的功能。以后就是用
JSP
写了
WEB
页面,我们还是可以用这些
JUnit
程序来做单元测试,避免了频繁的鼠标点按
WEB
页面这样的力气活。所以在
jBPM
自带的英文教程里都是一个
JUnit
程序,不仔佃看还真摸不着头脑。



6.2 修改hibernate.cfg.xml

hibernate.cfg.xml
的默认设置是用
HSQL
,这是一个内存数据库,这种内存数据库用来代替项目实际所用的数据库来做单元测试挺不错的。不过我们这里是要试试用
MySQL

Oracle
,那就改一下设置吧。

注:配置值可参考
D:/jbpm-starters-kit-3.1.1/jbpm-db
对应子目录下的
hibernate.properties
文件。

1

MySQL
的更改如下:

<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>

<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>

<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/jbpm</property>

<property name="hibernate.connection.username">root</property>

<property name="hibernate.connection.password">123456</property>

2

Oracle
的更改如下:

<property name="hibernate.dialect">org.hibernate.dialect.OracleDialect</property>

<property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>

<property name="hibernate.connection.url">jdbc:oracle:thin:@192.168.123.10:1521:wxxrDB</property>

<property name="hibernate.connection.username">chengang</property>

<property name="hibernate.connection.password">chengang</property>

如果你装了
Oracle
的客户端,并且
D:/oracle/ora92/network/ADMIN/tnsnames.ora
里做了如下的设置

WXXRDB_192.168.123.10 =

(DESCRIPTION =

(ADDRESS_LIST =

(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.123.10)(PORT = 1521))

)

(CONNECT_DATA =

(SID = wxxrDB)

(SERVER = DEDICATED)

)

)


Oracle

hibernate.connection.url
项也可以设为:
jdbc:oracle:oci:@WXXRDB_192.168.123.10



6.3 完善库引用

虽然
jBPM
在创建项目之初给我们设置好了库引用,如下图



但后面运行时还是报一些
NoClassDefFoundError
异常,如没有对
hibernate3.jar
的引用导致下面的错误

java.lang.NoClassDefFoundError: org/hibernate/Session

at org.jbpm.persistence.db.DbPersistenceServiceFactory.openService(DbPersistenceServiceFactory.java:55)

at org.jbpm.svc.Services.getService(Services.java:136)

.......

所以我们要为本文的实例完善库引用。主要是把
MySQL

Oracle

JDBC
库、以及
Hibernate

hibernate3.jar
加入到项目的库引用中。

(1)

找到缺少的
jar


l

mysql

jdbc
包,在
D:/jbpm-starters-kit-3.1.1/jbpm-db/mysql/lib
目录里

l

oracle

jdbc
包,
jbmp
中没有包含(可能是没拿到
oracle
授权),我们可以自已去
oracle
网站上下载,或者去
oracle
安装目录
D:/oracle/ora92/jdbc/lib

ojdbc14.jar
(我们公司用的是
Oracle9i


l

Hibernate3.jar
在目录
D:/jbpm-starters-kit-3.1.1/jbpm.3/lib/hibernate
里。

(2)

在项目里创建一个
lib
目录,将这三个
jar
复制到
lib
目录。

(3)

如下图设置三
jar
包的库引用





6.4 开始HellorWorld

这里是一个很简单的请假流程,请假人提交假单给经理审批,经理审批后结束。要说明的是,这个流程并不严谨,比如经理不通过流程应该到哪?不过这并不防碍拿它来做示例,螃蟹还得一个一个的吃。我们先拿这一杆子捅到底的流程做一个最简单的示例,从整体上对
jBPM
工作流开发有概念先。然后我们再慢慢丰富。

1
、定义流程

流程的定义文件是
processdefinition.xml
,这个是一个关键文件,
jBPM
的很大一部份内容都是关于它的。在这里我们把原来自动生成的内容,稍做改动:

<?xml version="1.0" encoding="GBK"?>

<process-definition xmlns="urn:jbpm.org:jpdl-3.1" name="helloworld">

<!--

申请

-->

<start-state name="request">

<task>

<controller>

<variable name="name" />

<variable name="day" />

<variable name="note" />

</controller>

</task>

<!--

流程转向

-->

<transition name="to_confirm" to="confirm">

<action name="requestAction"

class
="cn.com.chengang.jbpm.RequestAction">

<reason>

我要请假

</reason>

</action>

</transition>

</start-state>

<!--

审批

-->

<state name="confirm">

<transition name="to_end" to="end">

<action name="finishAction"

class
="cn.com.chengang.jbpm.ConfirmAction" />

</transition>

</state>

<!--

结束

-->

<end-state name="end" />

</process-definition>

说明:

流程的名称改成了
helloworld
。(呵呵,也就是这里和
helloworld
有关了)

<controller>
标签定义了三个数据:姓名、请假天数、说明。

<transition>
标签定了
request
节点的一个流程转向,这里是转到
confirm
节点。

<action>
标签定义了流程由一个节点转到另一个节点时,所要执行的动作,动作封装在一个
ActionHandler
类中。比如这里当
request

confirm
结点时将执行
RequestAction
类的
execute
方法。

FinishAction
下面还有一个
<reason>
(请假理由),它对应于
FinshAction
的属性
String reason


2
、 编写
ActionHandler

在上面
processdefinition.xml
里我们定义了两个
ActionHandler

RequestAction

ConfirmAction
。其代码如下:


package

cn.com.chengang.jbpm;


import

org.jbpm.graph.def.ActionHandler;


import

org.jbpm.graph.exe.ExecutionContext;


public



class
RequestAction implements ActionHandler {

private
static
final
long

serialVersionUID
= 1L;


private
String reason;


public
String getReason() {

return
reason;

}


public


void
setReason(String reason) {


this
.reason = reason;

}


public


void
execute(ExecutionContext context) throws Exception {

context.getContextInstance().setVariable("note", reason);

}

}

说明:
ExecutionContext
是一个贯通流程的容器。它是个大宝箱,里面啥玩意都有,后面将更深入的提到。这里的
reasion
就是
processdefinition.xml
中的

我要请假



package

cn.com.chengang.jbpm;


import

org.jbpm.graph.def.ActionHandler;


import

org.jbpm.graph.exe.ExecutionContext;


public



class
ConfirmAction implements ActionHandler {


private



static



final



long


serialVersionUID

= 1L;


public


void
execute(ExecutionContext context) throws Exception {

context.getContextInstance().setVariable("note", "

准假

"
);

}

}

OK
,后台的程序就算写完了(前台客户端的程序还没写),下面开始部署。



6.5 部署processdefinition.xml

我们要把
processdefinition.xml
的流程定义的数据部署到数据库中,因为
jBPM
在正式运行的时候不是去读
processdefinition.xml
文件,而是去读数据库中的流程定义。

这里写了一个个
JUnit
程序来部署
processdefinition.xml
,当然你用普通的
Java Main
也可以。


package

com.sample;


import

java.io.FileInputStream;


import

java.io.FileNotFoundException;


import

java.io.InputStream;


import

junit.framework.TestCase;


import

org.jbpm.JbpmConfiguration;


import

org.jbpm.JbpmContext;


import

org.jbpm.graph.def.ProcessDefinition;

/**

*

部署

processdefinition.xml

*

* @author chengang

*

*/


public



class
DeployProcessTest extends TestCase {

/**

*

在本方法执行完毕后,检查

jbpm_processdefinition

表会多了一条记录

*

* @throws FileNotFoundException

*/


public


void
testDeployProcessDefinition() throws FileNotFoundException {

//



jbpm.cfg.xml

取得

jbpm

的配置

JbpmConfiguration config = JbpmConfiguration.getInstance();

//

创建一个

jbpm

容器

JbpmContext jbpmContext = config.createJbpmContext();

//



processdefinition.xml

生成相对应的流程定义类

ProcessDefinition

InputStream is = new FileInputStream("processes/simple/processdefinition.xml");

ProcessDefinition processDefinition = ProcessDefinition.parseXmlInputStream(is);

//

利用容器的方法将流程定义数据部署到数据库上

jbpmContext.deployProcessDefinition(processDefinition);

//

关闭

jbpmContext

jbpmContext.close();

}

}

运行此程序,在控制台打印了一些日志,通过。如果出错,仔佃阅读出错信息以判断错误原因,并确定你按照前面两节:“修改
hibernate.cfg.xml
”和“完善库引用”的内容做好了设置。



6.6 从数据库中的查看部署效果

无论是
MySQL
还是
Oracle
,查询
jbpm_processdefinition
表,你会发现多了一条记录,如下图
(

PLSQL Developer
的显示为例
)



依次检查各表我们可以发现有如下变化:













并由此简单判断出各表的作用,表中各字段的作用由字段名也能知晓一二。

jbpm_processdefinition

一个流程定义文件对应一条记录,可记录多个流程定义文件,可记录一个流程定义文件的对个版本。

jbpm_action

记录
ActionHandler
的对象实例(以名称为标识)

jbpm_delegation

记录了
ActionHandler
全类名,以便于用反射方式来加载

jbpm_envent

它的
transition
引用了
Jbpm_transition
表的
id
,再看其它字段,估计此表是表示流程转向事件的一个实例,或者是一个各表之间的联接表。

jbpm_node

流程结点

jbpm_transition

流程的转向定义

jbpm_variableaccess

流程中携带的变量。
ACCESS
字段是这些变量的读写权限

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: