安装配置appfuse jsf basic
下载 smtp server 安装 推荐 Personal Mail Server Pro v2.3 crsky 可以下载. 网上可以找到 Serial
由于没有找到特别好用的free smtp server for windows .
保持默认配置即可.
进入eclipse 工程目录 方便以后直接导入
C:\eclipse-SDK-3.3.1.1-win32\eclipse\workspace>
执行
mvn archetype:create -DarchetypeGroupId=org.appfuse.archetypes -DarchetypeArtifactId=appfuse-basic-jsf -DremoteRepositories=http://static.appfuse.org/releases -DarchetypeVersion=2.0.1 -DgroupId=net.myjbpm.app -DartifactId=myapp
启动mysql 如果默认使用 root 空密码 则不需要修改. 否则修改 C:\eclipse-SDK-3.3.1.1-win32\eclipse\workspace\myjbpm\pom.xml文件
修改 文件底部
<!-- Database settings -->
<dbunit.dataTypeFactoryName>org.dbunit.dataset.datatype.DefaultDataTypeFactory</dbunit.dataTypeFactoryName>
<dbunit.operation.type>CLEAN_INSERT</dbunit.operation.type>
<hibernate.dialect>org.hibernate.dialect.MySQL5InnoDBDialect</hibernate.dialect>
<jdbc.groupId>mysql</jdbc.groupId>
<jdbc.artifactId>mysql-connector-java</jdbc.artifactId>
<jdbc.version>5.0.5</jdbc.version>
<jdbc.driverClassName>com.mysql.jdbc.Driver</jdbc.driverClassName>
<jdbc.url><![CDATA[jdbc:mysql://localhost/myjbpm?createDatabaseIfNotExist=true&useUnicode=true&characterEncoding=utf-8]]></jdbc.url>
<jdbc.username>root</jdbc.username>
<jdbc.password></jdbc.password>
我习惯使用easymock , 修改maven dependency 可选.
.....
<!-- Using EasyMock instead of jMock in Unit Tests ==
<dependency>
<groupId>jmock</groupId>
<artifactId>jmock</artifactId>
<version>${jmock.version}</version>
<scope>test</scope>
</dependency>
== -->
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<version>${easymock.version}</version>
<scope>test</scope>
</dependency>
....
<easymock.version>2.2</easymock.version>
....
C:\eclipse-SDK-3.3.1.1-win32\eclipse\workspace\myjbpm>mvn
时间较长, 请煮杯咖啡, 慢慢品尝.
完成后
C:\eclipse-SDK-3.3.1.1-win32\eclipse\workspace\myapp>mvn jetty:run-war
生成eclipse工程文件.确保本机smtp server启动
C:\eclipse-SDK-3.3.1.1-win32\eclipse\workspace\myapp>mvn install eclipse:eclipse
推荐 不要运行展开, web 和 java 源码, 方便以后升级. 阅读源码可以新建一个工程查看源码
安装eclipse maven plugin 参考.
http://m2eclipse.codehaus.org/Installing_Maven_2.0_plugin_for_Eclipse.html
http://m2eclipse.codehaus.org/Maven_2.0_Plugin_for_Eclipse.html
配置 maven 环境 for eclipse.
将myapp工程导入eclipse中.
修改 maven pom 新增 jbpm spring-modules dependency
C:\eclipse-SDK-3.3.1.1-win32\eclipse\workspace\myapp\pom.xml
我以本机 repository server 方式 替换了 spring 官方的spring-modules-jbpm31-0.8a.pom
由于目前spring-modules支持 jbpm3.1 实际上可以通过修改一些配置支持jbpm3.2
添加本机repository server 声明
<repository>
<id>myRepository</id>
<url>http://localhost/m2/repository</url>
</repository>
安装 apache 配置 repository server 还可以用其他工具, 网上有一些文章, 不再详述.
添加 dependency
<!-- Dependencies for spring-modules -->
<dependency>
<groupId>org.springmodules</groupId>
<artifactId>spring-modules-jbpm31</artifactId>
<version>0.8a</version>
</dependency>
<dependency>
<groupId>org.jbpm</groupId>
<artifactId>jbpm-jpdl</artifactId>
<version>3.2</version>
</dependency>
<dependency>
<groupId>org.jbpm</groupId>
<artifactId>jbpm-identity</artifactId>
<version>3.2</version>
</dependency>
新增菜单.
修改C:\eclipse-SDK-3.3.1.1-win32\eclipse\workspace\myapp\src\main\webapp\common\menu.jsp
新增
<menu:displayMenu name="TaskMenu"/>
<menu:displayMenu name="ProcessMenu"/>
修改C:\eclipse-SDK-3.3.1.1-win32\eclipse\workspace\myapp\src\main\webapp\WEB-INF\menu-config.xml
新增
<Menu name="TaskMenu" title="menu.task" page="/testMenu.jsp" roles="ROLE_ADMIN,ROLE_USER"/>
<Menu name="ProcessMenu" title="menu.process" page="/bpm/processes.html" roles="ROLE_ADMIN"/>
编辑C:\eclipse-SDK-3.3.1.1-win32\eclipse\workspace\myapp\src\main\resources\ApplicationResources_zh_CN.properties
新增
menu.task=我的任务
menu.process=流程管理
C:\eclipse-SDK-3.3.1.1-win32\eclipse\workspace\myapp>mvn jetty:run
http://localhost:8080 查看菜单已经增加.
集成 jbpm appfuse spring modules
jbpm spring-modules-jbpm 相关依赖有一些问题, 查看pom 中相关配置.
新建文件
C:\eclipse-SDK-3.3.1.1-win32\eclipse\workspace\myapp\src\main\resources\jbpmApplicationContext.xml
主要包含spring-modlues 相关配置
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd"> <beans default-autowire="byName" default-lazy-init="true"> <bean id="jbpmDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/jbpm32" /> <property name="username" value="jbossjbpm" /> <property name="password" value="jbossjbpm" /> </bean> <bean id="jbpmSessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource" ref="jbpmDataSource" /> <property name="mappingLocations"> <list> <value>classpath*:org/jbpm/**/*.hbm.xml</value> </list> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect"> org.hibernate.dialect.MySQL5InnoDBDialect </prop> <prop key="hibernate.show_sql">false</prop> <prop key="hibernate.cache.use_query_cache">true</prop> <prop key="hibernate.cache.provider_class"> org.hibernate.cache.EhCacheProvider </prop> </props> </property> </bean> <!--Hibernate TransactionManager--> <bean id="jbpmTransactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="jbpmSessionFactory" /> </bean> <!-- jBPM Configuration --> <bean id="jbpmConfiguration" class="org.springmodules.workflow.jbpm31.LocalJbpmConfigurationFactoryBean"> <property name="sessionFactory" ref="jbpmSessionFactory" /> <property name="configuration" value="classpath:jbpm.cfg.xml" /> <property name="processDefinitions"> <list> <!-- add new processDefinitions here --> <ref local="simpleWorkflow" /> </list> </property> <property name="createSchema" value="false"/> </bean> <!-- helper for reading jBPM process definitions --> <bean id="simpleWorkflow" class="org.springmodules.workflow.jbpm31.definition.ProcessDefinitionFactoryBean"> <property name="definitionLocation" value="classpath:jpdl/simple/processdefinition.xml" /> </bean> <!-- <bean id="approveFlow" class="org.springmodules.workflow.jbpm31.definition.ProcessDefinitionFactoryBean"> <property name="definitionLocation" value="classpath:approve/approveFlow.xml"/> </bean> --> <!-- jBPM template --> <bean id="jbpmTemplate" class="org.springmodules.workflow.jbpm31.JbpmTemplate"> <constructor-arg index="0" ref="jbpmConfiguration" /> <constructor-arg index="1" ref="simpleWorkflow" /> </bean> </beans>
修改 C:\eclipse-SDK-3.3.1.1-win32\eclipse\workspace\myapp\src\main\webapp\WEB-INF\web.xml
添加jbpmApplicationContext.xml
<!-- Context Configuration locations for Spring XML files --> <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath:/applicationContext-resources.xml classpath:/applicationContext-dao.xml classpath:/applicationContext-service.xml classpath:/jbpmApplicationContext.xml classpath*:/applicationContext.xml /WEB-INF/applicationContext*.xml /WEB-INF/xfire-servlet.xml /WEB-INF/security.xml </param-value> </context-param>
创建dao test class
C:\eclipse-SDK-3.3.1.1-win32\eclipse\workspace\myapp\src\test\java\net\myjbpm\bpm\dao
package net.myjbpm.bpm.dao;
import java.util.List;
import org.jbpm.graph.def.ProcessDefinition;
public class JbpmDaoTest extends JbpmBaseDaoTestCase {
private JbpmDao jbpmDao = null;
public void setJbpmDao(JbpmDao jbpmDao) {
this.jbpmDao = jbpmDao;
}
public void testGetProcessDefinitions() throws Exception {
List<ProcessDefinition> processes = jbpmDao.getProcessDefinitions();
assertTrue(processes.size() > 0);
}
}
创建测试用jbpm 相关配置
新建C:\eclipse-SDK-3.3.1.1-win32\eclipse\workspace\myapp\myapp\src\test\resources\jbpmApplicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd"> <beans default-autowire="byName" default-lazy-init="true"> <!-- It's only for unit test --> <bean id="jbpmDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/jbpm32" /> <property name="username" value="jbossjbpm" /> <property name="password" value="jbossjbpm" /> </bean> <bean id="jbpmSessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource" ref="jbpmDataSource" /> <property name="mappingLocations"> <list> <value>classpath*:org/jbpm/**/*.hbm.xml</value> </list> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect"> org.hibernate.dialect.MySQL5InnoDBDialect </prop> <prop key="hibernate.show_sql">false</prop> <prop key="hibernate.cache.use_query_cache">true</prop> <prop key="hibernate.cache.provider_class"> org.hibernate.cache.EhCacheProvider </prop> </props> </property> </bean> <!--Hibernate TransactionManager--> <bean id="jbpmTransactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="jbpmSessionFactory" /> </bean> <!-- jBPM Configuration --> <bean id="jbpmConfiguration" class="net.myjbpm.bpm.util.LocalSpring2JbpmConfigurationFactoryBean"> <property name="sessionFactory" ref="jbpmSessionFactory" /> <property name="configuration" value="classpath:jbpm.cfg.xml" /> <property name="processDefinitions"> <list> <!-- add new processDefinitions here --> <ref local="simpleWorkflow" /> </list> </property> <property name="createSchema" value="false"/> <property name="factoryLocator" ref="jbpmFactoryLocator" /> </bean> <bean id="jbpmFactoryLocator" class="net.myjbpm.bpm.util.Spring2JbpmFactoryLocator" /> <!-- helper for reading jBPM process definitions --> <bean id="simpleWorkflow" class="org.springmodules.workflow.jbpm31.definition.ProcessDefinitionFactoryBean"> <property name="definitionLocation" value="classpath:jpdl/simple/processdefinition.xml" /> </bean> <!-- <bean id="approveFlow" class="org.springmodules.workflow.jbpm31.definition.ProcessDefinitionFactoryBean"> <property name="definitionLocation" value="classpath:approve/approveFlow.xml"/> </bean> --> <!-- jBPM template --> <bean id="jbpmTemplate" class="org.springmodules.workflow.jbpm31.JbpmTemplate"> <constructor-arg index="0" ref="jbpmConfiguration" /> <constructor-arg index="1" ref="simpleWorkflow" /> </bean> </beans>
参考http://forum.springframework.org/showthread.php?t=31795
创建相关实现 class , interface
C:\eclipse-SDK-3.3.1.1-win32\eclipse\workspace\myapp\src\main\java\net\myjbpm\bpm\dao
package net.myjbpm.bpm.dao;
import java.util.List;
import org.jbpm.graph.def.ProcessDefinition;
public interface JbpmDao {
/**
* Gets a list of users ordered by the uppercase version of their processname.
*
* @return List populated list of users
*/
List<ProcessDefinition> getProcessDefinitions();
}
C:\eclipse-SDK-3.3.1.1-win32\eclipse\workspace\myapp\src\main\java\net\myjbpm\bpm\dao\hibernate
package net.myjbpm.bpm.dao.hibernate;
import java.util.List;
import org.jbpm.JbpmContext;
import org.jbpm.JbpmException;
import org.jbpm.graph.def.ProcessDefinition;
import org.springmodules.workflow.jbpm31.JbpmCallback;
import org.springmodules.workflow.jbpm31.JbpmTemplate;
import net.myjbpm.bpm.dao.JbpmDao;
public class JbpmDaoHibernate implements JbpmDao{
private JbpmTemplate jbpmTemplate;
@SuppressWarnings("unchecked")
public List<ProcessDefinition> getProcessDefinitions() {
return (List<ProcessDefinition>) jbpmTemplate.execute(new JbpmCallback() {
public Object doInJbpm(final JbpmContext jbpmContext)
throws JbpmException {
return jbpmContext.getGraphSession()
.findLatestProcessDefinitions();
}
});
}
public JbpmTemplate getJbpmTemplate() {
return jbpmTemplate;
}
public void setJbpmTemplate(JbpmTemplate jbpmTemplate) {
this.jbpmTemplate = jbpmTemplate;
}
}
配置 spring context
修改C:\eclipse-SDK-3.3.1.1-win32\eclipse\workspace\myapp\src\main\webapp\WEB-INF\applicationContext.xml
<!-- Add new DAOs here --> <bean id="jbpmDao" class="net.myjbpm.bpm.dao.hibernate.JbpmDaoHibernate"> <property name="jbpmTemplate" ref="jbpmTemplate"/> </bean> <!-- Add new Managers here --> <bean id="jbpmManager" class="net.myjbpm.bpm.service.impl.JbpmManagerImpl"> <property name="jbpmDao" ref="jbpmDao"/> </bean>
启动mysql.
测试dao
C:\eclipse-SDK-3.3.1.1-win32\eclipse\workspace\myapp>mvn test -Dtest=JbpmDaoTest
测试结果在C:\eclipse-SDK-3.3.1.1-win32\eclipse\workspace\myapp\target\surefire-reports
创建 manager test class
C:\eclipse-SDK-3.3.1.1-win32\eclipse\workspace\myapp\src\test\java\net\myjbpm\bpm\service\impl
package net.myjbpm.bpm.service.impl;
import static org.easymock.EasyMock.*;
import java.util.ArrayList;
import java.util.List;
import net.myjbpm.bpm.dao.JbpmDao;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.Log;
import org.jbpm.graph.def.ProcessDefinition;
import junit.framework.TestCase;
public class JbpmManagerImplTest extends TestCase{
private final Log log = LogFactory.getLog(JbpmManagerImplTest.class);
private JbpmManagerImpl manager = null;
private JbpmDao dao = null;
private ProcessDefinition process = null;
protected void setUp() throws Exception {
log.debug("setUpDao for JbpmManageImplTest");
dao = createStrictMock(JbpmDao.class);
manager = new JbpmManagerImpl((JbpmDao) dao);
}
public void testGetProcesses() {
log.debug("testing getProcesses");
List processes = new ArrayList();
// set expected behavior on dao
expect(dao.getProcessDefinitions()).andReturn(processes);
replay(dao);
List result = manager.getProcessDefinitions();
assertSame(processes, result);
verify(dao);
}
}
package net.myjbpm.bpm.service;
import java.util.List;
import org.jbpm.graph.def.ProcessDefinition;
public interface JbpmManager {
List<ProcessDefinition> getProcessDefinitions();
}
package net.myjbpm.bpm.service.impl;
import java.util.List;
import org.jbpm.graph.def.ProcessDefinition;
import net.myjbpm.bpm.dao.JbpmDao;
import net.myjbpm.bpm.service.JbpmManager;
public class JbpmManagerImpl implements JbpmManager{
private JbpmDao jbpmDao;
public JbpmManagerImpl() {
super();
// TODO Auto-generated constructor stub
}
public JbpmManagerImpl(JbpmDao jbpmDao) {
this.jbpmDao = jbpmDao;
// TODO Auto-generated constructor stub
}
public List<ProcessDefinition> getProcessDefinitions() {
// TODO Auto-generated method stub
return jbpmDao.getProcessDefinitions();
}
public JbpmDao getJbpmDao() {
return jbpmDao;
}
public void setJbpmDao(JbpmDao jbpmDao) {
this.jbpmDao = jbpmDao;
}
}
C:\eclipse-SDK-3.3.1.1-win32\eclipse\workspace\myapp>mvn test -Dtest=JbpmManagerImplTest
创建action test class
package net.myjbpm.bpm.webapp.action;
import net.myjbpm.bpm.service.JbpmManager;
public class ProcessListTest extends JbpmBasePageTestCase {
private ProcessList bean;
private JbpmManager jbpmManager;
public void setJbpmManager(JbpmManager jbpmManager) {
this.jbpmManager = jbpmManager;
}
@Override
@SuppressWarnings("unchecked")
protected void onSetUp() throws Exception {
super.onSetUp();
bean = new ProcessList();
bean.setJbpmManager(jbpmManager);
// add a test process to the database @do it latter@
}
@Override
protected void onTearDown() throws Exception {
super.onTearDown();
bean = null;
}
public void testGetProcesses() throws Exception {
assertTrue(bean.getProcesses().size() >= 1);
assertFalse(bean.hasErrors());
}
}
实现类
package net.myjbpm.bpm.webapp.action;
import java.io.Serializable;
import java.util.List;
import net.myjbpm.bpm.service.JbpmManager;
import org.appfuse.webapp.action.BasePage;
public class ProcessList extends BasePage implements Serializable{
/**
*
*/
private static final long serialVersionUID = 5941146729015089028L;
private JbpmManager jbpmManager;
public ProcessList() {
setSortColumn("name");
}
@SuppressWarnings("unchecked")
public List getProcesses() {
return sort(jbpmManager.getProcessDefinitions());
}
public JbpmManager getJbpmManager() {
return jbpmManager;
}
public void setJbpmManager(JbpmManager jbpmManager) {
this.jbpmManager = jbpmManager;
}
}
配置 jsf manage bean
C:\eclipse-SDK-3.3.1.1-win32\eclipse\workspace\myapp\src\main\webapp\WEB-INF\faces-config.xml
<!-- Add additional beans here --> <managed-bean> <managed-bean-name>processList</managed-bean-name> <managed-bean-class>net.myjbpm.bpm.webapp.action.ProcessList</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> <managed-property> <property-name>jbpmManager</property-name> <value>#{jbpmManager}</value> </managed-property> </managed-bean>
C:\eclipse-SDK-3.3.1.1-win32\eclipse\workspace\myapp>mvn test -Dtest=ProcessListTest
jsf xhtml 文件.
C:\eclipse-SDK-3.3.1.1-win32\eclipse\workspace\myapp\src\main\webapp\bpm\process.xhtml
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:c="http://java.sun.com/jstl/core" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:t="http://myfaces.apache.org/tomahawk"> <f:view> <f:loadBundle var="text" basename="#{processList.bundleName}"/> <head> <title>#{text['processList.title']}</title> <meta name="heading" content="#{text['processList.heading']}"/> <meta name="menu" content="ProcessMenu"/> </head> <h:form id="editProcess"> <!-- Error from this table is caused by http://issues.apache.org/jira/browse/TOMAHAWK-466 --> <t:dataTable id="processes" var="process" style="margin-top: 10px" value="#{processList.processes}" rows="25" sortColumn="#{processList.sortColumn}" sortAscending="#{processList.ascending}" styleClass="scrollerTable table" headerClass="standardTable_Header" rowClasses="standardTable_Row1,standardTable_Row2" columnClasses="standardTable_Column,standardTable_Column,standardTable_Column,standardTable_Column,standardTable_ColumnCentered"> <t:column width="25%"> <f:facet name="header"> <t:commandSortHeader columnName="id" arrow="true"> <h:outputText value="#{text['process.id']}" /> </t:commandSortHeader> </f:facet> <h:outputText value="#{process.id}" /> </t:column> <t:column width="25%"> <f:facet name="header"> <t:commandSortHeader columnName="name" arrow="true"> <h:outputText value="#{text['process.name']}" /> </t:commandSortHeader> </f:facet> <h:outputText value="#{process.name}" /> </t:column> <t:column width="25%"> <f:facet name="header"> <t:commandSortHeader columnName="description" arrow="true"> <h:outputText value="#{text['process.description']}" /> </t:commandSortHeader> </f:facet> <h:outputText value="#{process.description}" /> </t:column> </t:dataTable> <ui:include src="/common/tableFooter.xhtml"> <ui:param name="tableName" value="processes"/> </ui:include> </h:form> </f:view> </html>
添加相关资源文件. properites.
C:\eclipse-SDK-3.3.1.1-win32\eclipse\workspace\myapp>mvn jetty:run-war
安装eclipse 插件.
下载 jbpm-jpdl-suite-3.2.GA.zip 包含了 designer.
在eclipse 安装文件夹下D:\eclipse-SDK-3.3.1.1-win32\eclipse\links
新建一个 jpbm32.link
内容为
path=D:\\software\\jbpm-jpdl-3.2.GA\\designer
jbpm-jpdl-designer-3.1.2 加入了一些的有用的特性, 例生成jsf orms.xml 重新配置eclipse link 文件
删除 jbpm32.link
在eclipse 安装文件夹下D:\eclipse-SDK-3.3.1.1-win32\eclipse\links\jbpm32.link
新建D:\eclipse-SDK-3.3.1.1-win32\eclipse\links\jbpm-jpdl-designer-3.1.2.link
path=D:\\eclipse-SDK-3.3.1.1-win32\\plugin\\jbpm-jpdl-designer-3.1.2
http://labs.jboss.com/jbossjbpm/downloads/
完成时间预计 2008年1月12日
实际完成时间 2008年1月17日
LOOKING FORWORDS :
开发任务管理相关模块.
开发常用流程实例.
THAT'S ALL