Spring-boot: org.springframework.jmx.export.UnableToRegisterMBeanException

Created on 12 May 2017  路  1Comment  路  Source: spring-projects/spring-boot

I config two jndi datasource in tomcat

<Resource name="jdbc/web"
        auth="Container"
        type="javax.sql.DataSource"
        factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
        singleton = "false"
        testWhileIdle="true"
        testOnBorrow="true"
        testOnReturn="false"
        validationQuery="SELECT 1"
        timeBetweenEvictionRunsMillis="30000"
        maxActive="15"
        maxIdle="10"
        minIdle="5"
        removeAbandonedTimeout="60"
        removeAbandoned="false"
        logAbandoned="true"
        minEvictableIdleTimeMillis="30000"
        jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"
        username="unicpqarchive"
        password="huawei123"
        driverClassName="oracle.jdbc.driver.OracleDriver"
        url="jdbc:oracle:thin:XXXX"/>

<Resource name="jdbc/web"
        auth="Container"
        type="javax.sql.DataSource"
        factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
        singleton = "false"
        testWhileIdle="true"
        testOnBorrow="true"
        testOnReturn="false"
        validationQuery="SELECT 1"
        timeBetweenEvictionRunsMillis="30000"
        maxActive="15"
        maxIdle="10"
        minIdle="5"
        removeAbandonedTimeout="60"
        removeAbandoned="false"
        logAbandoned="true"
        minEvictableIdleTimeMillis="30000"
        jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"
        username="unicpq"
        password="huawei123"
        driverClassName="oracle.jdbc.driver.OracleDriver"
        url="jdbc:oracle:thin:@ABC/>

web.xml config

    <resource-ref>
        <res-ref-name>jdbc/unicpq</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
    </resource-ref>

    <resource-ref>
        <res-ref-name>jdbc/unicpqarchive</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
    </resource-ref>

application.properties config

#archive data source
datasource.archive.jndi=java:comp/env/jdbc/unicpqarchive

#config data source
datasource.config.jndi=java:comp/env/jdbc/unicpq

JAVA CODE

    @Primary
    @Profile( "prod" )
    @Bean( name = "configDataSource" )
    @ConditionalOnMissingBean(name="configDataSource")
    public DataSource getConfigJndiDataSource( @Value( "${datasource.config.jndi}" ) String jndiName ) throws Exception
    {
        JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
        DataSource dataSource = dataSourceLookup.getDataSource( jndiName );
        return dataSource;
    }

    @Profile( "prod" )
    @Bean( name = "archiveDataSource" )
    @ConditionalOnMissingBean(name = "archiveDataSource"  )
    public DataSource getArchiveJndiDataSource( @Value( "${datasource.archive.jndi}" ) String jndiName )
            throws Exception
    {
        JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
        DataSource dataSource = dataSourceLookup.getDataSource( jndiName );
        return dataSource;
    }

I deploy war in tomcat8, I get some exceptions

12-May-2017 14:58:56.288 INFO [localhost-startStop-1] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
12-May-2017 14:59:09.597 SEVERE [localhost-startStop-1] org.apache.catalina.core.ContainerBase.addChildInternal ContainerBase.addChild: start: 
 org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/cpqconfig]]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:162)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:753)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:729)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:717)
    at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:940)
    at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1816)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:722)
Caused by: org.springframework.jmx.export.UnableToRegisterMBeanException: Unable to register MBean [org.apache.tomcat.dbcp.dbcp2.BasicDataSource@883a73] with key 'archiveDataSource'; nested exception is javax.management.InstanceAlreadyExistsException: Catalina:type=DataSource,host=localhost,context=/cpqconfig,class=javax.sql.DataSource,name="jdbc/unicpqarchive"
    at org.springframework.jmx.export.MBeanExporter.registerBeanNameOrInstance(MBeanExporter.java:628)
    at org.springframework.jmx.export.MBeanExporter.registerBeans(MBeanExporter.java:550)
    at org.springframework.jmx.export.MBeanExporter.afterSingletonsInstantiated(MBeanExporter.java:432)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:781)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:370)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:314)
    at org.springframework.boot.web.support.SpringBootServletInitializer.run(SpringBootServletInitializer.java:151)
    at org.springframework.boot.web.support.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:131)
    at org.springframework.boot.web.support.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:86)
    at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:169)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5303)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
    ... 11 more
Caused by: javax.management.InstanceAlreadyExistsException: Catalina:type=DataSource,host=localhost,context=/cpqconfig,class=javax.sql.DataSource,name="jdbc/unicpqarchive"
    at com.sun.jmx.mbeanserver.Repository.addMBean(Repository.java:437)
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerWithRepository(DefaultMBeanServerInterceptor.java:1898)
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerDynamicMBean(DefaultMBeanServerInterceptor.java:966)
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerObject(DefaultMBeanServerInterceptor.java:900)
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerMBean(DefaultMBeanServerInterceptor.java:324)
    at com.sun.jmx.mbeanserver.JmxMBeanServer.registerMBean(JmxMBeanServer.java:513)
    at org.springframework.jmx.support.MBeanRegistrationSupport.doRegister(MBeanRegistrationSupport.java:195)
    at org.springframework.jmx.export.MBeanExporter.registerBeanInstance(MBeanExporter.java:674)
    at org.springframework.jmx.export.MBeanExporter.registerBeanNameOrInstance(MBeanExporter.java:618)
    ... 26 more

12-May-2017 14:59:09.645 SEVERE [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployWAR Error deploying web application archive E:\developtool\apache-tomcat-8.0.43-x86\webapps\cpqconfig.war
 java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/cpqconfig]]
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:757)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:729)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:717)
    at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:940)
    at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1816)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:722)
stackoverflow invalid

Most helpful comment

With spring.jmx.enabled set to true (the default), any beans in the context that are MBeans will be automatically registered with the JMX server. This fails because Tomcat has already registered them. You have a few options:

  1. Set spring.jmx.enabled=false
  2. Exclude the bean from being exported as we do in our own JNDI DataSource configuration
  3. Use application.properties and @Bean methods to configure your data sources directly rather than using JNDI

In the future, please ask this sort of question on Stack Overflow or Gitter. As mentioned in the guidelines for contributing, we prefer to use GitHub issues only for bugs and enhancements.

>All comments

With spring.jmx.enabled set to true (the default), any beans in the context that are MBeans will be automatically registered with the JMX server. This fails because Tomcat has already registered them. You have a few options:

  1. Set spring.jmx.enabled=false
  2. Exclude the bean from being exported as we do in our own JNDI DataSource configuration
  3. Use application.properties and @Bean methods to configure your data sources directly rather than using JNDI

In the future, please ask this sort of question on Stack Overflow or Gitter. As mentioned in the guidelines for contributing, we prefer to use GitHub issues only for bugs and enhancements.

Was this page helpful?
0 / 5 - 0 ratings