Jdbc Mule junit测试和内存中嵌入式数据库:无法处理上下文
我正在向遗留项目添加测试。该项目使用ApacheCommons的BasicDataSource定义JDBC数据源。我已经对其进行了更新,以便在从Jdbc Mule junit测试和内存中嵌入式数据库:无法处理上下文,jdbc,mule,derby,h2,Jdbc,Mule,Derby,H2,我正在向遗留项目添加测试。该项目使用ApacheCommons的BasicDataSource定义JDBC数据源。我已经对其进行了更新,以便在从mvn verify运行时,URL(来自测试属性文件)指定H2连接字符串。我的测试通过了,但在拆卸过程中,在处理MuleContext时会引发异常,导致我的所有测试都报告为失败 我当前的解决方法是在@After方法中设置muleContext=null,以避免清除引发异常的调度程序池。这是一种极端的黑客行为,但它似乎确实起了作用。所以我想知道如何更好地解
mvn verify
运行时,URL(来自测试属性文件)指定H2连接字符串。我的测试通过了,但在拆卸过程中,在处理MuleContext时会引发异常,导致我的所有测试都报告为失败
我当前的解决方法是在@After
方法中设置muleContext=null
,以避免清除引发异常的调度程序池。这是一种极端的黑客行为,但它似乎确实起了作用。所以我想知道如何更好地解决这个问题
例外情况是:
ERROR 2014-01-23 09:51:32,632 [Thread-1] org.mule.DefaultMuleContext: Failed to stop Mule context
org.mule.api.lifecycle.LifecycleException: null
at org.mule.lifecycle.AbstractLifecycleManager.invokePhase(AbstractLifecycleManager.java:156)
at org.mule.transport.ConnectorLifecycleManager.fireStopPhase(ConnectorLifecycleManager.java:78)
at org.mule.transport.AbstractConnector.stop(AbstractConnector.java:518)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.mule.lifecycle.phases.DefaultLifecyclePhase.applyLifecycle(DefaultLifecyclePhase.java:225)
at org.mule.lifecycle.RegistryLifecycleManager$RegistryLifecycleCallback.onTransition(RegistryLifecycleManager.java:276)
at org.mule.lifecycle.RegistryLifecycleManager.invokePhase(RegistryLifecycleManager.java:155)
at org.mule.lifecycle.RegistryLifecycleManager.fireLifecycle(RegistryLifecycleManager.java:126)
at org.mule.registry.AbstractRegistryBroker.fireLifecycle(AbstractRegistryBroker.java:80)
at org.mule.registry.MuleRegistryHelper.fireLifecycle(MuleRegistryHelper.java:120)
at org.mule.lifecycle.MuleContextLifecycleManager$MuleContextLifecycleCallback.onTransition(MuleContextLifecycleManager.java:94)
at org.mule.lifecycle.MuleContextLifecycleManager$MuleContextLifecycleCallback.onTransition(MuleContextLifecycleManager.java:90)
at org.mule.lifecycle.MuleContextLifecycleManager.invokePhase(MuleContextLifecycleManager.java:72)
at org.mule.lifecycle.MuleContextLifecycleManager.fireLifecycle(MuleContextLifecycleManager.java:64)
at org.mule.DefaultMuleContext.stop(DefaultMuleContext.java:272)
at org.mule.DefaultMuleContext.dispose(DefaultMuleContext.java:282)
at org.mule.tck.junit4.AbstractMuleContextTestCase.disposeContext(AbstractMuleContextTestCase.java:262)
at org.mule.tck.junit4.AbstractMuleContextTestCase.disposeContextPerTest(AbstractMuleContextTestCase.java:251)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:37)
at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:46)
at org.junit.internal.runners.statements.FailOnTimeout$1.run(FailOnTimeout.java:28)
Caused by: java.lang.NullPointerException
at org.apache.commons.pool.impl.GenericKeyedObjectPool$ObjectQueue.access$900(GenericKeyedObjectPool.java:2140)
at org.apache.commons.pool.impl.GenericKeyedObjectPool.clear(GenericKeyedObjectPool.java:1333)
at org.mule.transport.DefaultConfigurableKeyedObjectPool.clear(DefaultConfigurableKeyedObjectPool.java:80)
at org.mule.transport.AbstractConnector.clearDispatchers(AbstractConnector.java:819)
at org.mule.transport.AbstractConnector$3.onTransition(AbstractConnector.java:546)
at org.mule.transport.AbstractConnector$3.onTransition(AbstractConnector.java:519)
at org.mule.lifecycle.AbstractLifecycleManager.invokePhase(AbstractLifecycleManager.java:141)
... 30 more
我已经创建了一个显示问题的最小流。将任何消息发送到vm://startTest
,流将正确地将42插入测试表中。数据源目前配置为使用H2。我还用Derby验证了这一点,并在注释中包含了该配置
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:vm="http://www.mulesoft.org/schema/mule/vm" xmlns:jms="http://www.mulesoft.org/schema/mule/jms"
xmlns:jdbc-ee="http://www.mulesoft.org/schema/mule/ee/jdbc"
xmlns="http://www.mulesoft.org/schema/mule/core"
xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
version="EE-3.3.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.mulesoft.org/schema/mule/vm http://www.mulesoft.org/schema/mule/vm/current/mule-vm.xsd
http://www.mulesoft.org/schema/mule/jms http://www.mulesoft.org/schema/mule/jms/current/mule-jms.xsd
http://www.mulesoft.org/schema/mule/ee/jdbc http://www.mulesoft.org/schema/mule/ee/jdbc/current/mule-jdbc-ee.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd "
>
<spring:bean class="org.apache.commons.dbcp.BasicDataSource" id="dataSource">
<spring:property name="driverClassName" value="org.h2.Driver" />
<spring:property name="url" value="jdbc:h2:mem:test;MODE=Oracle" />
<spring:property name="validationQuery" value="SELECT 1 FROM DUAL" />
<!--
<spring:property name="driverClassName" value="org.apache.derby.jdbc.EmbeddedDriver" />
<spring:property name="url" value="jdbc:derby:memory:test;create=true" />
<spring:property name="validationQuery" value="values 1" />
-->
<spring:property name="testOnBorrow" value="true" />
</spring:bean>
<spring:bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<spring:constructor-arg ref="h2DataSource" />
</spring:bean>
<jdbc-ee:connector name="jdbcConnector"
dataSource-ref="dataSource" validateConnections="true"
queryTimeout="-1" pollingFrequency="0">
</jdbc-ee:connector>
<flow name="query-insert">
<vm:inbound-endpoint path="startTest"/>
<jdbc-ee:outbound-endpoint
exchange-pattern="request-response" queryKey="putvalues"
queryTimeout="-1" connector-ref="jdbcConnector">
<jdbc-ee:query key="putvalues"
value="insert into TEST_TABLE (A_NUMBER) values (42)" />
</jdbc-ee:outbound-endpoint>
</flow>
</mule>
如果要运行此流,可以在测试之前调用必要的DDL:jdbcTemplate.update(“createtablettest\utable(A_NUMBER int)”代码>
我正在使用Mule ESB 3.3.1、H2 1.3.174和Derby 10.6.1.0(由Mule提供)进行测试
我假设我遇到了Derby一节中的提示警告的问题,但是该页面上建议的解决方案(使用jdbc:Derby数据源)是不可接受的,因为这需要我修改一个工作的Mule配置文件。我很乐意重新实现jdbc:derby数据源提供的任何解决方案,但我不知道该解决方案是什么 将Mule配置文件分为两部分(DB connector和flows),这样您就可以在第三个文件中为测试定义不同的数据源,并将其与包含流的文件一起加载。是的,我会在我拥有这种优势的项目中这样做,如果可以,我也会在这里这样做。这个问题是,这次我不能:相关文件在许多项目之间共享,我没有更改它的权限。此外,我使用了derby数据源提出的解决方案,但没有任何帮助。目前,muleContext=null
hack是唯一对我有效的解决方法。。这看起来像一个真正的错误;Mule代码被添加为发布Mule-4553的解决方案。如果我对commons池和Mule如何使用GenericKeyedObjectPool有更多的了解,我很乐意为此提供一个解决方案。我不认为access$900错误有什么好的原因,另外还有一些讨厌的代码,在不同的对象上嵌套同步。好的,或者你是否尝试过使用setDisposeContextPerClass
在整个功能测试中保持MuleContext运行?是的,这样可以防止问题发生,直到最后一次拆卸。这是我最初的解决方法(与@AfterClassmuleContext=null
结合使用)。当前的解决方案更好,因为它为每个测试提供了一个清晰的H2实例。但这并不是我所说的修复:对象池似乎仍在某种程度上被破坏。我可能会考虑提供一个SpringJUnit4MuleTestRunner,并避免扩展FunctionalTestCase,这并不是Spring的工作方式。好吧,我想你的下一步行动是与MuleSoft建立一个JIRA来报告问题,然后得到一个真正的修复。