java 迁移到 Tomcat 8:InstanceAlreadyExistsException 数据源

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28295503/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 13:21:00  来源:igfitidea点击:

Migration to Tomcat 8: InstanceAlreadyExistsException datasource

javatomcatconfigurationcontext.xml

提问by Vadim R

I have a question about context config in Tomcat 8. I migrating project from Tomcat 7 to 8 and have unusual problem: if nothing change in config I caught an error:

我有一个关于 Tomcat 8 中的上下文配置的问题。我将项目从 Tomcat 7 迁移到 8 并且遇到了不寻常的问题:如果配置中没有任何变化,我发现了一个错误:

    "2015-02-03 12:05:48,310 FIRST_ADMIN ERROR web.context.ContextLoader:331 
-> Context initialization failed org.springframework.jmx.export.UnableToRegisterMBeanException: 
    Unable to register MBean [org.apache.tomcat.dbcp.dbcp2.BasicDataSource@434990dd]
     with key 'dataSource'; nested exception is 
    javax.management.InstanceAlreadyExistsException:  
    Catalina:type=DataSource,host=localhost,context=/first-
    admin,class=javax.sql.DataSource,name="jdbc/datasource/first"

Part of context:

部分上下文:

<Resource name="jdbc/datasource/first"
              auth="Container"
              type="javax.sql.DataSource"
              poolPreparedStatements="true"
              initialSize="25"
              maxActive="100"
              maxIdle="100"
              minIdle="25"
              username="us"
              password="pa"
              driverClassName="com.mysql.jdbc.Driver"
              validationQuery="select 1"
              testOnBorrow="true"
          url="jdbc:mysql://localhost:3306/firstproject?useUnicode=true&amp;characterEncoding=UTF-8&amp;profileSQL=false&amp;autoSlowLog=false&amp;slowQueryThresholdMillis=100&amp;autoReconnect=true"/>

So, it's works in tomcat 7 without any problem. In Tomcat 8 I can solve this problem in 2 ways:

所以,它在 tomcat 7 中没有任何问题。在 Tomcat 8 中,我可以通过两种方式解决这个问题:

  1. By adding to resource: singleton = "false";
  2. By adding to resource: factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
  1. 通过添加到资源: singleton = "false";
  2. 通过添加到资源: factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"

If I clearly understand tomcat creates datasource for my app and for jmx, but in Tomcat 7 it was single object, in Tomcat 8 it must be different. So my question is why that situation has happened? I couldn't find any information of this change in documentation. And I'm interesting what is better: create single datasource (I think so) or create several by factory.

如果我清楚地理解 tomcat 为我的应用程序和 jmx 创建数据源,但在 Tomcat 7 中它是单个对象,在 Tomcat 8 中它必须不同。所以我的问题是为什么会发生这种情况?我在文档中找不到有关此更改的任何信息。我很感兴趣什么更好:创建单个数据源(我认为是)或由工厂创建多个。

回答by Radi Radichev

We had the same problem. We declared our data source as a spring bean, and it looks like both spring and the bean itself try to register an Mbean which leads to this conflict. All we had to do is configure our Mbean Exporter like this:

我们遇到了同样的问题。我们将数据源声明为 spring bean,看起来 spring 和 bean 本身都试图注册导致此冲突的 Mbean。我们所要做的就是像这样配置我们的 Mbean 导出器:

@Bean
public AnnotationMBeanExporter annotationMBeanExporter() {
    AnnotationMBeanExporter annotationMBeanExporter = new AnnotationMBeanExporter();
    annotationMBeanExporter.addExcludedBean("dataSource");
    return annotationMBeanExporter;
}

Although I suppose setting the registration policy to:

虽然我想将注册策略设置为:

annotationMBeanExporter.setRegistrationPolicy(RegistrationPolicy.IGNORE_EXISTING);

might also work.

也可能工作。

回答by Andreas

I had the same error and resolved it by adding registration="ignoreExisting"to the mbean-export part:

我遇到了同样的错误,并通过将registration="ignoreExisting"添加到 mbean-export 部分来解决它:

<context:mbean-export server="mbeanServer" default-domain="mydomain" registration="ignoreExisting" />

回答by Hazemdido

If you want the solution using annotations Spring boot already defines MBeanExporterbean so you can auto-wire on it

如果你想要使用注解的解决方案 Spring boot 已经定义了MBeanExporterbean,所以你可以自动连接它

@Autowired
MBeanExporter mBeanExporter ;

Then change the registration policy

然后更改注册策略

mBeanExporter.setRegistrationPolicy(RegistrationPolicy.IGNORE_EXISTING);

回答by brightmatter

If anybody uses applicationContext.xmlstyle out there, I solved the issue like this:

如果有人在那里使用applicationContext.xml样式,我解决了这样的问题:

<bean id="myNamedExporter" class="org.springframework.jmx.export.MBeanExporter">
    <property name="registrationPolicy" value="IGNORE_EXISTING" />
</bean>