Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 关闭Spring启动应用程序时,无法注销数据源JMX MBean_Java_Spring_Jmx_Spring Boot_Spring Jmx - Fatal编程技术网

Java 关闭Spring启动应用程序时,无法注销数据源JMX MBean

Java 关闭Spring启动应用程序时,无法注销数据源JMX MBean,java,spring,jmx,spring-boot,spring-jmx,Java,Spring,Jmx,Spring Boot,Spring Jmx,我有一个简单的Spring启动应用程序,它使用org.apache.commons.dbcp2.BasicDataSource作为数据源bean Spring boot会自动将数据源公开为MBean bean声明: @Bean public DataSource dataSource() { BasicDataSource dataSource = new BasicDataSource(); dataSource.setUrl(dbUrl); dataSource.se

我有一个简单的Spring启动应用程序,它使用org.apache.commons.dbcp2.BasicDataSource作为数据源bean

Spring boot会自动将数据源公开为MBean

bean声明:

@Bean
public DataSource dataSource() {
    BasicDataSource dataSource = new BasicDataSource();
    dataSource.setUrl(dbUrl);
    dataSource.setDriverClassName(jdbcDriver);
    dataSource.setUsername(dbUserName);
    dataSource.setPassword(dbPassword);
    return dataSource;
}
一切正常。但是,我在关闭应用程序时看到错误。此错误仅在运行可执行jar时发生。当使用Gradle Spring插件(Gradle bootRun)时,不会显示这一点

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)
我在想, 1.这个bean如何作为JMX MBean公开?
2.如何正确注销此MBean?

我遇到了同样的问题。添加MBean服务器并注册数据源也无法修复它

我的结论是,DBCP2的BasicDataSource在从MBean服务器注销自身时存在缺陷

我通过切换到McChange的c3p0修复了我的问题: 我也有同样的问题。 c3p0工作得很好

如果使用
spring框架
-pom.xml

<!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
<dependency>
   <groupId>com.mchange</groupId>
   <artifactId>c3p0</artifactId>
   <version>0.9.5.2</version>
</dependency>
但它无法处理我需要执行的负载,并切换到以下内容

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;
这些值来自我在网上收集的其他帖子

根据我在具体任务中的经验,在相同环境下运行c3p0比dbcp2 v:2.1.1执行得更快

希望这有点帮助。
干杯

Spring尝试关闭源两次:

  • BasicDataSource在应用程序关闭时自动关闭自身
  • Spring使用默认销毁方法关闭数据源,但它已经关闭
  • 要避免这种情况,请使用:

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

    在Java配置中,BasicDataSource扩展了BasicDataSourceMXBean,因此它在JMX服务器上自动注册为MBean
    [org.apache.commons.dbcp2:name=dataSource,type=BasicDataSource]
    。当springboot关闭时,MBeanExporter注销MBean,然后springboot尝试销毁
    BasicDataSource
    ,并调用BasicDataSource的方法
    close()
    ,再次注销MBean(BasicDataSource捕获JMException,并打印此警告)。这只是一个警告。如果不想打印,可以在springboot中禁用JMX

    application.yml
    spring:
    jmx:
    enabled: false
    

    这似乎与开机无关。数据源本身尝试从JMX域注销,但失败。查看数据源类型文档怎么样?顺便问一下,为什么不能使用boot提供的基础设施?我偶然发现了这个问题,因为我遇到了同样的问题。这实际上不是一个错误-日志将该情况报告为警告。至于为什么不使用启动数据源,我敢打赌OP想要微调连接池,如果您没有在容器中运行(容器将为您提供池),您实际上不会从启动中获得池连接(SimpleDriverDataSource实际上不会给您池连接)。我很想知道如何用DBCP2解决这个问题,但如果它只是一个在关机时出现的警告,我就不会太担心它了。这来自Spring。正如@Will所说,这只是一个警告。BasicDataSource试图注销,但已被Spring注销(MBeanExporter中的destroy()。这就解决了我的问题,在服务器关闭期间没有更多的堆栈跟踪工作正常,也解决了我的问题
    application.yml
    spring:
    jmx:
    enabled: false