Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,10 @@ name: "CodeQL"

on:
push:
branches: [s3mock-v2, main]
branches: [s3mock-v2, s3mock-v3, s3mock-v4, main]
pull_request:
# The branches below must be a subset of the branches above
branches: [s3mock-v2, main]
schedule:
- cron: '43 21 * * 6'
branches: [s3mock-v2, s3mock-v3, s3mock-v4, main]

# Declare default permissions as read only.
permissions: read-all
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/maven-ci-and-prb.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ name: Maven Build

on:
push:
branches: [s3mock-v2, main]
branches: [s3mock-v2, s3mock-v3, s3mock-v4, main]
pull_request:
branches: [s3mock-v2, main]
branches: [s3mock-v2, s3mock-v3, s3mock-v4, main]

# Declare default permissions as read only.
permissions: read-all
Expand Down
5 changes: 3 additions & 2 deletions .github/workflows/maven-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,9 @@ jobs:
- name: Set up JDK
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
java-version: 21
distribution: 'temurin'
java-version: 25
distribution: 'oracle'
cache: 'maven'

# The release build pushes a Docker image to Docker Hub, so we need to log in
- name: Perform docker login
Expand Down
39 changes: 31 additions & 8 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ Whenever a 3rd party library is updated, S3Mock will update it's MINOR version.
# PLANNED - 6.x - RELEASE TBD
Version 6.x is JDK25 LTS bytecode compatible, with Docker integration.

Probably released with Spring Boot 5.x, updating baselines etc. as Spring Boot 5.x requires.
Will be released after Spring Boot 5.x, updating baselines etc. as Spring Boot 5.x requires.

Any JUnit / direct Java usage support will most likely be dropped and only supported on a best-effort basis.
(i.e., the modules will be deleted from the code base and not released anymore. It *may* be possible to
Expand Down Expand Up @@ -149,7 +149,13 @@ Version 5.x is JDK17 LTS bytecode compatible, with Docker and JUnit / direct Jav
## 5.0.0

* Features and fixes
* Breaking change (file system): Remove "DisplayName" from Owner. (fixes #2738)
* AWS APIs stopped returning "DisplayName" in November 2025.
* This is unfortunately a breaking change for clients starting S3Mock on existing file systems.
* Get object with range now returns the same headers as non-range calls.
* Docker: Copy "s3mock.jar" to "/opt/", run with absolute path reference to avoid issues when working directory is changed. (fixes #2827)
* S3Mock supports ChecksumType.FULL_OBJECT for Multipart uploads (fixes #2843)
* Return 412 on if-none-match=true when making CompleteMultipartRequest (fixes #2790)
* Refactorings
* Use Jackson 3 annotations and mappers.
* AWS has deprecated SDK for Java v1 and will remove support EOY 2025.
Expand All @@ -159,14 +165,31 @@ Version 5.x is JDK17 LTS bytecode compatible, with Docker and JUnit / direct Jav
* Remove legacy properties for S3Mock configuration.
* Move all controller-related code from "com.adobe.testing.s3mock" to "com.adobe.testing.s3mock.controller" package.
* Remove Apache libraries like "commons-compress", "commons-codec" or "commons-lang3" from dependencies. Kotlin and Java standard library provide similar functionality.
* Version updates
* Bump Spring Boot version to 4.0.0
* Bump Spring Framework version to 7.0.1
* Bump java version from 17 to 25
* Compile with Java 25, target Java 17
* Version updates (deliverable dependencies)
* Bump spring-boot.version from 3.5.8 to 4.0.2
* Bump Java version from 17 to 25
* Compile with Java 25, target Java 17. [This follows Spring guidance](https://spring.io/blog/2025/11/13/spring-framework-7-0-general-availability)
* Docker container runs Java 25
* Bump TestContainers to 2.0.2
* Bump Maven to 4.0.0
* Bump Bump testcontainers.version from 1.21.3 to 2.0.2
* Bump kotlin.version from 2.2.21 to 2.3.0
* Compile with Kotlin 2.3, target Kotlin 2.2. [This follows Spring guidance](https://spring.io/blog/2025/12/18/next-level-kotlin-support-in-spring-boot-4#kotlin-2-baseline)
* Bump alpine from 3.23.0 to 3.23.3 in /docker
* Bump org.testng:testng from 7.11.0 to 7.12.0
* Bump aws-v2.version from 2.40.0 to 2.41.23
* Version updates (build dependencies)
* Bump aws.sdk.kotlin:s3-jvm from 1.5.95 to 1.6.11
* Bump Maven to 4.0.0-rc5 (TODO: update to 4.0.0)
* Bump org.mockito.kotlin:mockito-kotlin from 6.1.0 to 6.2.3
* Bump org.apache.maven.plugins:maven-release-plugin from 3.3.0 to 3.3.1
* Bump org.codehaus.mojo:exec-maven-plugin from 3.6.2 to 3.6.3
* Bump org.apache.maven.plugins:maven-compiler-plugin from 3.14.1 to 3.15.0
* Bump digital.pragmatech.testing:spring-test-profiler from 0.0.14 to 0.0.15
* Bump com.puppycrawl.tools:checkstyle from 12.2.0 to 13.2.0
* Bump actions/upload-artifact from 5.0.0 to 6.0.0
* Bump actions/checkout from 6.0.1 to 6.0.2
* Bump github/codeql-action from 4.31.6 to 4.32.2
* Bump actions/setup-java from 5.0.0 to 5.2.0
* Bump step-security/harden-runner from 2.13.3 to 2.14.1

# DEPRECATED - 4.x
Version 4.x is JDK17 LTS bytecode compatible, with Docker and JUnit / direct Java integration.
Expand Down
7 changes: 5 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright 2017-2025 Adobe.
# Copyright 2017-2026 Adobe.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand All @@ -14,7 +14,7 @@
# limitations under the License.
#

.PHONY: build verify install
.PHONY: build verify install sort
.DEFAULT_GOAL := build

build: verify
Expand All @@ -24,3 +24,6 @@ verify:

install:
./mvnw -B -V -Dstyle.color=always clean install

sort:
./mvnw -B -V -Dstyle.color=always com.github.ekryd.sortpom:sortpom-maven-plugin:sort
4 changes: 2 additions & 2 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ ENV JAVA_HOME=/opt/java-minimal
ENV PATH="$PATH:$JAVA_HOME/bin"

COPY --from=staging_area "$JAVA_HOME" "$JAVA_HOME"
COPY ./target/s3mock-exec.jar s3mock.jar
COPY ./target/s3mock-exec.jar /opt/s3mock.jar

ENV LANG=en_US.UTF-8
ENV LANGUAGE=en_US:en
Expand All @@ -69,4 +69,4 @@ ENV root=/s3mockroot
EXPOSE 9090 9191

# run the app on startup
ENTRYPOINT ["java", "--illegal-access=warn", "-Djava.security.egd=file:/dev/./urandom", "-XX:+UseZGC", "-XX:+ZGenerational", "-jar", "s3mock.jar" ]
ENTRYPOINT ["java", "--illegal-access=warn", "-Djava.security.egd=file:/dev/./urandom", "-XX:+UseZGC", "-XX:+ZGenerational", "-jar", "/opt/s3mock.jar" ]
80 changes: 40 additions & 40 deletions integration-tests/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@
<name>S3Mock - Integration Tests</name>

<dependencies>
<dependency>
<groupId>aws.sdk.kotlin</groupId>
<artifactId>s3-jvm</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.adobe.testing</groupId>
<artifactId>s3mock</artifactId>
Expand All @@ -48,6 +53,21 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
Expand All @@ -58,6 +78,12 @@
<artifactId>awaitility</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-reflect</artifactId>
<version>${kotlin.version}</version>
<scope>test</scope>
</dependency>
<!-- Force Kotlin stdlib alignment to match aws-sdk-kotlin 1.5.x requirements -->
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
Expand All @@ -67,8 +93,7 @@
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-reflect</artifactId>
<version>${kotlin.version}</version>
<artifactId>kotlin-test-junit</artifactId>
<scope>test</scope>
</dependency>
<!-- Force Kotlin coroutines alignment to match aws-sdk-kotlin 1.5.x requirements -->
Expand All @@ -84,11 +109,6 @@
<version>${kotlin-coroutines.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-test-junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
Expand All @@ -111,27 +131,22 @@
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>aws-query-protocol</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>aws-xml-protocol</artifactId>
<artifactId>aws-crt-client</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>s3</artifactId>
<artifactId>aws-query-protocol</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>url-connection-client</artifactId>
<artifactId>aws-xml-protocol</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>aws-crt-client</artifactId>
<artifactId>s3</artifactId>
<scope>test</scope>
</dependency>
<dependency>
Expand All @@ -140,23 +155,8 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>aws.sdk.kotlin</groupId>
<artifactId>s3-jvm</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<groupId>software.amazon.awssdk</groupId>
<artifactId>url-connection-client</artifactId>
<scope>test</scope>
</dependency>
<dependency>
Expand All @@ -172,7 +172,6 @@
</dependencies>

<build>
<testSourceDirectory>src/test/kotlin</testSourceDirectory>
<pluginManagement>
<plugins>
<plugin>
Expand Down Expand Up @@ -212,13 +211,13 @@
</plugins>
</pluginManagement>
<plugins>
<plugin>
<artifactId>maven-checkstyle-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.github.gantsign.maven</groupId>
<artifactId>ktlint-maven-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-checkstyle-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
Expand All @@ -228,11 +227,12 @@
</configuration>
</plugin>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
</plugin>
</plugins>
<testSourceDirectory>src/test/kotlin</testSourceDirectory>
</build>

<profiles>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ internal class AclIT : S3TestBase() {
}.also { resp ->
assertThat(resp.sdkHttpResponse().isSuccessful).isTrue()
assertThat(resp.owner().id()).isNotBlank()
assertThat(resp.owner().displayName()).isNotBlank()
assertThat(resp.grants()).hasSize(1)
assertThat(resp.grants().first().permission()).isEqualTo(FULL_CONTROL)
}
Expand All @@ -86,7 +85,6 @@ internal class AclIT : S3TestBase() {

acl.owner().also { owner ->
assertThat(owner.id()).isEqualTo(DEFAULT_OWNER.id)
assertThat(owner.displayName()).isEqualTo(DEFAULT_OWNER.displayName)
}

acl.grants().also {
Expand All @@ -102,7 +100,6 @@ internal class AclIT : S3TestBase() {
.also { grantee ->
assertThat(grantee).isNotNull
assertThat(grantee.id()).isEqualTo(DEFAULT_OWNER.id)
assertThat(grantee.displayName()).isEqualTo(DEFAULT_OWNER.displayName)
assertThat(grantee.type()).isEqualTo(CANONICAL_USER)
}
}
Expand All @@ -126,7 +123,6 @@ internal class AclIT : S3TestBase() {
it.accessControlPolicy {
it.owner {
it.id(userId)
it.displayName(userName)
}
it
.grants(
Expand All @@ -150,7 +146,6 @@ internal class AclIT : S3TestBase() {
acl.owner().also {
assertThat(it).isNotNull
assertThat(it.id()).isEqualTo(userId)
assertThat(it.displayName()).isEqualTo(userName)
}

assertThat(acl.grants()).hasSize(1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,6 @@ internal class BucketIT : S3TestBase() {
}
assertThat(it.prefix()).isNull()
assertThat(it.continuationToken()).isNull()
assertThat(it.owner().displayName()).isEqualTo("s3-mock-file-store")
assertThat(it.owner().id()).isEqualTo("79a59df900b949e55d96a1e698fbacedfd6e09d98eacf8f8d5218e7cd47ef2be")
}
}
Expand Down Expand Up @@ -205,7 +204,6 @@ internal class BucketIT : S3TestBase() {
}
assertThat(it.prefix()).isEqualTo(bucketName)
assertThat(it.continuationToken()).isNull()
assertThat(it.owner().displayName()).isEqualTo("s3-mock-file-store")
assertThat(it.owner().id()).isEqualTo("79a59df900b949e55d96a1e698fbacedfd6e09d98eacf8f8d5218e7cd47ef2be")
}
}
Expand Down Expand Up @@ -245,7 +243,6 @@ internal class BucketIT : S3TestBase() {
}
assertThat(it.prefix()).isNull()
assertThat(it.continuationToken()).isNotNull
assertThat(it.owner().displayName()).isEqualTo("s3-mock-file-store")
assertThat(it.owner().id()).isEqualTo("79a59df900b949e55d96a1e698fbacedfd6e09d98eacf8f8d5218e7cd47ef2be")
}.continuationToken()

Expand All @@ -263,7 +260,6 @@ internal class BucketIT : S3TestBase() {
}
assertThat(it.prefix()).isNull()
assertThat(it.continuationToken()).isNull()
assertThat(it.owner().displayName()).isEqualTo("s3-mock-file-store")
assertThat(it.owner().id()).isEqualTo("79a59df900b949e55d96a1e698fbacedfd6e09d98eacf8f8d5218e7cd47ef2be")
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,7 @@ internal class GetPutDeleteObjectIT : S3TestBase() {
)
}.also {
assertThat(it.eTag()).isEqualTo(eTag.trim('"'))
// default storageClass is STANDARD, which is never returned from APIs except by GetObjectAttributes
// GetObjectAttributes returns the default storageClass "STANDARD", even though other APIs may not.
assertThat(it.storageClass()).isEqualTo(StorageClass.STANDARD)
assertThat(it.objectSize()).isEqualTo(UPLOAD_FILE_LENGTH)
assertThat(it.checksum().checksumSHA1()).isEqualTo(expectedChecksum)
Expand Down
Loading
Loading