Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Failed to Unregister DataSource JMX MBean While Shutting Down a Spring Boot Application

I have a simple Spring Boot application using org.apache.commons.dbcp2.BasicDataSource as dataSource bean.

The data source is exposed as MBean automatically by Spring boot.

The bean declaration:

@Bean
public DataSource dataSource() {
    BasicDataSource dataSource = new BasicDataSource();
    dataSource.setUrl(dbUrl);
    dataSource.setDriverClassName(jdbcDriver);
    dataSource.setUsername(dbUserName);
    dataSource.setPassword(dbPassword);
    return dataSource;
}

Everything works fine . However, I see error while shutting down the application. This error only occurs when running the executable jar. When using Gradle Spring plugin (gradle bootRun), this is not shown.

javax.management.InstanceNotFoundException: org.apache.commons.dbcp2:name=dataSource,type=BasicDataSource
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.getMBean(DefaultMBeanServerInterceptor.java:1095)
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.exclusiveUnregisterMBean(DefaultMBeanServerInterceptor.java:427)
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.unregisterMBean(DefaultMBeanServerInterceptor.java:415)
    at com.sun.jmx.mbeanserver.JmxMBeanServer.unregisterMBean(JmxMBeanServer.java:546)
    at org.apache.commons.dbcp2.BasicDataSource.close(BasicDataSource.java:1822)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.springframework.beans.factory.support.DisposableBeanAdapter.invokeCustomDestroyMethod(DisposableBeanAdapter.java:350)
    at org.springframework.beans.factory.support.DisposableBeanAdapter.destroy(DisposableBeanAdapter.java:273)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:540)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:516)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingleton(DefaultListableBeanFactory.java:827)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:485)
    at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:921)
    at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:895)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.doClose(EmbeddedWebApplicationContext.java:152)
    at org.springframework.context.support.AbstractApplicationContext$1.run(AbstractApplicationContext.java:809)

I am wondering, 1. How does this bean get exposed as JMX MBean? 2. How to properly unregister this MBean?

like image 201
jlai Avatar asked Jul 25 '14 03:07

jlai


2 Answers

Spring is trying to close BasicDataSource twice:

  1. BasicDataSource close itself automatically when application close
  2. Spring use default destroy method to close DataSource but it's already closed

To avoid this, use:

@Bean(destroyMethod = "")
public DataSource dataSource() 

In your Java Configuration

like image 83
Marcon Avatar answered Sep 19 '22 04:09

Marcon


I ran into the same problem. Adding an MBean server and registering the datasource can not fix it either.

http://docs.spring.io/spring/docs/current/spring-framework-reference/html/jmx.html

My conclusion is that DBCP2's BasicDataSource has a bug at unregistering itself from the MBean server.

I fixed mine by switching to mchange's c3p0: http://www.mchange.com/projects/c3p0/

like image 26
user832462 Avatar answered Sep 20 '22 04:09

user832462