Mostafa Omar
Mostafa Omar

Reputation: 177

Using "spring-boot-starter-webflux" and "spring-boot-starter-web" together

I'm trying to use WebClient instead of RestTemplate in my spring boot MVC Application, yet I couldn't find a specific dependency only for the WebClient, My application is fully MVC and as explained in the Spring Boot reference documentation section about WebFlux, adding both web and webflux starters will configure a Spring MVC web application, But that's not the case, When I added both I received the below error

2019-06-14 09:10:13.196  WARN 69495 --- [  restartedMain] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration': Unsatisfied dependency expressed through constructor parameter 3; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration$EnableWebFluxConfiguration': Initialization of bean failed; nested exception is java.lang.IllegalStateException:

The Java/XML config for Spring MVC and Spring WebFlux cannot both be enabled, e.g. via @EnableWebMvc and @EnableWebFlux, in the same application.

Note That I'm neither using @EnableWebMvc nor @EnableWebFlux on any of the Config classes.

Here's my Pom

...
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.5.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
        </dependency>
...

Upvotes: 1

Views: 8701

Answers (2)

Toerktumlare
Toerktumlare

Reputation: 14820

As noted in the spring documentation here Web Application

A SpringApplication attempts to create the right type of ApplicationContext on your behalf. The algorithm used to determine a WebApplicationType is fairly simple:

If Spring MVC is present, an AnnotationConfigServletWebServerApplicationContext is used

If Spring MVC is not present and Spring WebFlux is present, an AnnotationConfigReactiveWebServerApplicationContext is used

Otherwise, AnnotationConfigApplicationContext is used

This means that if you are using Spring MVC and the new WebClient from Spring WebFlux in the same application, Spring MVC will be used by default. You can override that easily by calling setWebApplicationType(WebApplicationType).

It is also possible to take complete control of the ApplicationContext type that is used by calling setApplicationContextClass(…​).

Says that if Spring MVC and Webflux is on the class path, Spring MVC will be preferred. This behaviour can be overridden.

This might give you some tips to start where to debug or try as suggested to force the application to be a servlet application.

public static void main(String[] args) {
    final SpringApplication application = new SpringApplication(MyApplication.class);
    application.setWebApplicationType(WebApplicationType.SERVLET);
    application.run(args);
}

Upvotes: 1

Mostafa Omar
Mostafa Omar

Reputation: 177

As mentioned in the provided link, in the Spring Boot reference documentation section about WebFlux, adding both web and webflux starters should work if you want to Use the webclient in an mvc servlets environment, I just had to clean my IDE cache and that was the issue. As a note: if you wanna start your environment programmatically you can choose one of the standard spring provided environments as below

//For Reactive
ConfigurableEnvironment environment = new StandardReactiveWebEnvironment();
//For Servlets mvc environment
ConfigurableEnvironment environment = new StandardServletEnvironment();

Upvotes: 1

Related Questions