安装配置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