Reputation: 1636
I moved my project from spring-boot 2.1.9 to 2.2.0.
While starting the project, I am facing the below error
messages.
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.springframework.plugin.core.PluginRegistry<org.springframework.hateoas.client.LinkDiscoverer, org.springframework.http.MediaType>' available: expected single matching bean but found 17: modelBuilderPluginRegistry,modelPropertyBuilderPluginRegistry,typeNameProviderPluginRegistry,syntheticModelProviderPluginRegistry,documentationPluginRegistry,apiListingBuilderPluginRegistry,operationBuilderPluginRegistry,parameterBuilderPluginRegistry,expandedParameterBuilderPluginRegistry,resourceGroupingStrategyRegistry,operationModelsProviderPluginRegistry,defaultsProviderPluginRegistry,pathDecoratorRegistry,apiListingScannerPluginRegistry,relProviderPluginRegistry,linkDiscovererRegistry,entityLinksPluginRegistry
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'linkDiscoverers' defined in class path resource [org/springframework/hateoas/config/HateoasConfiguration.class]: Unsatisfied dependency expressed through method 'linkDiscoverers' parameter 0; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.springframework.plugin.core.PluginRegistry<org.springframework.hateoas.client.LinkDiscoverer, org.springframework.http.MediaType>' available: expected single matching bean but found 17: modelBuilderPluginRegistry,modelPropertyBuilderPluginRegistry,typeNameProviderPluginRegistry,syntheticModelProviderPluginRegistry,documentationPluginRegistry,apiListingBuilderPluginRegistry,operationBuilderPluginRegistry,parameterBuilderPluginRegistry,expandedParameterBuilderPluginRegistry,resourceGroupingStrategyRegistry,operationModelsProviderPluginRegistry,defaultsProviderPluginRegistry,pathDecoratorRegistry,apiListingScannerPluginRegistry,relProviderPluginRegistry,linkDiscovererRegistry,entityLinksPluginRegistry
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of method linkDiscoverers in org.springframework.hateoas.config.HateoasConfiguration
required a single bean, but 17 were found:
- modelBuilderPluginRegistry: defined in null
- modelPropertyBuilderPluginRegistry: defined in null
- typeNameProviderPluginRegistry: defined in null
- syntheticModelProviderPluginRegistry: defined in null
- documentationPluginRegistry: defined in null
- apiListingBuilderPluginRegistry: defined in null
- operationBuilderPluginRegistry: defined in null
- parameterBuilderPluginRegistry: defined in null
- expandedParameterBuilderPluginRegistry: defined in null
- resourceGroupingStrategyRegistry: defined in null
- operationModelsProviderPluginRegistry: defined in null
- defaultsProviderPluginRegistry: defined in null
- pathDecoratorRegistry: defined in null
- apiListingScannerPluginRegistry: defined in null
- relProviderPluginRegistry: defined by method 'relProviderPluginRegistry' in class path resource [org/springframework/hateoas/config/HateoasConfiguration.class]
- linkDiscovererRegistry: defined in null
- entityLinksPluginRegistry: defined by method 'entityLinksPluginRegistry' in class path resource [org/springframework/hateoas/config/WebMvcEntityLinksConfiguration.class]
What could have caused this issue ?
Note: I am not using HATEOAS in my pom.xml
file.
pom.xml
<properties>
<java.version>1.8</java.version>
<swagger-springfox.version>2.9.2</swagger-springfox.version>
<sonar.jacoco.execPath>${project.basedir}/target/jacoco.exec</sonar.jacoco.execPath>
<jasypt-spring-boot-starter>2.1.1</jasypt-spring-boot-starter>
<logbook-spring-boot-starter>1.13.0</logbook-spring-boot-starter>
<assertj-swagger>0.8.1</assertj-swagger>
<jacoco-version>0.8.4</jacoco-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-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger-springfox.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger-springfox.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-spring-web</artifactId>
<version>${swagger-springfox.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-core</artifactId>
<version>${swagger-springfox.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-data-rest</artifactId>
<version>${swagger-springfox.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-bean-validators</artifactId>
<version>${swagger-springfox.version}</version>
</dependency>
Upvotes: 44
Views: 52691
Reputation: 4792
As Alexander Weiß has already answered, the spring-plugin-core
dependency is resolved with the wrong version 1.2.0.RELEASE
.
In order to force usage of the correct 2.0.0.RELEASE
, you have to EITHER exclude the wrong transitive dependency and explicitly specify the correct one, OR to pin (!) that dependency version in your pom.xml
. This is done in the <dependenciesManagement>
block, not in the <dependencies>
block. Pinning example for Springfox 3.0.0:
<properties>
<spring-plugin-core.version>2.0.0.RELEASE</spring-plugin-core.version>
<springfox.version>3.0.0</springfox.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- API Documentation -->
<!-- Fix wrong resolved `spring-plugin-core` dependency version for springfox -->
<dependency>
<groupId>org.springframework.plugin</groupId>
<artifactId>spring-plugin-core</artifactId>
<version>${spring-plugin-core.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>${springfox.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- API Documentation -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
</dependency>
</dependencies>
Upvotes: 1
Reputation: 1038
You can change the version like this:
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.8.0</version>
</dependency>
I am working with Spring Boot 2.4.1. But you can not see Swagger endpoint log when starting Spring Boot application.
Upvotes: 2
Reputation: 614
Use following 2 dependency to resolve Swagger and Hateoas dependency conflict.
If Spring Boot version is >= 2.2.0 the use io.springfox version 3.0.0
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>3.0.0</version>
</dependency>
After using version 3.0.0 swagger-ui will not be working so use following dependency and user /swagger-ui/ instead /swagger-ui.html
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
Upvotes: 9
Reputation: 1149
I am using springdoc-openapi and after having encountered this problem similar to the one mentioned here:
Description:
Parameter 0 of method linkDiscoverers in org.springframework.hateoas.config.HateoasConfiguration required a single bean, but 3 were found:
- relProviderPluginRegistry: defined by method 'relProviderPluginRegistry' in class path resource [org/springframework/hateoas/config/HateoasConfiguration.class]
- linkDiscovererRegistry: defined in null
- entityLinksPluginRegistry: defined by method 'entityLinksPluginRegistry' in class path resource [org/springframework/hateoas/config/WebMvcEntityLinksConfiguration.class]
Action:
Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed
I just add this dependency in my pom file
<dependency>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
<version>1.1.1.RELEASE</version>
</dependency>
hope that this can help someone
Upvotes: 2
Reputation: 41
I was getting error
"Error creating bean with name 'halLinkDisocoverer' defined in class path resource [org/springframework/hateoas/mediatype/hal/HalMediaTypeConfiguration.class]"..
While Building a Hypermedia-Driven RESTful Web Service
Deletion of this dependency
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<scope>test</scope>
</dependency>
resolved my issue.
Check this link for more details Why i am getting an error Factory method 'halLinkDisocoverer' threw exception in springboot?
Upvotes: 1
Reputation: 473
This kind of issue is occurring due to a new feature of Hateoas.
If you want to solve this problem , just embed the following line of codes in your swagger configuration file.
@Primary
@Bean
public LinkDiscoverers discoverers() {
List<LinkDiscoverer> plugins = new ArrayList<>();
plugins.add(new CollectionJsonLinkDiscoverer());
return new LinkDiscoverers(SimplePluginRegistry.create(plugins));
}
I think this is gonna solve your problem as it solved mine.
Upvotes: 8
Reputation: 23188
I had this issue with Swagger + HATEOAS
in my spring-boot
application.
The fix is given below (edit your Swagger configuration class):
@Configuration
@EnableSwagger2
public class SwaggerConfiguration {
@Bean
public LinkDiscoverers discoverers() {
List<LinkDiscoverer> plugins = new ArrayList<>();
plugins.add(new CollectionJsonLinkDiscoverer());
return new LinkDiscoverers(SimplePluginRegistry.create(plugins));
}
}
Upvotes: 72
Reputation: 743
For me this link helped: https://github.com/spring-projects/spring-hateoas/issues/731
In a nutshell i added to my dependencies:
<dependency>
<groupId>org.springframework.plugin</groupId>
<artifactId>spring-plugin-core</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
Upvotes: 21
Reputation: 632
The issue faced with me when i using
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.6.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
.....
.....
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>
with springfox swagger
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
if you take a look into spring hateoas dependencies there is a dependency on spring-plugin-core
with version 2.0.0.RELEASE
<dependency>
<groupId>org.springframework.plugin</groupId>
<artifactId>spring-plugin-core</artifactId>
<version>${spring-plugin.version}</version>
</dependency>
but swagger dependency use spring-plugin-core
with version 1.2.0.RELEASE
.
spring-boot have conflict on bean creation so, you need to unify the org.springframework.plugin
version to make spring see it, If you choose 2.0.0.RELEASE
swagger will bot be able to compile,
so version 1.2.0.RELEASE
will be work for both dependencies, like
<dependency>
<groupId>org.springframework.plugin</groupId>
<artifactId>spring-plugin-core</artifactId>
<version>1.2.0.RELEASE</version>
</dependency>
After that you need configuration class to initiate beans for swagger
and hateoas
like this:
@EnableSwagger2
@Configuration
public class SwaggerConfiguration {
@Primary
@Bean
public LinkDiscoverers discoverers() {
List<LinkDiscoverer> plugins = new ArrayList<>();
plugins.add(new CollectionJsonLinkDiscoverer());
return new LinkDiscoverers(SimplePluginRegistry.create(plugins));
}
@Bean
public Docket postsApi() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("{ApplicationName}")
.apiInfo(buildApiInfo())
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.regex("/.*"))
.build();
}
private ApiInfo buildApiInfo() {
Contact contact = new Contact("CompanyName", "https://company-domain.com", "[email protected]");
return new ApiInfoBuilder()
.title(""{ApplicationName}"")
.description("API Description")
.license("license")
.version("1.0")
.contact(contact)
.licenseUrl("licenseURl")
.build();
}
}
Upvotes: 6
Reputation: 346
For Spring boot version 2.1.3.RELEASE
users, the following dependencies work fine for hateoas+swagger:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
Upvotes: 3
Reputation: 25
Best Solution
Add below code in SwaggerConfig class
@Bean
public LinkDiscoverers discovers() {
List<LinkDiscoverer> plugins = new ArrayList<>();
plugins.add(new CollectionJsonLinkDiscoverer());
return new LinkDiscoverers(SimplePluginRegistry.create(plugins));[enter image description here][1]
}
Upvotes: 1
Reputation: 59
try this version 2.6.1,i already solve with this way
<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>
Upvotes: 3
Reputation: 611
I've removed these dependencies as a workaround and worked:
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.4.0</version>
</dependency>
please let me know if worked for you.
Upvotes: 0
Reputation: 500
Resolved it, it was happening due to integration when Swagger + HATEOAS was used with Spring Boot 2.2.4.RELEASE
package com.company.springbootworks.swagger;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.hateoas.client.LinkDiscoverer;
import org.springframework.hateoas.client.LinkDiscoverers;
import org.springframework.hateoas.mediatype.collectionjson.CollectionJsonLinkDiscoverer;
import org.springframework.http.ResponseEntity;
import org.springframework.plugin.core.SimplePluginRegistry;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger.web.DocExpansion;
import springfox.documentation.swagger.web.ModelRendering;
import springfox.documentation.swagger.web.OperationsSorter;
import springfox.documentation.swagger.web.TagsSorter;
import springfox.documentation.swagger.web.UiConfiguration;
import springfox.documentation.swagger.web.UiConfigurationBuilder;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public LinkDiscoverers discoverers() {
List<LinkDiscoverer> plugins = new ArrayList<>();
plugins.add(new CollectionJsonLinkDiscoverer());
return new LinkDiscoverers(SimplePluginRegistry.create(plugins));
}
@Bean
public Docket eDesignApi(SwaggerConfigProperties swaggerConfigProperties) {
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo(swaggerConfigProperties))
.enable(Boolean.valueOf(swaggerConfigProperties.getEnabled())).select()
.apis(RequestHandlerSelectors.any()).paths(PathSelectors.any()).build().pathMapping("/")
.directModelSubstitute(LocalDate.class, String.class).genericModelSubstitutes(ResponseEntity.class)
.useDefaultResponseMessages(Boolean.valueOf(swaggerConfigProperties.getUseDefaultResponseMessages()))
.enableUrlTemplating(Boolean.valueOf(swaggerConfigProperties.getEnableUrlTemplating()));
}
@Bean
UiConfiguration uiConfig(SwaggerConfigProperties swaggerConfigProperties) {
return UiConfigurationBuilder.builder().deepLinking(Boolean.valueOf(swaggerConfigProperties.getDeepLinking()))
.displayOperationId(Boolean.valueOf(swaggerConfigProperties.getDisplayOperationId()))
.defaultModelsExpandDepth(Integer.valueOf(swaggerConfigProperties.getDefaultModelsExpandDepth()))
.defaultModelExpandDepth(Integer.valueOf(swaggerConfigProperties.getDefaultModelExpandDepth()))
.defaultModelRendering(ModelRendering.EXAMPLE)
.displayRequestDuration(Boolean.valueOf(swaggerConfigProperties.getDisplayRequestDuration()))
.docExpansion(DocExpansion.NONE).filter(Boolean.valueOf(swaggerConfigProperties.getFilter()))
.maxDisplayedTags(Integer.valueOf(swaggerConfigProperties.getMaxDisplayedTags()))
.operationsSorter(OperationsSorter.ALPHA)
.showExtensions(Boolean.valueOf(swaggerConfigProperties.getShowExtensions()))
.tagsSorter(TagsSorter.ALPHA).supportedSubmitMethods(UiConfiguration.Constants.DEFAULT_SUBMIT_METHODS)
.validatorUrl(null).build();
}
private ApiInfo apiInfo(SwaggerConfigProperties swaggerConfigProperties) {
return new ApiInfoBuilder().title(swaggerConfigProperties.getTitle())
.description(swaggerConfigProperties.getDescription()).version(swaggerConfigProperties.getApiVersion())
.build();
}
}
and below are the swagger dependencies
<properties>
<java.version>1.8</java.version>
<swagger.version>2.9.2</swagger.version>
<swagger-annotations.version>1.5.21</swagger-annotations.version>
<swagger-models.version>1.5.21</swagger-models.version>
<spring-plugin.version>2.0.0.BUILD-SNAPSHOT</spring-plugin.version>
</properties>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>${swagger-annotations.version}</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>${swagger-models.version}</version>
</dependency>
Upvotes: 0
Reputation: 11
If you want Swagger
, but can compromise with HATEOAS
, then just remove the HATEOAS dependency and add:
compile group: 'io.springfox', name: 'springfox-swagger-ui', version:'2.9.2'
compile group: 'io.springfox', name: 'springfox-swagger2', version: '2.9.2'
Upvotes: 0
Reputation: 269
So I actually wanted hateoas support and had the same issue. Turned out this happens if you have
<dependency>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
</dependency>
instead of
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>
Upvotes: 0