From f7a9bebc34768faea3e69ea4c435129799f137a1 Mon Sep 17 00:00:00 2001 From: spencergibb Date: Mon, 19 Apr 2021 13:38:36 -0400 Subject: [PATCH] Adds MvcFoundOnClasspathFailureAnalyzer to provide a better experience if mvc is on the classpath. Previously only a warning was printed in the logs, but sometime ago, ServerCodecConfigurer was added as a bean dependency which caused apps with mvc on the classpath to fail with an error that was difficult to diagnose. The warning was changed to a failure analyzer. Fixes gh-2176 --- pom.xml | 1 + .../mvc-failure-analyzer/pom.xml | 59 +++++++++++++++++++ .../sample/MvcFailureAnalyzerApplication.java | 29 +++++++++ .../src/main/resources/application.yml | 3 + .../MvcFailureAnalyzerApplicationTests.java | 46 +++++++++++++++ .../pom.xml | 38 ++++++++++++ ...ewayClassPathWarningAutoConfiguration.java | 5 +- .../support/MvcFoundOnClasspathException.java | 21 +++++++ .../MvcFoundOnClasspathFailureAnalyzer.java | 33 +++++++++++ .../main/resources/META-INF/spring.factories | 6 +- 10 files changed, 237 insertions(+), 4 deletions(-) create mode 100644 spring-cloud-gateway-integration-tests/mvc-failure-analyzer/pom.xml create mode 100644 spring-cloud-gateway-integration-tests/mvc-failure-analyzer/src/main/java/org/springframework/cloud/gateway/sample/MvcFailureAnalyzerApplication.java create mode 100644 spring-cloud-gateway-integration-tests/mvc-failure-analyzer/src/main/resources/application.yml create mode 100644 spring-cloud-gateway-integration-tests/mvc-failure-analyzer/src/test/java/org/springframework/cloud/gateway/sample/MvcFailureAnalyzerApplicationTests.java create mode 100644 spring-cloud-gateway-integration-tests/pom.xml create mode 100644 spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/support/MvcFoundOnClasspathException.java create mode 100644 spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/support/MvcFoundOnClasspathFailureAnalyzer.java diff --git a/pom.xml b/pom.xml index 9b978b14..1c030503 100644 --- a/pom.xml +++ b/pom.xml @@ -151,6 +151,7 @@ spring-cloud-gateway-server spring-cloud-starter-gateway spring-cloud-gateway-sample + spring-cloud-gateway-integration-tests docs diff --git a/spring-cloud-gateway-integration-tests/mvc-failure-analyzer/pom.xml b/spring-cloud-gateway-integration-tests/mvc-failure-analyzer/pom.xml new file mode 100644 index 00000000..f7bfa256 --- /dev/null +++ b/spring-cloud-gateway-integration-tests/mvc-failure-analyzer/pom.xml @@ -0,0 +1,59 @@ + + + 4.0.0 + + mvc-failure-analyzer + jar + + Spring Cloud Gateway MVC Failure Analyzer Integration Test + Spring Cloud Gateway MVC Failure Analyzer Integration Test + + + + + + org.springframework.cloud + spring-cloud-gateway-integration-tests + 2.2.8.BUILD-SNAPSHOT + .. + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.cloud + spring-cloud-starter-gateway + + + org.springframework.boot + spring-boot-starter-test + test + + + io.projectreactor + reactor-test + test + + + org.assertj + assertj-core + test + + + + + + maven-deploy-plugin + + true + + + + + + diff --git a/spring-cloud-gateway-integration-tests/mvc-failure-analyzer/src/main/java/org/springframework/cloud/gateway/sample/MvcFailureAnalyzerApplication.java b/spring-cloud-gateway-integration-tests/mvc-failure-analyzer/src/main/java/org/springframework/cloud/gateway/sample/MvcFailureAnalyzerApplication.java new file mode 100644 index 00000000..f9c17d7d --- /dev/null +++ b/spring-cloud-gateway-integration-tests/mvc-failure-analyzer/src/main/java/org/springframework/cloud/gateway/sample/MvcFailureAnalyzerApplication.java @@ -0,0 +1,29 @@ +/* + * Copyright 2013-2019 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.cloud.gateway.sample; + +import org.springframework.boot.SpringBootConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; + +/** + * @author Spencer Gibb + */ +@SpringBootConfiguration +@EnableAutoConfiguration +public class MvcFailureAnalyzerApplication { + +} diff --git a/spring-cloud-gateway-integration-tests/mvc-failure-analyzer/src/main/resources/application.yml b/spring-cloud-gateway-integration-tests/mvc-failure-analyzer/src/main/resources/application.yml new file mode 100644 index 00000000..106caafa --- /dev/null +++ b/spring-cloud-gateway-integration-tests/mvc-failure-analyzer/src/main/resources/application.yml @@ -0,0 +1,3 @@ +logging: + level: + org.springframework.cloud.gateway: TRACE diff --git a/spring-cloud-gateway-integration-tests/mvc-failure-analyzer/src/test/java/org/springframework/cloud/gateway/sample/MvcFailureAnalyzerApplicationTests.java b/spring-cloud-gateway-integration-tests/mvc-failure-analyzer/src/test/java/org/springframework/cloud/gateway/sample/MvcFailureAnalyzerApplicationTests.java new file mode 100644 index 00000000..0cf93f6e --- /dev/null +++ b/spring-cloud-gateway-integration-tests/mvc-failure-analyzer/src/test/java/org/springframework/cloud/gateway/sample/MvcFailureAnalyzerApplicationTests.java @@ -0,0 +1,46 @@ +/* + * Copyright 2013-2019 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.cloud.gateway.sample; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.test.system.CapturedOutput; +import org.springframework.boot.test.system.OutputCaptureExtension; +import org.springframework.cloud.gateway.support.MvcFoundOnClasspathException; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +/** + * @author Spencer Gibb + */ +@ExtendWith(OutputCaptureExtension.class) +public class MvcFailureAnalyzerApplicationTests { + + @Test + public void contextLoads(CapturedOutput output) { + assertThatThrownBy( + () -> new SpringApplication(MvcFailureAnalyzerApplication.class) + .run("--server.port=0")).hasRootCauseInstanceOf( + MvcFoundOnClasspathException.class); + assertThat(output).contains("Spring MVC found on classpath", + "Please remove spring-boot-starter-web dependency"); + } + +} diff --git a/spring-cloud-gateway-integration-tests/pom.xml b/spring-cloud-gateway-integration-tests/pom.xml new file mode 100644 index 00000000..dfda11d9 --- /dev/null +++ b/spring-cloud-gateway-integration-tests/pom.xml @@ -0,0 +1,38 @@ + + + 4.0.0 + + spring-cloud-gateway-integration-tests + pom + + Spring Cloud Gateway Integration Tests + Spring Cloud Gateway Integration Tests + + + + + + org.springframework.cloud + spring-cloud-gateway + 2.2.8.BUILD-SNAPSHOT + .. + + + + mvc-failure-analyzer + + + + + + maven-deploy-plugin + + true + + + + + + diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/GatewayClassPathWarningAutoConfiguration.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/GatewayClassPathWarningAutoConfiguration.java index 1eb3430c..b70381d0 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/GatewayClassPathWarningAutoConfiguration.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/GatewayClassPathWarningAutoConfiguration.java @@ -22,6 +22,7 @@ import org.apache.commons.logging.LogFactory; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; +import org.springframework.cloud.gateway.support.MvcFoundOnClasspathException; import org.springframework.context.annotation.Configuration; @Configuration(proxyBeanMethods = false) @@ -38,9 +39,7 @@ public class GatewayClassPathWarningAutoConfiguration { protected static class SpringMvcFoundOnClasspathConfiguration { public SpringMvcFoundOnClasspathConfiguration() { - log.warn(BORDER - + "Spring MVC found on classpath, which is incompatible with Spring Cloud Gateway at this time. " - + "Please remove spring-boot-starter-web dependency." + BORDER); + throw new MvcFoundOnClasspathException(); } } diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/support/MvcFoundOnClasspathException.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/support/MvcFoundOnClasspathException.java new file mode 100644 index 00000000..a0ee6abd --- /dev/null +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/support/MvcFoundOnClasspathException.java @@ -0,0 +1,21 @@ +/* + * Copyright 2013-2021 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.cloud.gateway.support; + +public class MvcFoundOnClasspathException extends RuntimeException { + +} diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/support/MvcFoundOnClasspathFailureAnalyzer.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/support/MvcFoundOnClasspathFailureAnalyzer.java new file mode 100644 index 00000000..17c8828f --- /dev/null +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/support/MvcFoundOnClasspathFailureAnalyzer.java @@ -0,0 +1,33 @@ +/* + * Copyright 2013-2021 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.cloud.gateway.support; + +import org.springframework.boot.diagnostics.AbstractFailureAnalyzer; +import org.springframework.boot.diagnostics.FailureAnalysis; + +public class MvcFoundOnClasspathFailureAnalyzer + extends AbstractFailureAnalyzer { + + @Override + protected FailureAnalysis analyze(Throwable rootFailure, + MvcFoundOnClasspathException cause) { + String message = "Spring MVC found on classpath, which is incompatible with Spring Cloud Gateway."; + String action = "Please remove spring-boot-starter-web dependency."; + return new FailureAnalysis(message, action, cause); + } + +} diff --git a/spring-cloud-gateway-server/src/main/resources/META-INF/spring.factories b/spring-cloud-gateway-server/src/main/resources/META-INF/spring.factories index 5019e783..46cf98b1 100644 --- a/spring-cloud-gateway-server/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-gateway-server/src/main/resources/META-INF/spring.factories @@ -13,4 +13,8 @@ org.springframework.cloud.gateway.config.SimpleUrlHandlerMappingGlobalCorsAutoCo org.springframework.cloud.gateway.config.GatewayReactiveLoadBalancerClientAutoConfiguration org.springframework.boot.env.EnvironmentPostProcessor=\ -org.springframework.cloud.gateway.config.GatewayEnvironmentPostProcessor \ No newline at end of file +org.springframework.cloud.gateway.config.GatewayEnvironmentPostProcessor + +# Failure Analyzers +org.springframework.boot.diagnostics.FailureAnalyzer=\ +org.springframework.cloud.gateway.support.MvcFoundOnClasspathFailureAnalyzer \ No newline at end of file