I’m working on a Spring Boot application that interfaces with AWS S3, and I need to use LocalStack.
I want to configure the endpoint in application.properties
rather than in the Java code with .withEndpointConfiguration()
. This is because I can’t modify my Java code.
Here’s my Java code:
AmazonS3 client = AmazonS3ClientBuilder.standard()
.withPathStyleAccessEnabled(true)
.withRegion("us-east-1")
.withCredentials(awsCredentialsProvider())
.build();
In application.properties
, I’ve got:
aws.endpoint=http://localhost:4566
In my pom.xml
, I have included the following dependencies:
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3</artifactId>
<version>1.12.68</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-sts</artifactId>
<version>1.12.151</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
However, I’m encountering an error that seems to indicate it’s connecting to AWS instead of LocalStack.
The error message is:
com.amazonaws.services.s3.model.AmazonS3Exception: The AWS Access Key Id you provided does not exist in our records. (Service: Amazon S3; Status Code: 403; Error Code: InvalidAccessKeyId; Request ID: xxx; S3 Extended Request ID: xxx; Proxy: null)
Can I use application.properties
to define the S3 endpoint for the AWS SDK for Java?
2
Answers
The AWS SDK for Java v1/v2 itself doesn’t support setting the S3 endpoint via system properties.
If you only want to use
application.properties
for reading & setting the LocalStack S3 endpoint, you would typically already need to be using a library like Spring Cloud AWS that supports setting it viacloud.aws.s3.endpoint
.Without such a library, there’s no out-of-the-box way to do this.
You would need to set it programmatically using
.withEndpointConfiguration()
.Here’s an alternative and example that might help you: https://github.com/localstack-samples/sample-shipment-list-demo-lambda-dynamodb-s3. The whole point of it is to let you configure your beans based on Spring profiles, and runs on both AWS and LocalStack. The extended description is in the README.md file.
The short version: You can use different profiles to configure your beans based on their environments (dev, test, prod, etc). So with
.withEndpointConfiguration()
you can use the@Value
annotation when you declare your variable, in association with@Configuration
on the class level (seeAmazonS3Config
class) and anapplication-<profile>.yml
file. You then run your app usingmvn spring-boot:run -Dspring-boot.run.profiles=<profile>
.It looks like you’re using the Java AWS SDK v1 and the sample is using v2, but no worries, this is only a matter of library syntax when you configure your beans.