From a28d1f4ab933f4465dc3e760cfd1d20d6c4969f3 Mon Sep 17 00:00:00 2001 From: Nikita Karpuk Date: Tue, 16 Dec 2025 21:08:51 +0100 Subject: [PATCH 1/3] Spring: fix standalone run --- spring-app/build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-app/build.gradle b/spring-app/build.gradle index cfe3228..4d3a35f 100644 --- a/spring-app/build.gradle +++ b/spring-app/build.gradle @@ -32,6 +32,7 @@ dependencyManagement { dependencies { implementation project(":common-api") implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-restclient' implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-starter-actuator' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' From 7a4127a0c1757839ff759ae981d13e0bb71b18b9 Mon Sep 17 00:00:00 2001 From: Nikita Karpuk Date: Tue, 16 Dec 2025 21:09:21 +0100 Subject: [PATCH 2/3] Align Jackson configs --- .../bitxon/dropwizard/DropwizardApplication.java | 6 ++++++ .../dropwizard/test/GetByIdDropwizardTest.java | 3 ++- micronaut-app/src/main/resources/application.yml | 6 ++++++ .../micronaut/test/GetAccountByIdMicronautTest.java | 3 ++- .../RegisterObjectMapperCustomizer.java | 4 ++-- .../quarkus/test/GetAccountByIdQuarkusTest.java | 12 +++++++++--- spring-app/src/main/resources/application.yml | 3 +++ .../bitxon/spring/test/GetAccountByIdSpringTest.java | 3 ++- 8 files changed, 32 insertions(+), 8 deletions(-) diff --git a/dropwizard-app/src/main/java/bitxon/dropwizard/DropwizardApplication.java b/dropwizard-app/src/main/java/bitxon/dropwizard/DropwizardApplication.java index 2e2d660..104be00 100644 --- a/dropwizard-app/src/main/java/bitxon/dropwizard/DropwizardApplication.java +++ b/dropwizard-app/src/main/java/bitxon/dropwizard/DropwizardApplication.java @@ -10,6 +10,8 @@ import bitxon.dropwizard.errorhandler.ResourceNotFoundExceptionHandler; import bitxon.dropwizard.mapper.AccountMapper; import bitxon.dropwizard.resource.AccountResource; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.SerializationFeature; import io.dropwizard.client.JerseyClientBuilder; import io.dropwizard.core.Application; import io.dropwizard.core.setup.Bootstrap; @@ -67,6 +69,10 @@ protected void configure() { var exchangeClient = new ExchangeClient(client, configuration.getExchangeClientConfig()); environment.jersey().register(exchangeClient); + var objectMapper = environment.getObjectMapper(); + objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + objectMapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY); // not really necessary, but shows how to customize Jackson + environment.jersey().register(AccountResource.class); diff --git a/dropwizard-app/src/test/java/bitxon/dropwizard/test/GetByIdDropwizardTest.java b/dropwizard-app/src/test/java/bitxon/dropwizard/test/GetByIdDropwizardTest.java index 33e487b..e91872f 100644 --- a/dropwizard-app/src/test/java/bitxon/dropwizard/test/GetByIdDropwizardTest.java +++ b/dropwizard-app/src/test/java/bitxon/dropwizard/test/GetByIdDropwizardTest.java @@ -19,7 +19,8 @@ void getById() { .get("/accounts/{id}") .then() .statusCode(200) - .body("id", is(expectedId)); + .body("id", is(expectedId)) + .body("dateOfBirth", is("1991-01-21")); //@formatter:on } diff --git a/micronaut-app/src/main/resources/application.yml b/micronaut-app/src/main/resources/application.yml index add6f5a..bf8ea9b 100644 --- a/micronaut-app/src/main/resources/application.yml +++ b/micronaut-app/src/main/resources/application.yml @@ -24,6 +24,12 @@ netty: allocator: max-order: 3 +jackson: + serialization: + WRITE_DATES_AS_TIMESTAMPS: false + deserialization: + ACCEPT_SINGLE_VALUE_AS_ARRAY: true # not really necessary, but shows how to customize Jackson + datasources: default: maximum-pool-size: 40 # default=10 diff --git a/micronaut-app/src/test/java/bitxon/micronaut/test/GetAccountByIdMicronautTest.java b/micronaut-app/src/test/java/bitxon/micronaut/test/GetAccountByIdMicronautTest.java index 3f15ed7..a5df2ce 100644 --- a/micronaut-app/src/test/java/bitxon/micronaut/test/GetAccountByIdMicronautTest.java +++ b/micronaut-app/src/test/java/bitxon/micronaut/test/GetAccountByIdMicronautTest.java @@ -20,7 +20,8 @@ void getById() { .get("/accounts/{id}") .then() .statusCode(200) - .body("id", is(expectedId)); + .body("id", is(expectedId)) + .body("dateOfBirth", is("1991-01-21")); //@formatter:on } diff --git a/quarkus-app/src/main/java/bitxon/quarkus/customization/RegisterObjectMapperCustomizer.java b/quarkus-app/src/main/java/bitxon/quarkus/customization/RegisterObjectMapperCustomizer.java index cd2c4c9..b2096e3 100644 --- a/quarkus-app/src/main/java/bitxon/quarkus/customization/RegisterObjectMapperCustomizer.java +++ b/quarkus-app/src/main/java/bitxon/quarkus/customization/RegisterObjectMapperCustomizer.java @@ -1,6 +1,6 @@ package bitxon.quarkus.customization; -import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import io.quarkus.jackson.ObjectMapperCustomizer; import jakarta.inject.Singleton; @@ -9,6 +9,6 @@ public class RegisterObjectMapperCustomizer implements ObjectMapperCustomizer { public void customize(ObjectMapper mapper) { - mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + mapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY); // not really necessary, but shows how to customize Jackson } } diff --git a/quarkus-app/src/test/java/bitxon/quarkus/test/GetAccountByIdQuarkusTest.java b/quarkus-app/src/test/java/bitxon/quarkus/test/GetAccountByIdQuarkusTest.java index 2ebdf58..78a6e35 100644 --- a/quarkus-app/src/test/java/bitxon/quarkus/test/GetAccountByIdQuarkusTest.java +++ b/quarkus-app/src/test/java/bitxon/quarkus/test/GetAccountByIdQuarkusTest.java @@ -2,6 +2,7 @@ import static io.restassured.RestAssured.given; import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.is; import io.quarkus.test.junit.QuarkusTest; import org.junit.jupiter.api.Test; @@ -11,13 +12,18 @@ public class GetAccountByIdQuarkusTest extends AbstractQuarkusTest { @Test public void getById() { + var expectedId = 1; + //@formatter:off given() + .pathParam("id", expectedId) .when() - .get("/accounts/1") + .get("/accounts/{id}") .then() - .statusCode(200); - //@formatter:off + .statusCode(200) + .body("id", is(expectedId)) + .body("dateOfBirth", is("1991-01-21")); + //@formatter:on } @Test diff --git a/spring-app/src/main/resources/application.yml b/spring-app/src/main/resources/application.yml index c1f5407..ce8f603 100644 --- a/spring-app/src/main/resources/application.yml +++ b/spring-app/src/main/resources/application.yml @@ -10,6 +10,9 @@ management: port: 8081 spring: + jackson: + deserialization: + ACCEPT_SINGLE_VALUE_AS_ARRAY: true # not really necessary, but shows how to customize Jackson datasource: hikari: maximum-pool-size: 40 # default=10 diff --git a/spring-app/src/test/java/bitxon/spring/test/GetAccountByIdSpringTest.java b/spring-app/src/test/java/bitxon/spring/test/GetAccountByIdSpringTest.java index 26140fd..ebd3762 100644 --- a/spring-app/src/test/java/bitxon/spring/test/GetAccountByIdSpringTest.java +++ b/spring-app/src/test/java/bitxon/spring/test/GetAccountByIdSpringTest.java @@ -19,7 +19,8 @@ void getById() { .get("/accounts/{id}") .then() .statusCode(200) - .body("id", is(expectedId)); + .body("id", is(expectedId)) + .body("dateOfBirth", is("1991-01-21")); //@formatter:on } From 27774eceae3d1a236a6c6ff7718df433ac566482 Mon Sep 17 00:00:00 2001 From: Nikita Karpuk Date: Tue, 16 Dec 2025 21:33:46 +0100 Subject: [PATCH 3/3] GitHub Actions update --- .github/workflows/cicd-build.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/cicd-build.yml b/.github/workflows/cicd-build.yml index a96dacf..2461775 100644 --- a/.github/workflows/cicd-build.yml +++ b/.github/workflows/cicd-build.yml @@ -18,16 +18,16 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v6 - name: Set up JDK 21 - uses: actions/setup-java@v2 + uses: actions/setup-java@v5 with: java-version: '21' - distribution: 'adopt' + distribution: 'zulu' - name: Build with Gradle - run: ./gradlew clean build --parallel + run: ./gradlew clean build - name: Quarkus Native Image Test run: ./gradlew :quarkus-app:testNative