diff --git a/spring-integration-jmx/src/main/java/org/springframework/integration/jmx/config/MBeanExporterParser.java b/spring-integration-jmx/src/main/java/org/springframework/integration/jmx/config/MBeanExporterParser.java
index 1337250856..75c9889fa0 100644
--- a/spring-integration-jmx/src/main/java/org/springframework/integration/jmx/config/MBeanExporterParser.java
+++ b/spring-integration-jmx/src/main/java/org/springframework/integration/jmx/config/MBeanExporterParser.java
@@ -13,6 +13,8 @@
package org.springframework.integration.jmx.config;
+import java.util.UUID;
+
import javax.management.MBeanServerFactory;
import org.w3c.dom.Element;
@@ -26,12 +28,14 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
+import org.springframework.integration.monitor.IntegrationMBeanExporter;
import org.springframework.util.StringUtils;
/**
* Parser for the 'mbean-export' element of the integration JMX namespace.
*
* @author Mark Fisher
+ * @author Gary Russell
* @since 2.0
*/
public class MBeanExporterParser extends AbstractSingleBeanDefinitionParser {
@@ -46,7 +50,7 @@ public class MBeanExporterParser extends AbstractSingleBeanDefinitionParser {
@Override
protected String getBeanClassName(Element element) {
- return "org.springframework.integration.monitor.IntegrationMBeanExporter";
+ return IntegrationMBeanExporter.class.getName();
}
@Override
@@ -85,6 +89,10 @@ public class MBeanExporterParser extends AbstractSingleBeanDefinitionParser {
" (clashes with default). Please choose another bean id.",
definition);
}
+ if (id.matches(IntegrationMBeanExporter.class.getName() + "#[0-9]+")) {
+ // Randomize the name in case there are multiple contexts in the same JVM
+ id += "#" + UUID.randomUUID();
+ }
return id;
}
diff --git a/spring-integration-jmx/src/main/java/org/springframework/integration/monitor/IntegrationMBeanExporter.java b/spring-integration-jmx/src/main/java/org/springframework/integration/monitor/IntegrationMBeanExporter.java
index e9d9e079f4..f2621dda66 100644
--- a/spring-integration-jmx/src/main/java/org/springframework/integration/monitor/IntegrationMBeanExporter.java
+++ b/spring-integration-jmx/src/main/java/org/springframework/integration/monitor/IntegrationMBeanExporter.java
@@ -90,6 +90,7 @@ import org.springframework.util.ReflectionUtils;
* @author Dave Syer
* @author Helena Edelson
* @author Oleg Zhurakousky
+ * @author Gary Russell
*/
@ManagedResource
public class IntegrationMBeanExporter extends MBeanExporter implements BeanPostProcessor, BeanFactoryAware,
@@ -516,7 +517,8 @@ public class IntegrationMBeanExporter extends MBeanExporter implements BeanPostP
// Expose the raw bean if it is managed
MessageChannel bean = monitor.getMessageChannel();
if (assembler.includeBean(bean.getClass(), monitor.getName())) {
- registerBeanInstance(bean, monitor.getName());
+ registerBeanInstance(bean,
+ this.getMonitoredIntegrationObjectBeanKey(bean, name));
}
}
}
@@ -539,7 +541,8 @@ public class IntegrationMBeanExporter extends MBeanExporter implements BeanPostP
// Expose the raw bean if it is managed
MessageHandler bean = source.getMessageHandler();
if (assembler.includeBean(bean.getClass(), source.getName())) {
- registerBeanInstance(bean, monitor.getName());
+ registerBeanInstance(bean,
+ this.getMonitoredIntegrationObjectBeanKey(bean, name));
}
}
}
@@ -562,7 +565,8 @@ public class IntegrationMBeanExporter extends MBeanExporter implements BeanPostP
// Expose the raw bean if it is managed
MessageSource> bean = source.getMessageSource();
if (assembler.includeBean(bean.getClass(), source.getName())) {
- registerBeanInstance(bean, monitor.getName());
+ registerBeanInstance(bean,
+ this.getMonitoredIntegrationObjectBeanKey(bean, name));
}
}
}
@@ -688,6 +692,11 @@ public class IntegrationMBeanExporter extends MBeanExporter implements BeanPostP
return String.format(domain + ":type=ManagedEndpoint,name=%s,bean=%s" + getStaticNames(), name, source);
}
+ private String getMonitoredIntegrationObjectBeanKey(Object object, String name) {
+ // This ordering of keys seems to work with default settings of JConsole
+ return String.format(domain + ":type=" + object.getClass().getSimpleName() + ",name=%s" + getStaticNames(), name);
+ }
+
private String getStaticNames() {
if (objectNameStaticProperties.isEmpty()) {
return "";
diff --git a/spring-integration-jmx/src/test/java/org/springframework/integration_/mbeanexporterhelper/Int2307Tests.java b/spring-integration-jmx/src/test/java/org/springframework/integration_/mbeanexporterhelper/Int2307Tests.java
index 397bc40b8c..de1a6e5b80 100644
--- a/spring-integration-jmx/src/test/java/org/springframework/integration_/mbeanexporterhelper/Int2307Tests.java
+++ b/spring-integration-jmx/src/test/java/org/springframework/integration_/mbeanexporterhelper/Int2307Tests.java
@@ -12,27 +12,57 @@
*/
package org.springframework.integration_.mbeanexporterhelper;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
import java.util.Set;
-import org.junit.Test;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.ObjectInstance;
-import org.springframework.context.ApplicationContext;
+import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.jmx.export.MBeanExporter;
-import static org.junit.Assert.assertTrue;
-
/**
* @author Oleg Zhurakousky
+ * @author Gary Russell
*
*/
public class Int2307Tests {
@Test
public void testInt2307_DefaultMBeanExporter() throws Exception{
- ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("single-config.xml", this.getClass());
- context.destroy();
+ new ClassPathXmlApplicationContext("single-config.xml", this.getClass());
+ List servers = MBeanServerFactory.findMBeanServer(null);
+ assertEquals(1, servers.size());
+ MBeanServer server = servers.get(0);
+ Set mbeans = server.queryMBeans(null, null);
+ int bits = 0;
+ int count = 0;
+ for (ObjectInstance mbean : mbeans) {
+ if (mbean.toString().startsWith("org.springframework.integration.router.RecipientListRouter[test.domain:type=RecipientListRouter,name=rlr,random=")) {
+ bits |= 1;
+ count++;
+ } else if (mbean.toString().startsWith("org.springframework.integration.monitor.LifecycleMessageHandlerMetrics[test.domain:type=MessageHandler,name=rlr,bean=endpoint,random=")) {
+ bits |= 2;
+ count++;
+ } else if (mbean.toString().startsWith("org.springframework.integration.router.HeaderValueRouter[test.domain:type=HeaderValueRouter,name=hvr,random=")) {
+ bits |= 4;
+ count++;
+ } else if (mbean.toString().startsWith("org.springframework.integration.monitor.LifecycleMessageHandlerMetrics[test.domain:type=MessageHandler,name=hvr,bean=endpoint,random=")) {
+ bits |= 8;
+ count++;
+ }
+ }
+ assertEquals(0xf, bits);
+ assertEquals(4, count);
+
+ // make sure there are no duplicate MBean ObjectNames if 2 contexts loaded from same config
+ new ClassPathXmlApplicationContext("single-config.xml", this.getClass());
}
@SuppressWarnings("unchecked")
@@ -46,7 +76,6 @@ public class Int2307Tests {
assertTrue(excludedBeanNames.contains("x"));
assertTrue(excludedBeanNames.contains("y"));
assertTrue(excludedBeanNames.contains("foo")); // non SI bean
- context.destroy();
}
public static class Foo{}
diff --git a/spring-integration-jmx/src/test/java/org/springframework/integration_/mbeanexporterhelper/single-config-custom-exporter.xml b/spring-integration-jmx/src/test/java/org/springframework/integration_/mbeanexporterhelper/single-config-custom-exporter.xml
index 670e34a37a..a3b926d6b3 100644
--- a/spring-integration-jmx/src/test/java/org/springframework/integration_/mbeanexporterhelper/single-config-custom-exporter.xml
+++ b/spring-integration-jmx/src/test/java/org/springframework/integration_/mbeanexporterhelper/single-config-custom-exporter.xml
@@ -3,15 +3,24 @@
xmlns:context="http://www.springframework.org/schema/context"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-jmx="http://www.springframework.org/schema/integration/jmx"
+ xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.1.xsd
http://www.springframework.org/schema/integration/jmx http://www.springframework.org/schema/integration/jmx/spring-integration-jmx-2.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
-
-
+
+
+
+ #{new java.util.Random().nextInt()}
+ test
+
+
diff --git a/spring-integration-jmx/src/test/java/org/springframework/integration_/mbeanexporterhelper/single-config.xml b/spring-integration-jmx/src/test/java/org/springframework/integration_/mbeanexporterhelper/single-config.xml
index fffedc1c31..4dd3005e3a 100644
--- a/spring-integration-jmx/src/test/java/org/springframework/integration_/mbeanexporterhelper/single-config.xml
+++ b/spring-integration-jmx/src/test/java/org/springframework/integration_/mbeanexporterhelper/single-config.xml
@@ -3,14 +3,24 @@
xmlns:context="http://www.springframework.org/schema/context"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-jmx="http://www.springframework.org/schema/integration/jmx"
+ xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.1.xsd
http://www.springframework.org/schema/integration/jmx http://www.springframework.org/schema/integration/jmx/spring-integration-jmx-2.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
-
+
+
+
+ #{new java.util.Random().nextInt()}
+ test
+
+