diff --git a/spring-cloud-gateway-integration-tests/mvc-failure-analyzer/pom.xml b/spring-cloud-gateway-integration-tests/mvc-failure-analyzer/pom.xml
index 6dfc1e05..0539dc86 100644
--- a/spring-cloud-gateway-integration-tests/mvc-failure-analyzer/pom.xml
+++ b/spring-cloud-gateway-integration-tests/mvc-failure-analyzer/pom.xml
@@ -29,6 +29,10 @@
org.springframework.cloud
spring-cloud-starter-gateway
+
+ org.springframework.cloud
+ spring-cloud-starter-loadbalancer
+
org.springframework.boot
spring-boot-starter-test
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
index f9c17d7d..8bb621ef 100644
--- 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
@@ -18,12 +18,50 @@ package org.springframework.cloud.gateway.sample;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
+import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.cloud.client.DefaultServiceInstance;
+import org.springframework.cloud.gateway.route.RouteLocator;
+import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
+import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient;
+import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
+import org.springframework.cloud.loadbalancer.support.ServiceInstanceListSuppliers;
+import org.springframework.context.annotation.Bean;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
/**
* @author Spencer Gibb
*/
@SpringBootConfiguration
@EnableAutoConfiguration
+@RestController
+@LoadBalancerClient(name = "myservice", configuration = MyServiceConf.class)
public class MvcFailureAnalyzerApplication {
+ @GetMapping("hello")
+ public String hello() {
+ return "Hello";
+ }
+
+ @Bean
+ @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
+ public RouteLocator myRouteLocator(RouteLocatorBuilder builder) {
+ return builder.routes().route(r -> r.path("/myprefix/**")
+ .filters(f -> f.stripPrefix(1)).uri("lb://myservice")).build();
+ }
+
+}
+
+class MyServiceConf {
+
+ @LocalServerPort
+ private int port = 0;
+
+ @Bean
+ public ServiceInstanceListSupplier staticServiceInstanceListSupplier() {
+ return ServiceInstanceListSuppliers.from("myservice", new DefaultServiceInstance(
+ "myservice-1", "myservice", "localhost", port, false));
+ }
+
}
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
index 8d07fb77..ed8c9b82 100644
--- 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
@@ -23,6 +23,9 @@ 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 org.springframework.cloud.gateway.support.MvcFoundOnClasspathFailureAnalyzer;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.test.web.reactive.server.WebTestClient;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;
@@ -36,18 +39,41 @@ public class MvcFailureAnalyzerApplicationTests {
@Test
public void exceptionThrown(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");
+ assertThatThrownBy(
+ () -> new SpringApplication(MvcFailureAnalyzerApplication.class)
+ .run("--server.port=0")).hasRootCauseInstanceOf(
+ MvcFoundOnClasspathException.class);
+ assertThat(output).contains(MvcFoundOnClasspathFailureAnalyzer.MESSAGE,
+ MvcFoundOnClasspathFailureAnalyzer.ACTION);
}
@Test
public void exceptionNotThrownWhenDisabled(CapturedOutput output) {
assertThatCode(() -> new SpringApplication(MvcFailureAnalyzerApplication.class)
- .run("--spring.cloud.gateway.enabled=false", "--server.port=0")).doesNotThrowAnyException();
- assertThat(output).doesNotContain("Spring MVC found on classpath",
- "Please remove spring-boot-starter-web dependency");
+ .run("--spring.cloud.gateway.enabled=false", "--server.port=0"))
+ .doesNotThrowAnyException();
+ assertThat(output).doesNotContain(MvcFoundOnClasspathFailureAnalyzer.MESSAGE,
+ MvcFoundOnClasspathFailureAnalyzer.ACTION);
+ }
+
+ @Test
+ public void exceptionNotThrownWhenReactiveTypeSet(CapturedOutput output) {
+ assertThatCode(() -> {
+ ConfigurableApplicationContext context = new SpringApplication(
+ MvcFailureAnalyzerApplication.class).run(
+ "--spring.main.web-application-type=reactive",
+ "--server.port=0", "--debug=true");
+ Integer port = context.getEnvironment().getProperty("local.server.port",
+ Integer.class);
+ WebTestClient client = WebTestClient.bindToServer()
+ .baseUrl("http://localhost:" + port).build();
+ client.get().uri("/myprefix/hello").exchange().expectStatus().isOk()
+ .expectBody(String.class).isEqualTo("Hello");
+ context.close();
+ }).doesNotThrowAnyException();
+ assertThat(output).doesNotContain(MvcFoundOnClasspathFailureAnalyzer.MESSAGE,
+ MvcFoundOnClasspathFailureAnalyzer.ACTION);
+
}
}
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 ddb7a98f..2fd3e441 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
@@ -23,6 +23,7 @@ import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.cloud.gateway.support.MvcFoundOnClasspathException;
import org.springframework.context.annotation.Configuration;
@@ -37,6 +38,7 @@ public class GatewayClassPathWarningAutoConfiguration {
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(name = "org.springframework.web.servlet.DispatcherServlet")
+ @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
protected static class SpringMvcFoundOnClasspathConfiguration {
public SpringMvcFoundOnClasspathConfiguration() {
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
index 5a0cb97a..c0d5b41f 100644
--- 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
@@ -21,11 +21,19 @@ import org.springframework.boot.diagnostics.FailureAnalysis;
public class MvcFoundOnClasspathFailureAnalyzer extends AbstractFailureAnalyzer {
+ /**
+ * Message for MvcFoundOnClasspathException.
+ */
+ public static final String MESSAGE = "Spring MVC found on classpath, which is incompatible with Spring Cloud Gateway.";
+
+ /**
+ * Action for MvcFoundOnClasspathException.
+ */
+ public static final String ACTION = "Please set spring.main.web-application-type=reactive or remove spring-boot-starter-web dependency.";
+
@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);
+ return new FailureAnalysis(MESSAGE, ACTION, cause);
}
}