From 9b1b7e608c83e2789a3a86fbaa24cee9c12d53d0 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Mon, 14 Apr 2025 18:52:33 -0700 Subject: [PATCH] Prevent 'not eligible for getting processed' warnings when using JMX Update auto-configured `IntegrationMBeanExporter` to be created from a static method since it's a post-processor. Relevant injection now occurs by overriding the `afterSingletonsInstantiated()` method. Closes gh-45186 --- .../IntegrationAutoConfiguration.java | 27 ++++++++++++------- .../IntegrationAutoConfigurationTests.java | 2 +- .../build.gradle | 1 + .../src/main/resources/application.properties | 1 + .../SampleIntegrationApplicationTests.java | 10 +++++-- 5 files changed, 28 insertions(+), 13 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfiguration.java index cc531afac1b..3b576cbaaf1 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2024 the original author or authors. + * Copyright 2012-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +23,6 @@ import javax.sql.DataSource; import io.rsocket.transport.netty.server.TcpServerTransport; -import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigureBefore; @@ -44,6 +43,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.boot.context.properties.PropertyMapper; import org.springframework.boot.context.properties.source.MutuallyExclusiveConfigurationPropertiesException; import org.springframework.boot.task.ThreadPoolTaskSchedulerBuilder; +import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; @@ -200,14 +200,21 @@ public class IntegrationAutoConfiguration { protected static class IntegrationJmxConfiguration { @Bean - public IntegrationMBeanExporter integrationMbeanExporter(BeanFactory beanFactory, JmxProperties properties) { - IntegrationMBeanExporter exporter = new IntegrationMBeanExporter(); - String defaultDomain = properties.getDefaultDomain(); - if (StringUtils.hasLength(defaultDomain)) { - exporter.setDefaultDomain(defaultDomain); - } - exporter.setServer(beanFactory.getBean(properties.getServer(), MBeanServer.class)); - return exporter; + public static IntegrationMBeanExporter integrationMbeanExporter(ApplicationContext applicationContext) { + return new IntegrationMBeanExporter() { + + @Override + public void afterSingletonsInstantiated() { + JmxProperties properties = applicationContext.getBean(JmxProperties.class); + String defaultDomain = properties.getDefaultDomain(); + if (StringUtils.hasLength(defaultDomain)) { + setDefaultDomain(defaultDomain); + } + setServer(applicationContext.getBean(properties.getServer(), MBeanServer.class)); + super.afterSingletonsInstantiated(); + } + + }; } } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfigurationTests.java index 2fdfcdf6f9c..d943be65fed 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfigurationTests.java @@ -143,7 +143,7 @@ class IntegrationAutoConfigurationTests { this.contextRunner.withPropertyValues("spring.jmx.enabled=true").run((context) -> { MBeanServer mBeanServer = context.getBean(MBeanServer.class); assertThat(mBeanServer.getDomains()).contains("org.springframework.integration", - "org.springframework.integration.monitor"); + "org.springframework.boot.autoconfigure.integration"); assertThat(context).hasBean(IntegrationManagementConfigurer.MANAGEMENT_CONFIGURER_NAME); }); } diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-integration/build.gradle b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-integration/build.gradle index 3ad6c029a57..23aea32d31c 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-integration/build.gradle +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-integration/build.gradle @@ -9,6 +9,7 @@ dependencies { implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-integration")) implementation("org.springframework.integration:spring-integration-file") + implementation("org.springframework.integration:spring-integration-jmx") testImplementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-test")) testImplementation("org.awaitility:awaitility") diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-integration/src/main/resources/application.properties b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-integration/src/main/resources/application.properties index e5641a4620b..a6b3e36c67f 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-integration/src/main/resources/application.properties +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-integration/src/main/resources/application.properties @@ -2,3 +2,4 @@ logging.level.org.springframework.integration.file=DEBUG service.greeting=Hello service.input-dir=input service.output-dir=output +spring.jmx.enabled=true \ No newline at end of file diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-integration/src/test/java/smoketest/integration/consumer/SampleIntegrationApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-integration/src/test/java/smoketest/integration/consumer/SampleIntegrationApplicationTests.java index 0424c7ee7d5..2b65251199c 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-integration/src/test/java/smoketest/integration/consumer/SampleIntegrationApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-integration/src/test/java/smoketest/integration/consumer/SampleIntegrationApplicationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,18 +25,22 @@ import java.time.Duration; import org.awaitility.Awaitility; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.io.TempDir; import smoketest.integration.SampleIntegrationApplication; import smoketest.integration.ServiceProperties; import smoketest.integration.producer.ProducerApplication; import org.springframework.boot.SpringApplication; +import org.springframework.boot.test.system.CapturedOutput; +import org.springframework.boot.test.system.OutputCaptureExtension; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.Resource; import org.springframework.core.io.support.ResourcePatternUtils; import org.springframework.util.StreamUtils; +import static org.assertj.core.api.Assertions.assertThat; import static org.hamcrest.Matchers.containsString; /** @@ -45,12 +49,14 @@ import static org.hamcrest.Matchers.containsString; * @author Dave Syer * @author Andy Wilkinson */ +@ExtendWith(OutputCaptureExtension.class) class SampleIntegrationApplicationTests { private ConfigurableApplicationContext context; @AfterEach - void stop() { + void stopAndCheck(CapturedOutput output) { + assertThat(output).doesNotContain("WARN"); if (this.context != null) { this.context.close(); }