Jdbc Mule junit测试和内存中嵌入式数据库:无法处理上下文

Jdbc Mule junit测试和内存中嵌入式数据库:无法处理上下文,jdbc,mule,derby,h2,Jdbc,Mule,Derby,H2,我正在向遗留项目添加测试。该项目使用ApacheCommons的BasicDataSource定义JDBC数据源。我已经对其进行了更新,以便在从mvn verify运行时,URL(来自测试属性文件)指定H2连接字符串。我的测试通过了,但在拆卸过程中,在处理MuleContext时会引发异常,导致我的所有测试都报告为失败 我当前的解决方法是在@After方法中设置muleContext=null,以避免清除引发异常的调度程序池。这是一种极端的黑客行为,但它似乎确实起了作用。所以我想知道如何更好地解

我正在向遗留项目添加测试。该项目使用ApacheCommons的BasicDataSource定义JDBC数据源。我已经对其进行了更新,以便在从
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运行?是的,这样可以防止问题发生,直到最后一次拆卸。这是我最初的解决方法(与@AfterClass
muleContext=null
结合使用)。当前的解决方案更好,因为它为每个测试提供了一个清晰的H2实例。但这并不是我所说的修复:对象池似乎仍在某种程度上被破坏。我可能会考虑提供一个SpringJUnit4MuleTestRunner,并避免扩展FunctionalTestCase,这并不是Spring的工作方式。好吧,我想你的下一步行动是与MuleSoft建立一个JIRA来报告问题,然后得到一个真正的修复。