From e23e478e9eeed32004425d88d6da23ee91e657d8 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 10 Dec 2010 12:20:05 +0100 Subject: [PATCH] INT-1675: force initialization of other MBeanExporter instances before the integration monitor components are created --- .../jmx/config/MBeanExporterParser.java | 6 ++- .../monitor/IntegrationMBeanExporter.java | 50 +++++++++---------- .../jmx/config/RouterMBeanTests-context.xml | 17 +++---- .../jmx/config/RouterMBeanTests.java | 40 ++++++++++++--- .../config/RouterMBeanTestsNone-context.xml | 25 ++++++++++ .../config/RouterMBeanTestsSwitch-context.xml | 25 ++++++++++ 6 files changed, 117 insertions(+), 46 deletions(-) create mode 100644 spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/RouterMBeanTestsNone-context.xml create mode 100644 spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/RouterMBeanTestsSwitch-context.xml 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 a4048240b1..f34b3cab30 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 @@ -31,7 +31,11 @@ import org.w3c.dom.Element; */ public class MBeanExporterParser extends AbstractSingleBeanDefinitionParser { - private static final String ILLEGAL_NAME = "mbeanExporter"; + /** + * + */ + private static final String MBEAN_EXPORTER_NAME = "mbeanExporter"; + private static final String ILLEGAL_NAME = MBEAN_EXPORTER_NAME; @Override protected boolean shouldGenerateIdAsFallback() { 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 e91d080869..1315fe0b1e 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 @@ -83,14 +83,13 @@ import org.springframework.util.ReflectionUtils; * @author Oleg Zhurakousky */ @ManagedResource -public class IntegrationMBeanExporter extends MBeanExporter - implements BeanPostProcessor, BeanFactoryAware, BeanClassLoaderAware, SmartLifecycle { +public class IntegrationMBeanExporter extends MBeanExporter implements BeanPostProcessor, BeanFactoryAware, + BeanClassLoaderAware, SmartLifecycle { private static final Log logger = LogFactory.getLog(IntegrationMBeanExporter.class); public static final String DEFAULT_DOMAIN = "org.springframework.integration"; - private final AnnotationJmxAttributeSource attributeSource = new AnnotationJmxAttributeSource(); private ListableBeanFactory beanFactory; @@ -125,7 +124,6 @@ public class IntegrationMBeanExporter extends MBeanExporter private final Map objectNameStaticProperties = new HashMap(); - public IntegrationMBeanExporter() { super(); // Shouldn't be necessary, but to be on the safe side... @@ -134,7 +132,6 @@ public class IntegrationMBeanExporter extends MBeanExporter setAssembler(new MetadataMBeanInfoAssembler(attributeSource)); } - @Override public void setBeanClassLoader(ClassLoader classLoader) { this.beanClassLoader = classLoader; @@ -183,8 +180,7 @@ public class IntegrationMBeanExporter extends MBeanExporter Object advised = applyHandlerInterceptor(bean, monitor, beanClassLoader); handlers.add(monitor); return advised; - } - else if (bean instanceof MessageSource) { + } else if (bean instanceof MessageSource) { SimpleMessageSourceMetrics monitor = new SimpleMessageSourceMetrics((MessageSource) bean); Object advised = applySourceInterceptor(bean, monitor, beanClassLoader); sources.add(monitor); @@ -197,12 +193,10 @@ public class IntegrationMBeanExporter extends MBeanExporter Object target = extractTarget(bean); if (target instanceof QueueChannel) { monitor = new QueueChannelMetrics((QueueChannel) target, beanName); - } - else { + } else { monitor = new PollableChannelMetrics(beanName); } - } - else { + } else { monitor = new DirectChannelMetrics(beanName); } Object advised = applyChannelInterceptor(bean, monitor, beanClassLoader); @@ -233,8 +227,7 @@ public class IntegrationMBeanExporter extends MBeanExporter this.lifecycleLock.lock(); try { return this.running; - } - finally { + } finally { this.lifecycleLock.unlock(); } } @@ -249,8 +242,7 @@ public class IntegrationMBeanExporter extends MBeanExporter logger.info("started " + this); } } - } - finally { + } finally { this.lifecycleLock.unlock(); } } @@ -265,8 +257,7 @@ public class IntegrationMBeanExporter extends MBeanExporter logger.info("stopped " + this); } } - } - finally { + } finally { this.lifecycleLock.unlock(); } } @@ -276,8 +267,7 @@ public class IntegrationMBeanExporter extends MBeanExporter try { this.stop(); callback.run(); - } - finally { + } finally { this.lifecycleLock.unlock(); } } @@ -295,6 +285,16 @@ public class IntegrationMBeanExporter extends MBeanExporter registerSources(); } + @Override + public void afterPropertiesSet() { + super.afterPropertiesSet(); + /* + * Force early initialization of other MBeanExporters. Workaround for possible bug in Spring (see INT-1675) for + * more details. + */ + beanFactory.getBeansOfType(MBeanExporter.class); + } + @Override public void destroy() { super.destroy(); @@ -457,8 +457,7 @@ public class IntegrationMBeanExporter extends MBeanExporter } try { return extractTarget(advised.getTargetSource().getTarget()); - } - catch (Exception e) { + } catch (Exception e) { logger.error("Could not extract target", e); return null; } @@ -470,8 +469,7 @@ public class IntegrationMBeanExporter extends MBeanExporter if (bean instanceof Advised) { ((Advised) bean).addAdvisor(advisor); return bean; - } - else { + } else { ProxyFactory proxyFactory = new ProxyFactory(bean); proxyFactory.addAdvisor(advisor); return proxyFactory.getProxy(beanClassLoader); @@ -531,8 +529,7 @@ public class IntegrationMBeanExporter extends MBeanExporter Object field = null; try { field = extractTarget(getField(endpoint, "handler")); - } - catch (Exception e) { + } catch (Exception e) { logger.trace("Could not get handler from bean = " + beanName); } if (field == monitor.getMessageHandler()) { @@ -551,8 +548,7 @@ public class IntegrationMBeanExporter extends MBeanExporter if (targetSource != null) { try { target = targetSource.getTarget(); - } - catch (Exception e) { + } catch (Exception e) { logger.debug("Could not get handler from bean = " + name); } } diff --git a/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/RouterMBeanTests-context.xml b/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/RouterMBeanTests-context.xml index 9e7ac5b109..094428a656 100644 --- a/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/RouterMBeanTests-context.xml +++ b/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/RouterMBeanTests-context.xml @@ -11,19 +11,16 @@ http://www.springframework.org/schema/integration/jmx http://www.springframework.org/schema/integration/jmx/spring-integration-jmx.xsd"> - - - - - - - - - - + + + + + + + diff --git a/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/RouterMBeanTests.java b/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/RouterMBeanTests.java index 4af2f9d7b5..5caae68c2b 100644 --- a/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/RouterMBeanTests.java +++ b/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/RouterMBeanTests.java @@ -15,32 +15,56 @@ package org.springframework.integration.jmx.config; import static org.junit.Assert.assertEquals; +import java.util.Arrays; +import java.util.List; import java.util.Set; import javax.management.MBeanServer; import javax.management.ObjectName; +import org.junit.After; import org.junit.Test; import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; +import org.springframework.context.support.ClassPathXmlApplicationContext; /** * @author Dave Syer * @since 2.0 */ -@ContextConfiguration -@RunWith(SpringJUnit4ClassRunner.class) +@RunWith(Parameterized.class) public class RouterMBeanTests { - @Autowired private MBeanServer server; - + + private ClassPathXmlApplicationContext context; + + public RouterMBeanTests(String configLocation) { + context = new ClassPathXmlApplicationContext(configLocation, getClass()); + server = context.getBean(MBeanServer.class); + } + + @Parameters + public static List getParameters() { + return Arrays.asList( + new Object[] { RouterMBeanTests.class.getSimpleName() + "-context.xml" }, + new Object[] { RouterMBeanTests.class.getSimpleName() + "None-context.xml" }, + new Object[] { RouterMBeanTests.class.getSimpleName() + "Switch-context.xml" }); + } + + @After + public void close() { + if (context != null) { + context.close(); + } + } + @Test public void testRouterMBeanExists() throws Exception { // System.err.println(server.queryNames(new ObjectName("test.RouterMBean:*"), null)); - Set names = server.queryNames(new ObjectName("test.RouterMBean:type=MessageHandler,name=ptRouter,*"), null); + Set names = server.queryNames( + new ObjectName("test.RouterMBean:type=MessageHandler,name=ptRouter,*"), null); assertEquals(1, names.size()); } diff --git a/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/RouterMBeanTestsNone-context.xml b/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/RouterMBeanTestsNone-context.xml new file mode 100644 index 0000000000..6840c5b65e --- /dev/null +++ b/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/RouterMBeanTestsNone-context.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + diff --git a/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/RouterMBeanTestsSwitch-context.xml b/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/RouterMBeanTestsSwitch-context.xml new file mode 100644 index 0000000000..d182ef0082 --- /dev/null +++ b/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/RouterMBeanTestsSwitch-context.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + +