在 tomcat 容器中具有多个 Web 应用程序的 Spring Boot 执行器引发 javax.management.InstanceAlreadyExistsException 异常

Posted

技术标签:

【中文标题】在 tomcat 容器中具有多个 Web 应用程序的 Spring Boot 执行器引发 javax.management.InstanceAlreadyExistsException 异常【英文标题】:Spring Boot actuator with multiple web applications in a tomcat container throws javax.management.InstanceAlreadyExistsException exception 【发布时间】:2015-01-10 04:36:02 【问题描述】:

我在一个 tomcat 容器内运行多个 Spring Boot 应用程序(不是嵌入式的 - 只是独立的 tomcat 容器)。但是,它在启动 Web 应用程序时给了我以下异常。它不会影响任何 Web 应用程序的功能,但仍然是我想解决的问题,以实现干净的启动。

非常感谢任何有关如何解决此问题的帮助。

使用 Spring Boot 1.1.7

org.springframework.jmx.export.UnableToRegisterMBeanException: Unable to register MBean [org.springframework.boot.actuate.endpoint.jmx.DataEndpointMBean@14bee2f1] wit
h key 'metricsEndpoint'; nested exception is javax.management.InstanceAlreadyExistsException: org.springframework.boot:type=Endpoint,name=metricsEndpoint
        at org.springframework.jmx.export.MBeanExporter.registerBeanNameOrInstance(MBeanExporter.java:609)
        at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.registerEndpoint(EndpointMBeanExporter.java:162)
        at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.locateAndRegisterEndpoints(EndpointMBeanExporter.java:142)
        at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.doStart(EndpointMBeanExporter.java:134)
        at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.start(EndpointMBeanExporter.java:257)
        at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:173)
        at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:51)
        at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:346)
        at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:149)
        at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:112)
        at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:775)
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.finishRefresh(EmbeddedWebApplicationContext.java:131)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:485)
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:109)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
        at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:142)

org.springframework.jmx.export.UnableToRegisterMBeanException: Unable to register MBean [org.springframework.boot.actuate.endpoint.jmx.DataEndpointMBean@1be9493f] with key 'traceEndpoint'; nested exception is javax.management.InstanceAlreadyExistsException: org.springframework.boot:type=Endpoint,name=traceEndpoint
        at org.springframework.jmx.export.MBeanExporter.registerBeanNameOrInstance(MBeanExporter.java:609)
        at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.registerEndpoint(EndpointMBeanExporter.java:162)
        at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.locateAndRegisterEndpoints(EndpointMBeanExporter.java:142)
        at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.doStart(EndpointMBeanExporter.java:134)
        at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.start(EndpointMBeanExporter.java:257)
        at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:173)
        at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:51)
        at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:346)

org.springframework.jmx.export.UnableToRegisterMBeanException: Unable to register MBean [org.springframework.boot.actuate.endpoint.jmx.DataEndpointMBean@533a21cd] with key 'dumpEndpoint'; nested exception is javax.management.InstanceAlreadyExistsException: org.springframework.boot:type=Endpoint,name=dumpEndpoint
        at org.springframework.jmx.export.MBeanExporter.registerBeanNameOrInstance(MBeanExporter.java:609)
        at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.registerEndpoint(EndpointMBeanExporter.java:162)
        at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.locateAndRegisterEndpoints(EndpointMBeanExporter.java:142)
        at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.doStart(EndpointMBeanExporter.java:134)
        at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.start(EndpointMBeanExporter.java:257)
        at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:173)
        at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:51)
        at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:346)
        at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:149)

org.springframework.jmx.export.UnableToRegisterMBeanException: Unable to register MBean [org.springframework.boot.actuate.endpoint.jmx.DataEndpointMBean@695b578c] with key 'autoConfigurationAuditEndpoint'; nested exception is javax.management.InstanceAlreadyExistsException: org.springframework.boot:type=Endpoint,name=autoConfigurationAuditEndpoint
        at org.springframework.jmx.export.MBeanExporter.registerBeanNameOrInstance(MBeanExporter.java:609)
        at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.registerEndpoint(EndpointMBeanExporter.java:162)
        at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.locateAndRegisterEndpoints(EndpointMBeanExporter.java:142)
        at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.doStart(EndpointMBeanExporter.java:134)
        at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.start(EndpointMBeanExporter.java:257)
        at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:173)
        at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:51)
        at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:346)
        at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:149)

org.springframework.jmx.export.UnableToRegisterMBeanException: Unable to register MBean [org.springframework.boot.actuate.endpoint.jmx.ShutdownEndpointMBean@7271ef13] with key 'shutdownEndpoint'; nested exception is javax.management.InstanceAlreadyExistsException: org.springframework.boot:type=Endpoint,name=shutdownEndpoint
        at org.springframework.jmx.export.MBeanExporter.registerBeanNameOrInstance(MBeanExporter.java:609)
        at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.registerEndpoint(EndpointMBeanExporter.java:162)
        at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.locateAndRegisterEndpoints(EndpointMBeanExporter.java:142)
        at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.doStart(EndpointMBeanExporter.java:134)
        at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.start(EndpointMBeanExporter.java:257)
        at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:173)
        at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:51)

org.springframework.jmx.export.UnableToRegisterMBeanException: Unable to register MBean [org.springframework.boot.actuate.endpoint.jmx.DataEndpointMBean@34ea9086] with key 'configurationPropertiesReportEndpoint'; nested exception is javax.management.InstanceAlreadyExistsException: org.springframework.boot:type=Endpoint,name=configurationPropertiesReportEndpoint
        at org.springframework.jmx.export.MBeanExporter.registerBeanNameOrInstance(MBeanExporter.java:609)
        at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.registerEndpoint(EndpointMBeanExporter.java:162)
        at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.locateAndRegisterEndpoints(EndpointMBeanExporter.java:142)
        at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.doStart(EndpointMBeanExporter.java:134)
        at org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter.start(EndpointMBeanExporter.java:257)
        at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:173)
        at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:51)
        at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:346)
        at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:149)

【问题讨论】:

默认情况下,所有端点都在域 org.springboot 下注册并使用默认名称。这些可以通过设置endpoints.jmx.* 属性来覆盖。见here。您可能想要更改每个应用程序的域或将endpoints.jmx.unique-name 设置为true @M.Deinum - 非常感谢。将 unique-name 设置为 true 就可以了。端点现在将注册为什么?另外,如果您可以将此添加为答案,我会接受它,以便对其他人也有帮助。再次感谢! 我不知道实际名称是什么,可能取决于使用的底层策略。您可能需要查看 Spring Boot 的端点注册部分。 【参考方案1】:

默认情况下,所有端点都在域org.springboot 下注册并使用默认名称。这些可以通过设置endpoints.jmx.* 属性来覆盖。见here。

您可能希望更改每个应用程序的域或将 endpoints.jmx.unique-names 设置为 true。

【讨论】:

【参考方案2】:

通过添加以下属性在 application.properties 中禁用 JMX

spring.jmx.enabled = false

【讨论】:

这将使应用程序运行但不会解决问题 请参阅下面@bigbadmouse 的答案,以更详细地了解其工作原理。它帮助了我。就我而言,我在尝试运行单元测试时得到了InstanceAlreadyExistsException,因此我将spring.jmx.enabled = false 行添加到我的src/test/resources/application.properties 文件中。【参考方案3】:

唯一名称对我不起作用。我还必须添加一个默认域。

这是我的 yml 代码

spring:
  jmx:
    default-domain: agentservice

endpoints: 
  jmx:
    domain: agentservice
    unique-names: true

【讨论】:

【参考方案4】:

为了补充我投票赞成的 Gondy 的答案,下面是一个链接,正是说明了它的工作原理。 PhilWebb 说 “事实证明,如果您使用 Spring 的测试上下文框架,默认注册 JMX 信息会导致一些问题。.. 默认情况下,使用 @ContextConfiguration 的测试保持上下文打开”“我认为我们需要将 spring.datasource.jmx-enabled 更改为默认为 false 并使其选择加入"

见GitHub(在“philwebb 于 2014 年 11 月 7 日发表评论”)


我很欣赏这不是一个独特的答案。但是这个问题已经困扰了我一段时间,Gondy 的回答帮助了我,然后我发现了原因并想以我唯一可用的方式分享这些额外的信息

【讨论】:

感谢您的解释,@Gondy 的回答也对我有所帮助,但我希望他能添加更多信息。这很有帮助。【参考方案5】:
spring:
  jmx:
    default-domain: agentservice

endpoints: 
  jmx:
    domain: agentservice
    unique-names: true

在同一个 JVM 上部署多个实例时与我一起使用上述配置

【讨论】:

【参考方案6】:

在单个 Tomcat 服务器上部署多个 web 应用程序(在我的情况下为 Spring Boot)时,由于 javax.management.InstanceAlreadyExistsException,我收到了这个错误 org.springframework.jmx.export.UnableToRegisterMBeanException。 在网上搜索了一番后,我发现了这个: “spring.jmx.enabled 设置为 true(默认值),上下文中的任何 MBean bean 都将自动注册到 JMX 服务器。” 来源:https://github.com/spring-projects/spring-boot/issues/9179

选项是:

Option-1) 设置 spring.jmx.enabled=false 来源:https://github.com/spring-projects/spring-boot/issues/9179

选项 2) 为每个部署的 web 应用程序为 JMX bean 提供唯一的名称 spring.jmx.default-domain:app1 spring.jmx.default-domain: app2 来源:https://github.com/jhipster/generator-jhipster/issues/874

Option-3) 在每个 webapp 中更改 bean 本身的名称 @豆 公共数据源 app1DataSource() ... @豆 公共数据源 app2DataSource() ...

【讨论】:

以上是关于在 tomcat 容器中具有多个 Web 应用程序的 Spring Boot 执行器引发 javax.management.InstanceAlreadyExistsException 异常的主要内容,如果未能解决你的问题,请参考以下文章

tomcat: 类加载器

使用Tomcat在Eclipse中运行Web服务的多个上下文具有相同路径错误

tomcat工作原理

Tomcat多层容器的设计

Linux中tomcat

tomcat初始化web.xml