diff --git a/module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/env/DevToolsPropertyDefaultsPostProcessor.java b/module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/env/DevToolsPropertyDefaultsPostProcessor.java index 8f4d3e949c7..05cdfc6aedb 100755 --- a/module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/env/DevToolsPropertyDefaultsPostProcessor.java +++ b/module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/env/DevToolsPropertyDefaultsPostProcessor.java @@ -28,6 +28,7 @@ import org.springframework.boot.devtools.logger.DevToolsLogFactory; import org.springframework.boot.devtools.restart.Restarter; import org.springframework.boot.devtools.settings.DevToolsSettings; import org.springframework.boot.devtools.system.DevToolsEnablementDeducer; +import org.springframework.boot.web.context.reactive.ConfigurableReactiveWebEnvironment; import org.springframework.core.NativeDetector; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; @@ -55,9 +56,7 @@ public class DevToolsPropertyDefaultsPostProcessor implements EnvironmentPostPro private static final String WEB_LOGGING = "logging.level.web"; - private static final String[] WEB_ENVIRONMENT_CLASSES = { - "org.springframework.web.context.ConfigurableWebEnvironment", - "org.springframework.boot.web.reactive.context.ConfigurableReactiveWebEnvironment" }; + private static final String SERVLET_WEB_ENVIRONMENT_CLASS = "org.springframework.web.context.ConfigurableWebEnvironment"; private static final Map PROPERTIES; @@ -112,13 +111,12 @@ public class DevToolsPropertyDefaultsPostProcessor implements EnvironmentPostPro } private boolean isWebApplication(Environment environment) { - for (String candidate : WEB_ENVIRONMENT_CLASSES) { - Class environmentClass = resolveClassName(candidate, environment.getClass().getClassLoader()); - if (environmentClass != null && environmentClass.isInstance(environment)) { - return true; - } + if (environment instanceof ConfigurableReactiveWebEnvironment) { + return true; } - return false; + Class servletWebEnvironmentClass = resolveClassName(SERVLET_WEB_ENVIRONMENT_CLASS, + environment.getClass().getClassLoader()); + return servletWebEnvironmentClass != null && servletWebEnvironmentClass.isInstance(environment); } private @Nullable Class resolveClassName(String candidate, ClassLoader classLoader) { diff --git a/module/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/env/DevToolsPropertyDefaultsPostProcessorTests.java b/module/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/env/DevToolsPropertyDefaultsPostProcessorTests.java new file mode 100644 index 00000000000..6bbad0f88f6 --- /dev/null +++ b/module/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/env/DevToolsPropertyDefaultsPostProcessorTests.java @@ -0,0 +1,87 @@ +/* + * Copyright 2012-present 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.devtools.env; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.logging.DeferredLog; +import org.springframework.boot.test.system.CapturedOutput; +import org.springframework.boot.test.system.OutputCaptureExtension; +import org.springframework.boot.test.util.TestPropertyValues; +import org.springframework.boot.web.context.reactive.StandardReactiveWebEnvironment; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.StandardEnvironment; +import org.springframework.test.util.ReflectionTestUtils; +import org.springframework.web.context.support.StandardServletEnvironment; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link DevToolsPropertyDefaultsPostProcessor}. + * + * @author ohchanKyu + */ +@ExtendWith(OutputCaptureExtension.class) +class DevToolsPropertyDefaultsPostProcessorTests { + + private static final String WEB_LOGGING_HINT = "For additional web related logging consider setting the " + + "'logging.level.web' property to 'DEBUG'"; + + @Test + void postProcessWhenServletWebEnvironmentLogsWebLoggingHint(CapturedOutput output) throws Exception { + postProcess(new StandardServletEnvironment()); + assertThat(output).contains(WEB_LOGGING_HINT); + } + + @Test + void postProcessWhenReactiveWebEnvironmentLogsWebLoggingHint(CapturedOutput output) throws Exception { + postProcess(new StandardReactiveWebEnvironment()); + assertThat(output).contains(WEB_LOGGING_HINT); + } + + @Test + void postProcessWhenNonWebEnvironmentDoesNotLogWebLoggingHint(CapturedOutput output) throws Exception { + postProcess(new StandardEnvironment()); + assertThat(output).doesNotContain(WEB_LOGGING_HINT); + } + + @Test + void postProcessWhenWebLoggingIsConfiguredDoesNotLogWebLoggingHint(CapturedOutput output) throws Exception { + StandardReactiveWebEnvironment environment = new StandardReactiveWebEnvironment(); + TestPropertyValues.of("logging.level.web=DEBUG").applyTo(environment); + postProcess(environment); + assertThat(output).doesNotContain(WEB_LOGGING_HINT); + } + + private void postProcess(ConfigurableEnvironment environment) throws Exception { + DevToolsPropertyDefaultsPostProcessor postProcessor = new DevToolsPropertyDefaultsPostProcessor(); + // Run in a new thread so that DevTools is not disabled by the test runner + Thread thread = new Thread(() -> postProcessor.postProcessEnvironment(environment, new SpringApplication())); + thread.start(); + thread.join(); + replayDeferredLog(); + } + + private void replayDeferredLog() { + Object logger = ReflectionTestUtils.getField(DevToolsPropertyDefaultsPostProcessor.class, "logger"); + assertThat(logger).isInstanceOf(DeferredLog.class); + ((DeferredLog) logger).switchTo(DevToolsPropertyDefaultsPostProcessor.class); + } + +}