I recently upgraded my SpringCloud project from Brixton to Finchley and everything was working just fine. I was working on Finchley.SR2 and I had no problems, but whenever I upgrade my project to Finchley.RELEASE (and this is the only change I make), the project fails to start.
The reason is that the project could not find the AmazonS3Client
Bean:
...Unsatisfied dependency expressed through constructor parameter 0;
nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type 'com.amazonaws.services.s3.AmazonS3Client' available:
expected at least 1 bean which qualifies as autowire candidate.
Dependency annotations: {}
These are my previous relevant configurations and classes:
build.gradle
buildscript {
ext {
springBootVersion = '2.0.2.RELEASE'
}
...
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath('io.spring.gradle:dependency-management-plugin:1.0.5.RELEASE')
}
}
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:Finchley.SR2"
}
}
dependencies {
...
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.cloud:spring-cloud-starter-aws')
compile('org.springframework.cloud:spring-cloud-starter-config'
...
}
...
S3Config.java (The class that creates the AmazonS3/AmazonS3Client Bean)
...
@Configuration
public class S3Config {
@Bean
public AmazonS3 amazonS3() {
return AmazonS3ClientBuilder.standard()
.withCredentials(new DefaultAWSCredentialsProviderChain())
.build();
}
}
StorageService (the class that fails to find the Bean)
...
@Service
public class StorageService {
private final AmazonS3Client amazonS3Client;
@Autowired
public StorageService(AmazonS3Client amazonS3Client) {
this.amazonS3Client = amazonS3Client;
}
...
}
And this is the only change I make to the build.gradle file when upgrading to Finchley.Release:
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:Finchley.RELEASE"
}
}
I've tried looking for any missing library and tweaking all the configurations I can find, but none seem to take any effect.
After a brief talk with the Spring maintainers, a solution was found.
It seems I was at fault by assuming that a Bean of AmazonS3
should always be found as an AmazonS3Client
Bean just because one implements the other. It was just pure luck that it worked on previous Spring versions.
The proper way to create an AmazonS3Client
would be the following:
@Configuration
public class S3Config {
@Bean
public static AmazonS3Client amazonS3Client() {
return (AmazonS3Client) AmazonS3ClientBuilder.standard()
.withCredentials(new DefaultAWSCredentialsProviderChain())
.build();
}
}