好多人在一开始使用jbpm-human-task的服务时都会遇到使用这个WSHumanTaskHandler的问题。针对Mina,JBPM提供了WSHumanTaskHandler、CommandBasedWSHumanTaskHandler。在解释之前,先假定一个简单的人工流程:s->T1->T2->e。
一般可以理解为:WSHumanTaskHandler是用于流程实例一直处于活动状态的流程;CommandBasedWSHumanTaskHandler则用于流程执行时间比较长,ksession需要从内存中despose掉的流程,既然ksession要被despose掉,那就需要数据库去存储了。
下面是两者不同的初始化方法、以及所需不同的KnowledgeSession的生成方法:
ksession = kaAdeptor.getKnowledgeBase().newStatefulKnowledgeSession();
handler = new WSHumanTaskHandler();
ksession.getWorkItemManager().registerWorkItemHandler("Human Task",handler);
-----------------------------
Environment env = KnowledgeBaseFactory.newEnvironment();
env.set( EnvironmentName.ENTITY_MANAGER_FACTORY, emf );
env.set( EnvironmentName.TRANSACTION_MANAGER, tm);
ksession = JPAKnowledgeService.newStatefulKnowledgeSession(kaAdeptor.getKnowledgeBase(), null, env);
handler = new CommandBasedWSHumanTaskHandler(ksession);
ksession.getWorkItemManager().registerWorkItemHandler("Human Task",handler);
如果将前者的handler注册给后面的ksession,执行流程时不会报异常,在s节点时session info会被持久,T1可以正常执行,但流程到不了T2了。如果后者注册
Caused by: java.lang.NullPointerException
at org.jbpm.process.audit.JPAWorkingMemoryDbLogger.addProcessLog(JPAWorkingMemoryDbLogger.java:93)
……
现在专门说一下对CommandBasedWSHumanTaskHandler的使用。个人感觉现在的这个类还不适用于生产环境,本人在使用的时候遇到了以下问题:
1流程实例启动后,服务器(PS,HTS)都一直操持运行状态,运行正常。
2流程实例启动后,T1待用户执行,运行ksession.despose()方法,再重新通过
JPAKnowledgeService.loadStatefulKnowledgeSession( sessionId, kaAdeptor.getKnowledgeBase(), null, env );
将ksession加载回来。后执行T1的complete方法,结果报异常:
ERROR [SingleSessionCommandService] Could not commit session
java.lang.NullPointerException
at org.drools.persistence.jpa.JpaPersistenceContextManager.beginCommandScopedEntityManager(JpaPersistenceContextManager.java:67)
at org.drools.persistence.SingleSessionCommandService.execute(SingleSessionCommandService.java:287)
at org.drools.command.impl.CommandBasedStatefulKnowledgeSession$1.abortWorkItem(CommandBasedStatefulKnowledgeSession.java:155)
at org.jbpm.process.workitem.wsht.CommandBasedWSHumanTaskHandler$GetCompletedTaskResponseHandler.execute(CommandBasedWSHumanTaskHandler.java:263)
……
如果将CommandBasedWSHumanTaskHandler做一下小的改动,加入public void setKsession(KnowledgeRuntime session);在ksession被load回来之后,将以前的
ksession.getWorkItemManager().registerWorkItemHandler("Human Task", new CommandBasedWSHumanTaskHandler(ksession));
改为
hadler.setSsession(ksession);
ksession.getWorkItemManager().registerWorkItemHandler("Human Task", handler);
注意这个handler是使用最原始的那个ksession实例化好的。这样程序才能正常运行。也就是说Handler在实例化后不能销毁掉,否则流程不能正常流转。这也正说明了下面这种情况。
3流程实例启动后,重启PS和HTS,complete任务T1后,T2的任务不能正常生成。
由上,大家在使用这个类的时候要注意这些问题。
如果需要在生产环境下使用jbpm-human-task,则应该使用他所提供的JMS机制的组件,但经测试也还存在bug,且版本服务器上的最新代码这一块也有了很大的改动,据开发者说也有问题。那就是还要等更新的版本了。