Browse Source

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
pull/45202/head
Phillip Webb 8 months ago
parent
commit
9b1b7e608c
  1. 21
      spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfiguration.java
  2. 2
      spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfigurationTests.java
  3. 1
      spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-integration/build.gradle
  4. 1
      spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-integration/src/main/resources/application.properties
  5. 10
      spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-integration/src/test/java/smoketest/integration/consumer/SampleIntegrationApplicationTests.java

21
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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 io.rsocket.transport.netty.server.TcpServerTransport;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureBefore; 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.PropertyMapper;
import org.springframework.boot.context.properties.source.MutuallyExclusiveConfigurationPropertiesException; import org.springframework.boot.context.properties.source.MutuallyExclusiveConfigurationPropertiesException;
import org.springframework.boot.task.ThreadPoolTaskSchedulerBuilder; import org.springframework.boot.task.ThreadPoolTaskSchedulerBuilder;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@ -200,14 +200,21 @@ public class IntegrationAutoConfiguration {
protected static class IntegrationJmxConfiguration { protected static class IntegrationJmxConfiguration {
@Bean @Bean
public IntegrationMBeanExporter integrationMbeanExporter(BeanFactory beanFactory, JmxProperties properties) { public static IntegrationMBeanExporter integrationMbeanExporter(ApplicationContext applicationContext) {
IntegrationMBeanExporter exporter = new IntegrationMBeanExporter(); return new IntegrationMBeanExporter() {
@Override
public void afterSingletonsInstantiated() {
JmxProperties properties = applicationContext.getBean(JmxProperties.class);
String defaultDomain = properties.getDefaultDomain(); String defaultDomain = properties.getDefaultDomain();
if (StringUtils.hasLength(defaultDomain)) { if (StringUtils.hasLength(defaultDomain)) {
exporter.setDefaultDomain(defaultDomain); setDefaultDomain(defaultDomain);
}
setServer(applicationContext.getBean(properties.getServer(), MBeanServer.class));
super.afterSingletonsInstantiated();
} }
exporter.setServer(beanFactory.getBean(properties.getServer(), MBeanServer.class));
return exporter; };
} }
} }

2
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) -> { this.contextRunner.withPropertyValues("spring.jmx.enabled=true").run((context) -> {
MBeanServer mBeanServer = context.getBean(MBeanServer.class); MBeanServer mBeanServer = context.getBean(MBeanServer.class);
assertThat(mBeanServer.getDomains()).contains("org.springframework.integration", assertThat(mBeanServer.getDomains()).contains("org.springframework.integration",
"org.springframework.integration.monitor"); "org.springframework.boot.autoconfigure.integration");
assertThat(context).hasBean(IntegrationManagementConfigurer.MANAGEMENT_CONFIGURER_NAME); assertThat(context).hasBean(IntegrationManagementConfigurer.MANAGEMENT_CONFIGURER_NAME);
}); });
} }

1
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(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-integration"))
implementation("org.springframework.integration:spring-integration-file") 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(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-test"))
testImplementation("org.awaitility:awaitility") testImplementation("org.awaitility:awaitility")

1
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.greeting=Hello
service.input-dir=input service.input-dir=input
service.output-dir=output service.output-dir=output
spring.jmx.enabled=true

10
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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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.awaitility.Awaitility;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.io.TempDir; import org.junit.jupiter.api.io.TempDir;
import smoketest.integration.SampleIntegrationApplication; import smoketest.integration.SampleIntegrationApplication;
import smoketest.integration.ServiceProperties; import smoketest.integration.ServiceProperties;
import smoketest.integration.producer.ProducerApplication; import smoketest.integration.producer.ProducerApplication;
import org.springframework.boot.SpringApplication; 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.context.ConfigurableApplicationContext;
import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource; import org.springframework.core.io.Resource;
import org.springframework.core.io.support.ResourcePatternUtils; import org.springframework.core.io.support.ResourcePatternUtils;
import org.springframework.util.StreamUtils; import org.springframework.util.StreamUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.containsString;
/** /**
@ -45,12 +49,14 @@ import static org.hamcrest.Matchers.containsString;
* @author Dave Syer * @author Dave Syer
* @author Andy Wilkinson * @author Andy Wilkinson
*/ */
@ExtendWith(OutputCaptureExtension.class)
class SampleIntegrationApplicationTests { class SampleIntegrationApplicationTests {
private ConfigurableApplicationContext context; private ConfigurableApplicationContext context;
@AfterEach @AfterEach
void stop() { void stopAndCheck(CapturedOutput output) {
assertThat(output).doesNotContain("WARN");
if (this.context != null) { if (this.context != null) {
this.context.close(); this.context.close();
} }

Loading…
Cancel
Save