springfox: Springfox swagger2 @Component does not get indexed by Spring Framework 5 `spring-context-indexer`

Springfox Swagger Version

2.8.0

Spring Boot Version

2.0.2.RELEASE

Description

When using component-indexer with springfox-swagger2, the application fails to start.

Error:

Parameter 2 of method swagger2ControllerMapping in springfox.documentation.swagger2.configuration.Swagger2DocumentationConfiguration 
required a bean of type 'springfox.documentation.swagger2.mappers.ServiceModelToSwagger2Mapper' 
that could not be found.

Test case

https://github.com/ssouris/swagger-component-indexer-bug

About this issue

  • Original URL
  • State: open
  • Created 6 years ago
  • Reactions: 13
  • Comments: 25 (6 by maintainers)

Most upvoted comments

@Diagoras

I mean, For compatibility with spring-context-indexer, the Swagger configuration should be modified.

@Configuration
@Import({ SpringfoxWebMvcConfiguration.class, SwaggerCommonConfiguration.class })
//  TODO: remove below: componentScan of external library does not work when using spring-context-indexer. 
//  @ComponentScan(basePackages = { 
//     "springfox.documentation.swagger2.mappers"
//  })   
//   
@ConditionalOnWebApplication
public class Swagger2DocumentationConfiguration {
 
    // TODO:  Add all the @Components under "springfox.documentation.swagger2.mappers" as beans.
     @Bean
     public ModelMapper modelMapper() {
         return new ModelMapperImpl();
     }  

     @Bean
     public ParameterMapper parameterMapper() {
         return new ParameterMapperImpl();
     }  

     @Bean
     public SecurityMapper securityMapper() {
         return new SecurityMapperImpl();
     }  

     @Bean
     public LicensMapperImpl licenseMapper() {
         return new LicenseMapperImpl();
     }
   
     @Bean
     public  VendorExtensionMapper vendorExtensionMapper() {
          return new VendorExtensionsMapperImpl();  
     }

    @Bean
  public ServiceModelToSwagger2Mapper serviceModelToSwagger2Mapper(
     ModelMapper modelMapper,
     ParameterMapper parameterMapper,
     SecurityMapper securityMapper,
     LicenseMapper licenseMapper,
     VendorExtensionMapper vendorExtensionMapper) {
          return new ServiceModelToSwagger2MapperImpl(modelMapper, parameterMapper, securityMapper, licenseMapper, vendorExtensionMapper);
     }
}

In addition, @Components under the following packages may require @Bean registration.

  • SpringfoxWebMvcConfiguration.java

    springfox.documentation.spring.web.scanners springfox.documentation.spring.web.readers.operation springfox.documentation.spring.web.readers.parameter springfox.documentation.spring.web.plugins springfox.documentation.spring.web.paths

  • ModelConfiguration

    springfox.documentation.schema

  • SwaggerCommonConfiguration

    springfox.documentation.swagger.schema springfox.documentation.swagger.readers springfox.documentation.swagger.web


I hope to fix this setting in swagger.

Otherwise, all @Components in the above package must be registered by the developer directly with @Bean.

@dilipkrish cc: @ssouris @nathanmauro I wrote a PR for this issue. Could you review it?

https://github.com/springfox/springfox/pull/2971

Any update on this issue? 😃 I thought it was just me when I updated and wanted to use spring-context-indexer. but it turns out allot of other people have this as well.

movement?

@dilipkrish Using spring-context-indexer will index @Components and do component scanning at runtime. The @Component of a dependency library such as springfox-swagger2 is not indexed, so it is not registered in the runtime.

In my opinion, it would be better to allow springfox-swagger2’s component bean registration to be registered as @Bean under @Configuration rather than relying on @ComponentScan. (ServiceModelToSwagger2MapperImpl and so on…)

Then we think that the components needed by @Configuration in runtime can be registered as bean.

@dilipkrish spring-context-indexer

The Spring Context Indexer scans classes that are annotated by @Component in the classpath at compile time and writes them to META-INF/spring.components. And, at runtime, only the classes of `META-INF/spring.components’ recorded without @Component Annotation scan can be registered as beans, saving the scanning time.

@Component is scanned and recorded at compile time, but the @Component class inside the dependency library is not scanned. (Such as Swagger’s ServiceModelToSwagger2MapperImpl)

Swagger’s @Component classes are not listed in META-INF/spring.components and will not be registered as beans at runtime.

This is the cause of the current problem.

Swagger’s @Component in Spring should be registered as a bean at runtime. (You can not rely on ComponentScan.)

The solution is to declare @Component of Swagger as @Bean in @Configuration class.

Has anybody figured out how to resolve this? I am very interested in using this new feature of spring 5 but need to also use springfox.

Even if there is a temporary workaround that someone has come up with, I would be very interested.

@mhyeon-lee,

My application is running after applying your suggested code, however, my swagger ui shows only the following message and gets stuck in a loop.

Unable to infer base url. This is common when using dynamic servlet registration or when the API is behind an API Gateway. The base url is the root of where all the swagger resources are served. For e.g. if the api is available at http://example.org/api/v2/api-docs then the base url is http://example.org/api/. Please enter the location manually:

Any suggest of how to fix that?

@wgorski definitely yes. I could use some help if you’re aware of how to solve this problem.

Its not the same issue @lucasoares. I dont recall why @wreulicke closed his PR. This would be awesome to get back working

@dilipkrish, is this something you will want to look at sooner or rather later? We’re trying to figure out if we are should wait or look for a workaround. Thanks