| 5  安裝 jBPM 的 Eclipse 開發(fā)插件  有個輔助工具開發(fā)起來方便一點,只不過現(xiàn)在 jBPM 的開發(fā)工具插件功能還不算太強,也就一個“項目創(chuàng)建向?qū)?#8221;的功能,讓你:  (1)不用再去配置 classpath 庫的引用了  (2)直接得到了一個 jBPM 的項目初始結(jié)構(gòu)  其實吧,開發(fā) jBPM 也不需要什么插件工具,在熟練了以后,庫引用了項目初始結(jié)構(gòu)都可以手工創(chuàng)建。  插件不用再去下載了, jbpm-starters-kit-3.1.1 包里就有,目錄地址如下: D:\jbpm-starters-kit-3.1.1\jbpm-designer\jbpm-gpd-feature\eclipse ,插件的安裝方式是鏈接式還是直接復(fù)制式,任選吧。不懂的就去看看《 Eclipse 從入門精通》這本書,在前面章節(jié)都有講到。另外,注明一下 Eclipse 的版本我是用 3.2 ,插件和 Eclispe 版本相關(guān)的,要注意了。  如果安裝成功,則 Eclipse 首選項里多了一個 JBoss jBPM ,另外我們也需要到這個 jBPM 的首選項里做一些配置工作――指定 jBPM 的安裝路徑(如下圖所示)。這個配置主要是為了找到 jbpm 下的各種 jar 包,好讓 Eclipse 設(shè)置項目的庫引用。本文指向路徑是 d:\jbpm-starters-kit-3.1.1\jbpm.3  6   jBPM 的 Hello World  6.1 新建jBPM項目  主菜單“文件->新建->項目”,在彈出的對話框里,有“ Process Project ”項,如下圖所示:  
 項目創(chuàng)建起了,介紹一下里面的文件吧:  l           MessageActionHandler ,自動生成的一個 ActionHandler 。不想要可以刪掉。  l           ehcache.xml  cache 的配置文件,里面有很詳解的英文說明。沒有必要可以不用改它。  l           hibernate.cfg.xml   jBPM 是用 Hibernate 進行工作流的數(shù)據(jù)存儲的,這個就是 Hibernate 的配置文件。后面我們將講到如何配置這個文件。  l           jbpm.cfg.xml   jbpm 本身的配置文件?,F(xiàn)在是空的,它用的是缺省配置,你想知道有哪些配置就去看這個文件 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 的優(yōu)良設(shè)計使得它的可測試性非常之高,喜歡寫 t 單元測試的人有福了。  l           gpd.xml  用于生成流程圖的定義文件。都是一些方框的坐標(biāo)和長寬  l           processdefinition.xml  這個是對最重要的流程配置文件,以后寫流程要經(jīng)常和它打交道。  l           processimage.jpg  一個流程圖  
 6.2 修改hibernate.cfg.xml      hibernate.cfg.xml 的默認(rèn)設(shè)置是用 HSQL ,這是一個內(nèi)存數(shù)據(jù)庫,這種內(nèi)存數(shù)據(jù)庫用來代替項目實際所用的數(shù)據(jù)庫來做單元測試挺不錯的。不過我們這里是要試試用 MySQL 、 Oracle ,那就改一下設(shè)置吧。  注:配置值可參考 D:\jbpm-starters-kit-3.1.1\jbpm-db 對應(yīng)子目錄下的 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 里做了如下的設(shè)置  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 在創(chuàng)建項目之初給我們設(shè)置好了庫引用,如下圖  但后面運行時還是報一些 NoClassDefFoundError 異常,如沒有對 hibernate3.jar 的引用導(dǎo)致下面的錯誤  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 授權(quán)),我們可以自已去 oracle 網(wǎng)站上下載,或者去 oracle 安裝目錄 D:\oracle\ora92\jdbc\lib 找 ojdbc14.jar (我們公司用的是 Oracle9i )  l           Hibernate3.jar 在目錄 D:\jbpm-starters-kit-3.1.1\jbpm.3\lib\hibernate 里。  (2)       在項目里創(chuàng)建一個 lib 目錄,將這三個 jar 復(fù)制到 lib 目錄。  (3)       如下圖設(shè)置三 jar 包的庫引用  
 6.4 開始HellorWorld  這里是一個很簡單的請假流程,請假人提交假單給經(jīng)理審批,經(jīng)理審批后結(jié)束。要說明的是,這個流程并不嚴(yán)謹(jǐn),比如經(jīng)理不通過流程應(yīng)該到哪?不過這并不防礙拿它來做示例,螃蟹還得一個一個的吃。我們先拿這一桿子捅到底的流程做一個最簡單的示例,從整體上對 jBPM 工作流開發(fā)有概念先。然后我們再慢慢豐富。  1 、定義流程  流程的定義文件是 processdefinition.xml ,這個是一個關(guān)鍵文件, jBPM 的很大一部份內(nèi)容都是關(guān)于它的。在這里我們把原來自動生成的內(nèi)容,稍做改動:  <?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>         <!-- 流程轉(zhuǎn)向 -->         <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>      <!-- 結(jié)束 -->      <end-state name="end" />  </process-definition>  
 流程的名稱改成了 helloworld 。(呵呵,也就是這里和 helloworld 有關(guān)了)  <controller> 標(biāo)簽定義了三個數(shù)據(jù):姓名、請假天數(shù)、說明。  <transition> 標(biāo)簽定了 request 節(jié)點的一個流程轉(zhuǎn)向,這里是轉(zhuǎn)到 confirm 節(jié)點。  <action> 標(biāo)簽定義了流程由一個節(jié)點轉(zhuǎn)到另一個節(jié)點時,所要執(zhí)行的動作,動作封裝在一個 ActionHandler 類中。比如這里當(dāng) request 到 confirm 結(jié)點時將執(zhí)行 RequestAction 類的 execute 方法。  FinishAction 下面還有一個 <reason> (請假理由),它對應(yīng)于 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", " 準(zhǔn)假 " );      }  }  OK ,后臺的程序就算寫完了(前臺客戶端的程序還沒寫),下面開始部署。  6.5 部署processdefinition.xml      我們要把 processdefinition.xml 的流程定義的數(shù)據(jù)部署到數(shù)據(jù)庫中,因為 jBPM 在正式運行的時候不是去讀 processdefinition.xml 文件,而是去讀數(shù)據(jù)庫中的流程定義。    這里寫了一個個 JUnit 程序來部署 processdefinition.xml ,當(dāng)然你用普通的 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 {      /**       * 在本方法執(zhí)行完畢后,檢查 jbpm_processdefinition 表會多了一條記錄        *       * @throws FileNotFoundException        */      public void testDeployProcessDefinition() throws FileNotFoundException {         // 從 jbpm.cfg.xml 取得 jbpm 的配置         JbpmConfiguration config = JbpmConfiguration.getInstance();         // 創(chuàng)建一個 jbpm 容器         JbpmContext jbpmContext = config.createJbpmContext();         // 由 processdefinition.xml 生成相對應(yīng)的流程定義類 ProcessDefinition         InputStream is = new FileInputStream("processes/simple/processdefinition.xml");         ProcessDefinition processDefinition = ProcessDefinition.parseXmlInputStream(is);         // 利用容器的方法將流程定義數(shù)據(jù)部署到數(shù)據(jù)庫上         jbpmContext.deployProcessDefinition(processDefinition);         // 關(guān)閉 jbpmContext         jbpmContext.close();      }  }  運行此程序,在控制臺打印了一些日志,通過。如果出錯,仔佃閱讀出錯信息以判斷錯誤原因,并確定你按照前面兩節(jié):“修改 hibernate.cfg.xml ”和“完善庫引用”的內(nèi)容做好了設(shè)置。  6.6 從數(shù)據(jù)庫中的查看部署效果  無論是 MySQL 還是 Oracle ,查詢 jbpm_processdefinition 表,你會發(fā)現(xiàn)多了一條記錄,如下圖 ( 以 PLSQL Developer 的顯示為例 )  依次檢查各表我們可以發(fā)現(xiàn)有如下變化:  
 并由此簡單判斷出各表的作用,表中各字段的作用由字段名也能知曉一二。  
 作者簡介 | 
|  |