运行 同一应用程序中的两个 Tomcat 服务器在 MBean 注册上失败

Running two Tomcat servers in the same application fails on MBean registration

我正在尝试在同一个应用程序中 运行 两个嵌入式 Tomcat 服务器,但我一直收到一个异常,即 "Tomcat" 名称已经注册为 MBean。 运行 两个 Tomcat 服务器在两个不同的进程中工作得很好。就在我尝试在单个进程中 运行 两个 Tomcat 服务器时。

我有理由不想在同一个 Tomcat 服务器实例中创建两个连接器,简而言之,我正在 运行 需要启动三个服务器的单元测试,我想要运行 三个独立的服务器,因为这就是现实世界中 运行 的方式,而不是在具有多个连接器的单个服务器中。

我想知道是否有任何方法可以更改 Tomcat 服务器用于 MBean 注册的名称,或者甚至完全关闭整个 MBean 注册?

作为记录,下面是我在同一进程中启动两个 Tomcat 实例时获得的堆栈跟踪:

SEVERE: Error registering Tomcat:j2eeType=Servlet,name=gor,WebModule=//localhost/gorserver,J2EEApplication=none,J2EEServer=none
javax.management.InstanceAlreadyExistsException: Tomcat:j2eeType=Servlet,name=gor,WebModule=//localhost/gorserver,J2EEApplication=none,J2EEServer=none
    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:522)
    at org.apache.tomcat.util.modeler.Registry.registerComponent(Registry.java:742)
    at org.apache.catalina.util.LifecycleMBeanBase.register(LifecycleMBeanBase.java:158)
    at org.apache.catalina.util.LifecycleMBeanBase.initInternal(LifecycleMBeanBase.java:61)
    at org.apache.catalina.core.ContainerBase.initInternal(ContainerBase.java:1080)
    at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:136)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5508)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1571)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1561)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

Aug 30, 2016 2:20:57 AM org.apache.catalina.util.LifecycleMBeanBase register
WARNING: Failed to register object [StandardEngine[Tomcat].StandardHost[localhost].StandardContext[/gorserver].StandardWrapper[gor]] with name [Tomcat:j2eeType=Servlet,name=gor,WebModule=//localhost/gorserver,J2EEApplication=none,J2EEServer=none] during component initialisation
javax.management.InstanceAlreadyExistsException: Tomcat:j2eeType=Servlet,name=gor,WebModule=//localhost/gorserver,J2EEApplication=none,J2EEServer=none
    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:522)
    at org.apache.tomcat.util.modeler.Registry.registerComponent(Registry.java:742)
    at org.apache.catalina.util.LifecycleMBeanBase.register(LifecycleMBeanBase.java:158)
    at org.apache.catalina.util.LifecycleMBeanBase.initInternal(LifecycleMBeanBase.java:61)
    at org.apache.catalina.core.ContainerBase.initInternal(ContainerBase.java:1080)
    at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:136)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5508)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1571)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1561)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

最终发现可以通过为添加到 Tomcat 服务器的每个上下文提供唯一名称(例如,添加要添加到的服务器的端口号)来解决此问题:

context.setName("MyServerContext_" + httpPort);

这导致 MBean 具有不同的名称。