Maven test Exception:Another resource already exists with name xxx 已经解决

来源:互联网 发布:line聊天软件 官方网站 编辑:程序博客网 时间:2024/04/30 09:21

1、问题:

在run as Maven test出现以上Exception。

项目集成了spring+atomikos jta

主要原因是所有的单元测试类都继承了BaseTest,本来是为了方便每次单元测试前都可以获取ApplicationContext,其部分源码如下:

public class BaseTest {
    ...
    private static ApplicationContext context;

    @BeforeClass
    public static void initContext() {
        context = new FileSystemXmlApplicationContext("src/main/webapp/WEB-INF/spring-config.xml"); 
    }

    protected ApplicationContext getContext() {
        return context;
    }
    ...
}

如果没有用atomikos jta是没问题的,但事与愿违,出现了此Exception


2、原因:

从atomikos找到了明白了原因:

This happens if you accidentally instantiate two connectors with the same value for uniqueResourceName. A common example is if you include spring config files multiple times within the same VM: Spring will then create all the beans more than once - and this is problematic for recovery. An example of this problem is here: javax.naming.NamingException: Another resource already exists...

附链接:http://www.atomikos.com/Documentation/KnownProblems#JNDI_Error_Another_resource_alre

意思是多次加载了spring配置文件时spring在上下文中多次创建了beans,即在同一个VM中创建了多个dataSource,就违背了每个dataSource必须uniqueResourceName的规定,

so异常就出现啦。


3、解决方案:

只要在没个单元测试类运行结束之后关闭连接就OK啦,附上修改后的BaseTest部分源码:

public class BaseTest {
    ...
    private static ApplicationContext context;

    @BeforeClass
    public static void initContext() {
        context = new FileSystemXmlApplicationContext("src/main/webapp/WEB-INF/spring-config.xml"); 
    }

    /**
     * 必须在每个单元测试类运行结束之后关闭连接,
     * 要不会出现Another resource already exists with name xxx一次
     */
    @AfterClass
    public static void destroyTransaction() {
        AtomikosDataSourceBean webds = (AtomikosDataSourceBean)context.getBean("webDataSource");
        AtomikosDataSourceBean ds = (AtomikosDataSourceBean)context.getBean("dataSource");
        webds.close();
        ds.close();
    }

    public ApplicationContext getContext() {
        return context;
    }
    ...
}

希望能帮到遇到同一个问题的朋友啦。最后附上部分spring配置文件:

...

<bean id="webDataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean"  init-method="init" destroy-method="close">   
        <description>web mysql xa datasource</description>   
        <property name="uniqueResourceName">   
            <value>web_ds</value>   
        </property>   
        <property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" />   
        <property name="xaProperties">   
            <props>   
                <prop key="user">${database.user}</prop>   
                <prop key="password">${database.password}</prop>   
                <prop key="URL">${database.jdbcUrl}</prop>   
            </props>   
        </property>   
        <property name="poolSize" value="${database.maxPoolSize}"/>    

</bean>   

<bean id="dataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean"  init-method="init" destroy-method="close">   
<description>admin mysql xa datasource</description>   
        <property name="uniqueResourceName">   
            <value>admin_ds</value>   
        </property>   
        <property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" />   
        <property name="xaProperties">   
            <props>   
                <prop key="user">${admin.database.user}</prop>   
                <prop key="password">${admin.database.password}</prop>   
                <prop key="URL">${admin.database.jdbcUrl}</prop>   
            </props>   
        </property>   
        <property name="poolSize" value="${database.maxPoolSize}"/>    
</bean>   

...


1 0
原创粉丝点击