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 ”项,如下图所示:
项目创建起了,介绍一下里面的文件吧: 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 一个流程图
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) ) )
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 的显示为例 ) 依次检查各表我们可以发现有如下变化: 并由此简单判断出各表的作用,表中各字段的作用由字段名也能知晓一二。
作者简介 |
|