Spring Cloud Gateway; Spring MVC found on classpath, which is incompatible with Spring Cloud Gateway Issue
Asked Answered
P

4

23

I got this below error when run the API-GATEWAY, I tried so many ways but I couldn't solve this issue.

Description:

Spring MVC found on classpath, which is incompatible with Spring Cloud Gateway.

Action:

Please set spring.main.web-application-type=reactive or remove spring-boot-starter-web dependency.

Main Class

package com.sample.apigateway;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication
@EnableEurekaClient
public class ApiGatewayApplication {

    public static void main(String[] args) {
        SpringApplication.run(ApiGatewayApplication.class, args);
    }

}

application.yml

spring:
  application:
    name: GATEWAY-SERVICE

  cloud:
    gateway:
      routes:
        - id: USER-SERVICE
          uri: lb://USER-SERVICE
          predicates:
            - Path=/users/**
        - id: DEPARTMENT-SERVICE
          uri: lb://DEPARTMENT-SERVICE
          predicates:
            - Path=/departments/**

eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:8761/eureka/

  instance:
    hostname: localhost

server:
  port: 9191

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.5.3</version>
    <relativePath/>
    <!-- lookup parent from repository -->
  </parent>
  <groupId>com.sample.apigateway</groupId>
  <artifactId>apigateway</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>apigateway</name>
  <description>Demo project for Spring Boot</description>
  <properties>
    <java.version>11</java.version>
    <spring-cloud.version>2020.0.3</spring-cloud.version>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>
    <dependency>
      <groupId>io.springfox</groupId>
      <artifactId>springfox-boot-starter</artifactId>
      <version>3.0.0</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>${spring-cloud.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>

</project>

Full Error Message

2021-07-30 23:12:02.420  WARN 19032 --- [           main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.cloud.gateway.config.GatewayClassPathWarningAutoConfiguration$SpringMvcFoundOnClasspathConfiguration': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.cloud.gateway.config.GatewayClassPathWarningAutoConfiguration$SpringMvcFoundOnClasspathConfiguration]: Constructor threw exception; nested exception is org.springframework.cloud.gateway.support.MvcFoundOnClasspathException
2021-07-30 23:12:02.423  INFO 19032 --- [           main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
2021-07-30 23:12:02.441  INFO 19032 --- [           main] ConditionEvaluationReportLoggingListener :

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2021-07-30 23:12:02.454 ERROR 19032 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   :

***************************
APPLICATION FAILED TO START
***************************

Description:

Spring MVC found on classpath, which is incompatible with Spring Cloud Gateway.

Action:

Please set spring.main.web-application-type=reactive or remove spring-boot-starter-web dependency.


Process finished with exit code 1
Parapodium answered 30/7, 2021 at 8:31 Comment(4)
Can you provide the exact error messages or stack traces?Rehearsal
Updated the question bro.Parapodium
Spring Cloud Gateway is API Gateway implementation by Spring Cloud team on top of Spring reactive ecosystem. Hence add the property suggested [spring.main.web-application-type=reactive].Lechner
#Arun I did all suggested things but error does not fix..Parapodium
F
28

I was facing the similar issue. As suggested in the error section making following change to application.properties file worked fine for me.

spring.main.web-application-type=reactive
Friedrich answered 27/8, 2021 at 19:44 Comment(2)
is this right way to do it? This means I have to adapt my application to spring webfluxOrthoscope
@TukaramBhosale You are right, Note that spring.io/projects/spring-cloud-gateway is not compatible with spring-boot-starter-web.Friedrich
R
8

Please note that Spring Cloud Gateway is not compatible with Spring MVC (spring-boot-starter-web). This is outlined in section "How to include Spring Cloud Gateway in the official reference documentation":

Spring Cloud Gateway is built on Spring Boot 2.x, Spring WebFlux, and Project Reactor. As a consequence, many of the familiar synchronous libraries (Spring Data and Spring Security, for example) and patterns you know may not apply when you use Spring Cloud Gateway.

Additionally, it is stated that:

Spring Cloud Gateway requires the Netty runtime provided by Spring Boot and Spring Webflux. It does not work in a traditional Servlet Container or when built as a WAR.

As already suggested by the error message, you would need to remove the dependency on spring-boot-starter-web. You can list all your direct and transitive dependencies with the following command:

mvn dependency:tree

This will reveal that spring-cloud-starter-netflix-eureka-server depends on spring-boot-starter-web. Once you remove the following lines from your pom.xml, your application should start up:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
Rehearsal answered 31/7, 2021 at 8:16 Comment(6)
Spring Cloud Gateway requires the Netty runtime provided by Spring Boot and Spring Webflux. It does not work in a traditional Servlet Container or when built as a WAR.. This means we cannot build a WAR for gateway and deploy in tomcat?Calliope
No, this is not supported, please also see docs.spring.io/spring-boot/docs/current/reference/html/…: "Because Spring WebFlux does not strictly depend on the Servlet API and applications are deployed by default on an embedded Reactor Netty server, War deployment is not supported for WebFlux applications."Rehearsal
Okay, then how do we deploy spring cloud gateway (Spring boot webflux) in production environment?Calliope
Create a JAR archive instead of a WAR archive and run it in the target environment: java -jar archive.jarRehearsal
But is that recommended in production environment? I mean is that scalable and stable? Also I am not able to figure out how we can set context path for gateway. Tried setting spring.webflux.base-path but didn't work.Calliope
Yes, JAR archives simplify everything. But also depends on how much logic is wrapped around your war deployment. JAR is preferred due to the simplicity, especially when deploying within containerized environments.Capote
S
1

Because I need MVC for my simple requirement I replace Spring webflux Gateway (spring-cloud-gateway-webflux) by Spring MVC Gateway (group = "org.springframework.cloud", name = "spring-cloud-gateway-mvc")

Like this

import org.springframework.cloud.gateway.mvc.ProxyExchange
..
@RestController
@SpringBootApplication
public class GatewaySampleApplication {

    @Value("${remote.home}")
    private URI home;

    @GetMapping("/test")
    public ResponseEntity<?> proxy(ProxyExchange<byte[]> proxy) throws Exception {
        return proxy.uri(home.toString() + "/image/png").get();
    }

}

Reference https://cloud.spring.io/spring-cloud-gateway/multi/multi__building_a_simple_gateway_using_spring_mvc_or_webflux.html

Sussman answered 8/9, 2022 at 15:24 Comment(1)
Sunsetting netflix-zuul and requiring webflux for the replacement is a real PITA which prevents me from upgrading a large spring-boot 2.3.x application. I will try my luck with this ProxyExchange.Kalat
M
0

I solved it by adding:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>

and add the below :

spring.main.web-application-type=reactive

in application.properties or yaml file

Marry answered 11/12, 2022 at 18:41 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.