关于JbpmContext关闭时的tx services问题怎么解决呢?

elice 2008-04-23
JbpmContext关闭时出错是如何产生的,应该怎么解决呢?
在jbpm-starter-kit-3.1.4的例子中运行是正常的,
到我自己写的工程中运行却出错,拜托于朋友们!

[ERROR] problem closing service 'persistence'
org.jbpm.JbpmException: no jbpm tx service configured
	at org.jbpm.persistence.db.DbPersistenceService.isRollbackOnly(DbPersistenceService.java:395)
	at org.jbpm.persistence.db.DbPersistenceService.close(DbPersistenceService.java:213)
	at org.jbpm.svc.Services.close(Services.java:225)
	at org.jbpm.JbpmContext.close(JbpmContext.java:139)
	at elicex.jbpm.sample.v2.HelloWorldDatabase.deployProcessDefinition(HelloWorldDatabase.java:51)
	at elicex.jbpm.sample.v2.HelloWorldDatabase.testHelloWorldDatabaseProcess(HelloWorldDatabase.java:36)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:585)
	at junit.framework.TestCase.runTest(TestCase.java:168)
	at junit.framework.TestCase.runBare(TestCase.java:134)
	at junit.framework.TestResult$1.protect(TestResult.java:110)
	at junit.framework.TestResult.runProtected(TestResult.java:128)
	at junit.framework.TestResult.run(TestResult.java:113)
	at junit.framework.TestCase.run(TestCase.java:124)
	at junit.framework.TestSuite.runTest(TestSuite.java:232)
	at junit.framework.TestSuite.run(TestSuite.java:227)
	at org.junit.internal.runners.OldTestClassRunner.run(OldTestClassRunner.java:76)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:38)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)


程序代码
// elicex@gmail.com <Apr 22, 2008>
package elicex.jbpm.sample.v2;

import java.util.List;

import junit.framework.TestCase;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jbpm.JbpmConfiguration;
import org.jbpm.JbpmContext;
import org.jbpm.db.GraphSession;
import org.jbpm.graph.def.ProcessDefinition;
import org.jbpm.graph.exe.ProcessInstance;
import org.jbpm.graph.exe.Token;

//@SuppressWarnings("deprecation")
public class HelloWorldDatabase extends TestCase {
	private static final Log log = LogFactory.getLog(HelloWorldDatabase.class);
	private static JbpmConfiguration jbpmConfiguration = null;
	static {
		jbpmConfiguration = JbpmConfiguration
				.parseInputStream(HelloWorldDatabase.class
						.getResourceAsStream("jbpm.cfg.xml"));
	}

	protected void setUp() throws Exception {
		jbpmConfiguration.createSchema();
	}

	protected void tearDown() throws Exception {
		jbpmConfiguration.dropSchema();
	}

	public void testHelloWorldDatabaseProcess() {
		deployProcessDefinition();
		processInstanceIsCreatedWhenUserSubmitsWebappForm();
		theProcessInstanceContinuesWhenAnAsyncMessageIsReceived();
	}

	public void deployProcessDefinition() {
		// 从XML中获取流程定义
		ProcessDefinition processDefinition = ProcessDefinition
				.parseXmlInputStream(getClass().getResourceAsStream(
						"Definition.xml"));
		// 持久化流程定义
		JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
		try {
			jbpmContext.deployProcessDefinition(processDefinition);
		} finally {
			jbpmContext.close();
		}
		log.info("### delopyProcessDefinition done!");
	}

	public void processInstanceIsCreatedWhenUserSubmitsWebappForm() {
		JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
		try {
			GraphSession graphSession = jbpmContext.getGraphSession();
			// 从数据库中获取流程定义
			ProcessDefinition processDefinition = graphSession
					.findLatestProcessDefinition("helloWorld");
			// 构建流程实例
			ProcessInstance processInstance = new ProcessInstance(
					processDefinition);
			// 获取根令牌
			Token token = processInstance.getRootToken();
			assertEquals("start", token.getNode().getName());
			// 发出信号
			token.signal();
			assertEquals("middle", token.getNode().getName());
			// 持久化流程实例
			jbpmContext.save(processInstance);
		} finally {
			jbpmContext.close();
		}
		log.info("### processInstanceIsCreatedWhenUserSubmitsWebappForm done!");
	}

//	@SuppressWarnings("unchecked")
	public void theProcessInstanceContinuesWhenAnAsyncMessageIsReceived() {
		JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
		try {
			GraphSession graphSession = jbpmContext.getGraphSession();
			// 从数据库中获取流程定义
			ProcessDefinition processDefinition = graphSession
					.findLatestProcessDefinition("helloWorld");
			// 获取流程实例集合
			List processInstances = graphSession
					.findProcessInstances(processDefinition.getId());
			ProcessInstance processInstance = (ProcessInstance) processInstances.get(0);
			// 发出信号
			processInstance.signal();
			assertTrue(processInstance.hasEnded());
			// 持久化流程实例
			jbpmContext.save(processInstance);
		} finally {
			jbpmContext.close();
		}
		log.info("### theProcessInstanceContinues"
				+ "WhenAnAsyncMessageIsReceived done!");
	}
}

配置文件jbpm.cfg.xml
<jbpm-configuration>
	<jbpm-context>
		<service name='persistence'
			factory='org.jbpm.persistence.db.DbPersistenceServiceFactory' />
	</jbpm-context>
	<string name='resource.hibernate.cfg.xml' value='hibernate.cfg.xml' />
	<string name='resource.business.calendar'
		value='org/jbpm/calendar/jbpm.business.calendar.properties' />
	<string name='resource.default.modules'
		value='org/jbpm/graph/def/jbpm.default.modules.properties' />
	<string name='resource.converter'
		value='org/jbpm/db/hibernate/jbpm.converter.properties' />
	<string name='resource.action.types'
		value='org/jbpm/graph/action/action.types.xml' />
	<string name='resource.node.types'
		value='org/jbpm/graph/node/node.types.xml' />
	<string name='resource.varmapping'
		value='org/jbpm/context/exe/jbpm.varmapping.xml' />
</jbpm-configuration>

配置文件Definition.xml
<process-definition name="helloWorld">
	<start-state name="start">
		<transition to="middle" />
	</start-state>
	<state name="middle">
		<transition to="end" />
	</state>
	<end-state name="end" />
</process-definition>
zhoden 2008-04-24
elice 写道
JbpmContext关闭时出错是如何产生的,应该怎么解决呢?
在jbpm-starter-kit-3.1.4的例子中运行是正常的,
到我自己写的工程中运行却出错,拜托于朋友们!

[ERROR] problem closing service 'persistence'
org.jbpm.JbpmException: no jbpm tx service configured
	at org.jbpm.persistence.db.DbPersistenceService.isRollbackOnly(DbPersistenceService.java:395)
	at org.jbpm.persistence.db.DbPersistenceService.close(DbPersistenceService.java:213)
	at org.jbpm.svc.Services.close(Services.java:225)
	at org.jbpm.JbpmContext.close(JbpmContext.java:139)
	at elicex.jbpm.sample.v2.HelloWorldDatabase.deployProcessDefinition(HelloWorldDatabase.java:51)
	at elicex.jbpm.sample.v2.HelloWorldDatabase.testHelloWorldDatabaseProcess(HelloWorldDatabase.java:36)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:585)
	at junit.framework.TestCase.runTest(TestCase.java:168)
	at junit.framework.TestCase.runBare(TestCase.java:134)
	at junit.framework.TestResult$1.protect(TestResult.java:110)
	at junit.framework.TestResult.runProtected(TestResult.java:128)
	at junit.framework.TestResult.run(TestResult.java:113)
	at junit.framework.TestCase.run(TestCase.java:124)
	at junit.framework.TestSuite.runTest(TestSuite.java:232)
	at junit.framework.TestSuite.run(TestSuite.java:227)
	at org.junit.internal.runners.OldTestClassRunner.run(OldTestClassRunner.java:76)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:38)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)


程序代码
// elicex@gmail.com <Apr 22, 2008>
package elicex.jbpm.sample.v2;

import java.util.List;

import junit.framework.TestCase;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jbpm.JbpmConfiguration;
import org.jbpm.JbpmContext;
import org.jbpm.db.GraphSession;
import org.jbpm.graph.def.ProcessDefinition;
import org.jbpm.graph.exe.ProcessInstance;
import org.jbpm.graph.exe.Token;

//@SuppressWarnings("deprecation")
public class HelloWorldDatabase extends TestCase {
	private static final Log log = LogFactory.getLog(HelloWorldDatabase.class);
	private static JbpmConfiguration jbpmConfiguration = null;
	static {
		jbpmConfiguration = JbpmConfiguration
				.parseInputStream(HelloWorldDatabase.class
						.getResourceAsStream("jbpm.cfg.xml"));
	}

	protected void setUp() throws Exception {
		jbpmConfiguration.createSchema();
	}

	protected void tearDown() throws Exception {
		jbpmConfiguration.dropSchema();
	}

	public void testHelloWorldDatabaseProcess() {
		deployProcessDefinition();
		processInstanceIsCreatedWhenUserSubmitsWebappForm();
		theProcessInstanceContinuesWhenAnAsyncMessageIsReceived();
	}

	public void deployProcessDefinition() {
		// 从XML中获取流程定义
		ProcessDefinition processDefinition = ProcessDefinition
				.parseXmlInputStream(getClass().getResourceAsStream(
						"Definition.xml"));
		// 持久化流程定义
		JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
		try {
			jbpmContext.deployProcessDefinition(processDefinition);
		} finally {
			jbpmContext.close();
		}
		log.info("### delopyProcessDefinition done!");
	}

	public void processInstanceIsCreatedWhenUserSubmitsWebappForm() {
		JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
		try {
			GraphSession graphSession = jbpmContext.getGraphSession();
			// 从数据库中获取流程定义
			ProcessDefinition processDefinition = graphSession
					.findLatestProcessDefinition("helloWorld");
			// 构建流程实例
			ProcessInstance processInstance = new ProcessInstance(
					processDefinition);
			// 获取根令牌
			Token token = processInstance.getRootToken();
			assertEquals("start", token.getNode().getName());
			// 发出信号
			token.signal();
			assertEquals("middle", token.getNode().getName());
			// 持久化流程实例
			jbpmContext.save(processInstance);
		} finally {
			jbpmContext.close();
		}
		log.info("### processInstanceIsCreatedWhenUserSubmitsWebappForm done!");
	}

//	@SuppressWarnings("unchecked")
	public void theProcessInstanceContinuesWhenAnAsyncMessageIsReceived() {
		JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
		try {
			GraphSession graphSession = jbpmContext.getGraphSession();
			// 从数据库中获取流程定义
			ProcessDefinition processDefinition = graphSession
					.findLatestProcessDefinition("helloWorld");
			// 获取流程实例集合
			List processInstances = graphSession
					.findProcessInstances(processDefinition.getId());
			ProcessInstance processInstance = (ProcessInstance) processInstances.get(0);
			// 发出信号
			processInstance.signal();
			assertTrue(processInstance.hasEnded());
			// 持久化流程实例
			jbpmContext.save(processInstance);
		} finally {
			jbpmContext.close();
		}
		log.info("### theProcessInstanceContinues"
				+ "WhenAnAsyncMessageIsReceived done!");
	}
}

配置文件jbpm.cfg.xml
<jbpm-configuration>
	<jbpm-context>
		<service name='persistence'
			factory='org.jbpm.persistence.db.DbPersistenceServiceFactory' />
	</jbpm-context>
	<string name='resource.hibernate.cfg.xml' value='hibernate.cfg.xml' />
	<string name='resource.business.calendar'
		value='org/jbpm/calendar/jbpm.business.calendar.properties' />
	<string name='resource.default.modules'
		value='org/jbpm/graph/def/jbpm.default.modules.properties' />
	<string name='resource.converter'
		value='org/jbpm/db/hibernate/jbpm.converter.properties' />
	<string name='resource.action.types'
		value='org/jbpm/graph/action/action.types.xml' />
	<string name='resource.node.types'
		value='org/jbpm/graph/node/node.types.xml' />
	<string name='resource.varmapping'
		value='org/jbpm/context/exe/jbpm.varmapping.xml' />
</jbpm-configuration>

配置文件Definition.xml
<process-definition name="helloWorld">
	<start-state name="start">
		<transition to="middle" />
	</start-state>
	<state name="middle">
		<transition to="end" />
	</state>
	<end-state name="end" />
</process-definition>


deployProcessDefinition();
processInstanceIsCreatedWhenUserSubmitsWebappForm();
theProcessInstanceContinuesWhenAnAsyncMessageIsReceived();
这三个方法里,都有关闭jbpm容器上下文,在tearDown方法中,关闭试试
elice 2008-04-24
按 zhoden 的方法试了一下,这个方法只是将出错的时间推迟了,tx services 关闭时的问题却并没有解决,查找一下 jbpmContent 中的 services 不是 null, 这个 tx services 是什么呢?为什么在官方的例子中沒有出错,而自己写的程序却有错误呢?应该是配置问题,因为直接把官方的例程COPY到我的工程之中,也是这样的
jiadong 2008-04-24
no jbpm tx service configured

if(jbpmContext!=null) jbpmContext.close();
elice 2008-04-24
后来在老外的网站上终于把问题的原因找到了,原来3.2版比3.1版的配置文件多了一个配置项目,加上这个配置项目之后就OK了

<service name="tx" factory="org.jbpm.tx.TxServiceFactory">

因为是按照开发指南的例子写了一个jbpm.cfg.xml,缺少这一条,所以就造成了这个情况。一般来说,jbpm.cfg.xml其实可以不用写的,jbpm会自动使用org.jbpm包下的default.jbpm.cfg.xml作为配置文件来启动整个jbpm服务。

终于弄明白了
liangfeifei 2008-04-28
今天也碰到了这个问题,按照你的方法,我的问题也解决了,太感谢了
skyfly2424 2008-04-29
jbpm.cfg.xml 文件中的DbPersistenceServiceFactory 配子是否有问题呀
elice 2008-04-29
在org.jbpm包下有一个default.jbpm.cfg.xml这是默认的配置文件