Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring-ReactiveWeb! Netty doesnt start after add Swagger 2 documentation

Does Swagger support Spring Reactive-Web?

I am trying to write a simple crud application with Reactive Web and Reactive Mongo. Everything works fine. But when I add Swagger to my project, Netty doesn't start.

Here is my controller class:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import uz.n0d1r.datas.Point;
import uz.n0d1r.repository.PointRepository;

@RestController(value = "/points")
public class PointController {

    private final PointRepository pointRepository;

    public PointController(PointRepository pointRepository) {
        this.pointRepository = pointRepository;
    }

    @PostMapping
    Mono<Void> create(@RequestBody Point point) {
        return pointRepository.save(point).then();
    }

    @GetMapping
    Flux<Point> list() {
        return this.pointRepository.findAll();
    }

}

Swagger Config:

import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.ArrayList;
import java.util.List;
@Configuration
@EnableSwagger2
public class TrackServiceSwaggerConfig {

    @Bean
    public Docket api() {
        ParameterBuilder aParameterBuilder = new ParameterBuilder();
//        aParameterBuilder.name("Authorization").modelRef(new ModelRef("string")).parameterType("header").required(true).build();
        List<Parameter> header = new ArrayList<Parameter>();
        header.add(aParameterBuilder.build());
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(paths())
                .build()
                .globalOperationParameters(header);
    }

    // Describe your apis
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("Track-Service APIs")
                .description("description goes here ")
                .contact(new Contact("Nodirbek Sadullayev", "n0d1r.uz", "[email protected]"))
                .version("1.0-SNAPSHOT")
                .build();
    }

    // Only select apis that matches the given Predicates.
    private Predicate<String> paths() {
        // Match all paths except /error
        return Predicates.and(
                PathSelectors.regex("/.*"),
                Predicates.not(PathSelectors.regex("/error.*"))
        );
    }
}

My dependencies list below:

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.projectreactor</groupId>
            <artifactId>reactor-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.6.1</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.6.1</version>
        </dependency>

    </dependencies>

Error log:

org.springframework.context.ApplicationContextException: Unable to start reactive web server; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerConfiguration$ReactorNettyAutoConfiguration': Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter
            at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.onRefresh(ReactiveWebServerApplicationContext.java:59) ~[spring-boot-2.0.0.M6.jar:2.0.0.M6]
            at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543) ~[spring-context-5.0.1.RELEASE.jar:5.0.1.RELEASE]
            at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.refresh(ReactiveWebServerApplicationContext.java:44) ~[spring-boot-2.0.0.M6.jar:2.0.0.M6]
            at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:751) [spring-boot-2.0.0.M6.jar:2.0.0.M6]
            at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:387) [spring-boot-2.0.0.M6.jar:2.0.0.M6]
            at org.springframework.boot.SpringApplication.run(SpringApplication.java:327) [spring-boot-2.0.0.M6.jar:2.0.0.M6]
            at org.springframework.boot.SpringApplication.run(SpringApplication.java:1245) [spring-boot-2.0.0.M6.jar:2.0.0.M6]
            at org.springframework.boot.SpringApplication.run(SpringApplication.java:1233) [spring-boot-2.0.0.M6.jar:2.0.0.M6]
            at uz.n0d1r.TrackServiceApplication.main(TrackServiceApplication.java:10) [classes/:na]
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_65]
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_65]
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_65]
            at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_65]
            at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147) [idea_rt.jar:na]
        Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerConfiguration$ReactorNettyAutoConfiguration': Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:591) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:502) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
            at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:312) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
            at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
            at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:310) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
            at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
            at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:368) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1249) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1098) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:502) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
            at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:312) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
            at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
            at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:310) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
            at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:205) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
            at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.getWebServerFactory(ReactiveWebServerApplicationContext.java:117) ~[spring-boot-2.0.0.M6.jar:2.0.0.M6]
            at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.createWebServer(ReactiveWebServerApplicationContext.java:82) ~[spring-boot-2.0.0.M6.jar:2.0.0.M6]
            at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.onRefresh(ReactiveWebServerApplicationContext.java:56) ~[spring-boot-2.0.0.M6.jar:2.0.0.M6]
            ... 13 common frames omitted
        Caused by: java.lang.NoClassDefFoundError: org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter
            at springfox.documentation.spring.web.ObjectMapperConfigurer.postProcessBeforeInitialization(ObjectMapperConfigurer.java:45) ~[springfox-spring-web-2.6.1.jar:2.6.1]
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:423) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1696) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:583) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
            ... 30 common frames omitted
        Caused by: java.lang.ClassNotFoundException: org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
            at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[na:1.8.0_65]
            at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_65]
            at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) ~[na:1.8.0_65]
            at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_65]
            ... 34 common frames omitted

Any suggestions ? thanks!

like image 504
N0D1R Avatar asked Nov 30 '17 17:11

N0D1R


People also ask

How do I add Swagger 2 to spring boot?

To enable the Swagger2 in Spring Boot application, you need to add the following dependencies in our build configurations file. For Gradle users, add the following dependencies in your build. gradle file. Now, add the @EnableSwagger2 annotation in your main Spring Boot application.

Is Springfox deprecated?

springfox (documentationProvider): Springfox is deprecated for removal in version 7.0. 0 of openapi-generator. The project seems to be no longer maintained (last commit is of Oct 14, 2020). It works with Spring Boot 2.5.

What is Springfox swagger UI?

Springfox is a framework that acts as the “glue” between Swagger and Spring. It generates the specification (contract) based on your code and also deploys the Swagger UI client with your application, allowing you to immediately test your REST API.


1 Answers

Swagger 3 will be soon released, and it includes support for netty.

By that time, you can use the snapshot version:

{
repositories {
    maven {
        url 'http://oss.jfrog.org/artifactory/oss-snapshot-local/'
    }
}
dependencies {
    compile 'io.springfox:springfox-swagger2:3.0.0-SNAPSHOT'
    compile 'io.springfox:springfox-swagger-ui:3.0.0-SNAPSHOT'
    compile 'io.springfox:springfox-spring-webflux:3.0.0-SNAPSHOT'
}

}

and you enable it with @EnableSwagger2WebFlux

source: https://github.com/springfox/springfox/issues/1773

like image 117
Manza Avatar answered Oct 27 '22 19:10

Manza