jBPM开发入门(3)
来源:互联网 发布:java performance中文 编辑:程序博客网 时间:2024/05/18 01:50
5 安装jBPM的Eclipse开发插件
有个辅助工具开发起来方便一点,只不过现在jBPM的开发工具插件功能还不算太强,也就一个“项目创建向导”的功能,让你:
(1)不用再去配置classpath库的引用了
(2)直接得到了一个jBPM的项目初始结构
其实吧,开发jBPM也不需要什么插件工具,在熟练了以后,库引用了项目初始结构都可以手工创建。
插件不用再去下载了,jbpm-starters-kit-
如果安装成功,则Eclipse首选项里多了一个JBoss jBPM,另外我们也需要到这个jBPM的首选项里做一些配置工作――指定jBPM的安装路径(如下图所示)。这个配置主要是为了找到jbpm下的各种jar包,好让Eclipse设置项目的库引用。本文指向路径是d:/jbpm-starters-kit-
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-
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-
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-
l oracle的jdbc包,jbmp中没有包含(可能是没拿到oracle授权),我们可以自已去oracle网站上下载,或者去oracle安装目录D:/oracle/ora92/jdbc/lib找ojdbc14.jar(我们公司用的是Oracle9i)
l Hibernate3.jar在目录D:/jbpm-starters-kit-
(2) 在项目里创建一个lib目录,将这三个jar复制到lib目录。
(3) 如下图设置三jar包的库引用
这里是一个很简单的请假流程,请假人提交假单给经理审批,经理审批后结束。要说明的是,这个流程并不严谨,比如经理不通过流程应该到哪?不过这并不防碍拿它来做示例,螃蟹还得一个一个的吃。我们先拿这一杆子捅到底的流程做一个最简单的示例,从整体上对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。其代码如下:
packagecn.com.chengang.jbpm;
importorg.jbpm.graph.def.ActionHandler;
importorg.jbpm.graph.exe.ExecutionContext;
publicclassRequestAction implements ActionHandler {
privatestaticfinallongserialVersionUID=
privateString reason;
publicString getReason() {
returnreason;
}
publicvoidsetReason(String reason) {
this.reason = reason;
}
publicvoidexecute(ExecutionContext context) throws Exception {
context.getContextInstance().setVariable("note", reason);
}
}
说明:ExecutionContext是一个贯通流程的容器。它是个大宝箱,里面啥玩意都有,后面将更深入的提到。这里的reasion就是processdefinition.xml中的”我要请假”
packagecn.com.chengang.jbpm;
importorg.jbpm.graph.def.ActionHandler;
importorg.jbpm.graph.exe.ExecutionContext;
publicclassConfirmAction implements ActionHandler {
privatestaticfinallongserialVersionUID=
publicvoidexecute(ExecutionContext context) throws Exception {
context.getContextInstance().setVariable("note", "准假");
}
}
OK,后台的程序就算写完了(前台客户端的程序还没写),下面开始部署。
我们要把processdefinition.xml的流程定义的数据部署到数据库中,因为jBPM在正式运行的时候不是去读processdefinition.xml文件,而是去读数据库中的流程定义。这里写了一个个JUnit程序来部署processdefinition.xml,当然你用普通的Java Main也可以。
packagecom.sample;
importjava.io.FileInputStream;
importjava.io.FileNotFoundException;
importjava.io.InputStream;
importjunit.framework.TestCase;
importorg.jbpm.JbpmConfiguration;
importorg.jbpm.JbpmContext;
importorg.jbpm.graph.def.ProcessDefinition;
/**
* 部署processdefinition.xml
*
* @author chengang
*
*/
publicclassDeployProcessTest extends TestCase {
/**
* 在本方法执行完毕后,检查jbpm_processdefinition表会多了一条记录
*
* @throws FileNotFoundException
*/
publicvoidtestDeployProcessDefinition() 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字段是这些变量的读写权限
陈刚,广西桂林人,著作有《Eclipse从入门到精通》
- jBPM开发入门(3)
- jBPM开发入门指南(3)
- JBPM开发入门指南(3)
- jBPM开发入门指南(3)
- jBPM开发入门指南(3)
- jBPM开发入门指南(3)
- jBPM开发入门指南(3)
- jBPM开发入门指南
- jBPM开发入门指南
- jBPM开发入门指南
- jBPM开发入门(2)
- jBPM开发入门指南
- jBPM开发入门指南
- jbpm(3)---jbpm入门示例
- jBPM开发入门指南(1)
- jBPM开发入门指南(2)
- JBPM开发入门指南(1)
- JBPM开发入门指南(2)
- 如何给系统菜单添加一个菜单项
- qq邮箱不能上传文件的修复
- 在用户环境中如何确定系统显示元素的颜色
- 《人月神话》读书笔记(十六)——关于文档
- *.3ds的文件格式
- jBPM开发入门(3)
- 如何查询和设置系统参数
- 帮人管理服务器遇到难题了 :(
- 暴力的边界--Leo与跆拳道(3)
- 初学数据库开发小结
- [原创]VMware-workstation6.0 for linux安装使用
- 在泥潭中愈陷愈深的丁俊晖
- 艾恩ASP留言本系统(XML版)
- 仿STL中的堆算法的一个实现