micrometer info health example check actuator java spring jmx spring-boot spring-jmx

java - info - Error al anular el registro del MBS de DataSource JMX al cerrar una aplicación Spring Boot



spring boot info endpoint (4)

Tengo una aplicación Spring Boot simple que utiliza org.apache.commons.dbcp2.BasicDataSource como bean DataSource.

El origen de datos se expone como MBean automáticamente por Spring Boot.

La declaración de frijol:

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

Todo funciona bien. Sin embargo, veo un error al cerrar la aplicación. Este error solo ocurre al ejecutar el jar ejecutable. Cuando se utiliza el complemento Gradle Spring (gradle bootRun), esto no se muestra.

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)

Me pregunto: 1. ¿Cómo se expone este bean como JMX MBean? 2. ¿Cómo anular correctamente el registro de este MBean?


Spring está intentando cerrar BasicDataSource dos veces:

  1. BasicDataSource se cierra automáticamente cuando se cierra la aplicación
  2. Spring usa el método de destrucción predeterminado para cerrar DataSource pero ya está cerrado

Para evitar esto, use:

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

En su configuración de Java



Tuve el mismo problema. c3p0 funciona muy bien.

si se utiliza spring framework - pom.xml

<!-- https://mvnrepository.com/artifact/com.mchange/c3p0 --> <dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> <version>0.9.5.2</version> </dependency>

inicialmente utilizado

DataSource ds_unpooled = DataSources.unpooledDataSource(persistenceUrl, persistenceUsername, persistencePassword); return DataSources.pooledDataSource(ds_unpooled);

pero no pudo manejar la carga que necesito realizar y cambié a la siguiente

ComboPooledDataSource cpds = new ComboPooledDataSource(); cpds.setDriverClass( persistenceDriver ); //loads the jdbc driver cpds.setJdbcUrl( persistenceUrl ); cpds.setUser(persistenceUsername); cpds.setPassword(persistencePassword); cpds.setMinPoolSize(5); cpds.setMaxPoolSize(50); cpds.setUnreturnedConnectionTimeout(1800); cpds.setMaxStatements(50); cpds.setMaxIdleTime(21600); cpds.setIdleConnectionTestPeriod(10800); return cpds;

esos valores son de otras publicaciones que he reunido en línea.

en mi experiencia para mi tarea específica, ejecutar c3p0 se realiza más rápido que dbcp2 v: 2.1.1 en el mismo entorno.

Espero que esto ayude un poco. ¡aclamaciones!


BasicDataSource extends BasicDataSourceMXBean , por lo que se registra automáticamente con el servidor JMX como MBean [org.apache.commons.dbcp2:name=dataSource,type=BasicDataSource] . Cuando Springboot se detiene, MBeanExporter anula el registro del MBean, luego springboot intenta destruir BasicDataSource , y llama al método BasicDataSource close() , anula el registro del MBean nuevamente (BasicDataSource detecta la excepción JMException e imprime esta advertencia). Es solo una advertencia. Si no desea imprimirlo, puede desactivar JMX en springboot.

application.yml spring: jmx: enabled: false