From 4298a402c8564d52da79ec455d7a74e0caff9a5c Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 4 Sep 2026 20:39:26 +0000 Subject: [PATCH] Upgrade to Spring Boot 4.1.1 / Java 26 to match GIM Inventar Software - Bump spring-boot-starter-parent to 4.1.1 and java.version to 26. - Fix source breakage from the Boot 4 / Spring Framework 7 API moves: ServletWebServerInitializedEvent relocated to org.springframework.boot.web.server.servlet.context, and Boot 4's web starter now pulls Jackson 3 (tools.jackson.*) instead of Jackson 2, so ObjectMapper/JsonProcessingException usage in DataExportController moves to tools.jackson.databind.ObjectMapper and the now-unchecked tools.jackson.core.JacksonException. - Replace the non-functional placeholder @SpringBootTest (this is a library with no bootable application, so a bare @SpringBootTest could never find a configuration class - it was already erroring before this change) with a real smoke test app that imports SnapAdminAutoConfiguration, boots a full Spring context, and hits the admin index and a model list route end-to-end. This is what previously crashed at startup on Spring Boot 4.1.1 when consumed as a published jar; it now builds and runs clean. - Bump the release workflow's JDK to 26 (temurin) to match. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01CzTxQYQNrcQaCJnYNELDaa --- .github/workflows/release.yml | 4 +- pom.xml | 4 +- .../external/StartupAuthCheckRunner.java | 2 +- .../controller/DataExportController.java | 14 +++---- .../SpringBootSnapAdminApplicationTests.java | 32 ---------------- .../smoketest/SmokeTestApplication.java | 11 ++++++ .../smoketest/SmokeTestApplicationTests.java | 38 +++++++++++++++++++ .../snapadmin/smoketest/SmokeTestEntity.java | 27 +++++++++++++ src/test/resources/application.properties | 9 +++++ 9 files changed, 97 insertions(+), 44 deletions(-) delete mode 100644 src/test/java/tech/ailef/snapadmin/SpringBootSnapAdminApplicationTests.java create mode 100644 src/test/java/tech/ailef/snapadmin/smoketest/SmokeTestApplication.java create mode 100644 src/test/java/tech/ailef/snapadmin/smoketest/SmokeTestApplicationTests.java create mode 100644 src/test/java/tech/ailef/snapadmin/smoketest/SmokeTestEntity.java create mode 100644 src/test/resources/application.properties diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e5b3b670..f23fa7e7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,8 +13,8 @@ jobs: - name: Set up Java uses: actions/setup-java@v3 with: - java-version: '17' - distribution: 'adopt' + java-version: '26' + distribution: 'temurin' - name: Publish package env: JRELEASER_NEXUS2_USERNAME: ${{ secrets.JRELEASER_NEXUS2_USERNAME }} diff --git a/pom.xml b/pom.xml index 3ca54996..c7b36056 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.springframework.boot spring-boot-starter-parent - 3.1.5 + 4.1.1 tech.ailef @@ -15,7 +15,7 @@ SnapAdmin SnapAdmin is an auto-generated CRUD admin panel for Spring Boot/JPA apps - 17 + 26 diff --git a/src/main/java/tech/ailef/snapadmin/external/StartupAuthCheckRunner.java b/src/main/java/tech/ailef/snapadmin/external/StartupAuthCheckRunner.java index c9ffede7..1b2d70f0 100644 --- a/src/main/java/tech/ailef/snapadmin/external/StartupAuthCheckRunner.java +++ b/src/main/java/tech/ailef/snapadmin/external/StartupAuthCheckRunner.java @@ -25,7 +25,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.web.servlet.context.ServletWebServerInitializedEvent; +import org.springframework.boot.web.server.servlet.context.ServletWebServerInitializedEvent; import org.springframework.context.ApplicationListener; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/src/main/java/tech/ailef/snapadmin/external/controller/DataExportController.java b/src/main/java/tech/ailef/snapadmin/external/controller/DataExportController.java index 30c33251..5037ef5c 100644 --- a/src/main/java/tech/ailef/snapadmin/external/controller/DataExportController.java +++ b/src/main/java/tech/ailef/snapadmin/external/controller/DataExportController.java @@ -51,8 +51,8 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.ObjectMapper; import tech.ailef.snapadmin.external.SnapAdmin; import tech.ailef.snapadmin.external.dbmapping.DbFieldValue; @@ -278,16 +278,16 @@ private String toJsonl(List items, List fields, boolean raw) { try { String json = mapper.writeValueAsString(map); sb.append(json); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { throw new SnapAdminException(e); } - + sb.append("\n"); } return sb.toString(); } - + private String toJsonlQuery(DbQueryResult result, List fields) { if (result.isEmpty()) return ""; @@ -299,10 +299,10 @@ private String toJsonlQuery(DbQueryResult result, List fields) { try { String json = mapper.writeValueAsString(map); sb.append(json); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { throw new SnapAdminException(e); } - + sb.append("\n"); } diff --git a/src/test/java/tech/ailef/snapadmin/SpringBootSnapAdminApplicationTests.java b/src/test/java/tech/ailef/snapadmin/SpringBootSnapAdminApplicationTests.java deleted file mode 100644 index 11a5005e..00000000 --- a/src/test/java/tech/ailef/snapadmin/SpringBootSnapAdminApplicationTests.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * SnapAdmin - An automatically generated CRUD admin UI for Spring Boot apps - * Copyright (C) 2023 Ailef (http://ailef.tech) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - -package tech.ailef.snapadmin; - -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest -class SpringBootSnapAdminApplicationTests { - - @Test - void contextLoads() { - } - -} diff --git a/src/test/java/tech/ailef/snapadmin/smoketest/SmokeTestApplication.java b/src/test/java/tech/ailef/snapadmin/smoketest/SmokeTestApplication.java new file mode 100644 index 00000000..c3ce856e --- /dev/null +++ b/src/test/java/tech/ailef/snapadmin/smoketest/SmokeTestApplication.java @@ -0,0 +1,11 @@ +package tech.ailef.snapadmin.smoketest; + +import org.springframework.boot.autoconfigure.ImportAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +import tech.ailef.snapadmin.external.SnapAdminAutoConfiguration; + +@SpringBootApplication +@ImportAutoConfiguration(SnapAdminAutoConfiguration.class) +public class SmokeTestApplication { +} diff --git a/src/test/java/tech/ailef/snapadmin/smoketest/SmokeTestApplicationTests.java b/src/test/java/tech/ailef/snapadmin/smoketest/SmokeTestApplicationTests.java new file mode 100644 index 00000000..7c447480 --- /dev/null +++ b/src/test/java/tech/ailef/snapadmin/smoketest/SmokeTestApplicationTests.java @@ -0,0 +1,38 @@ +package tech.ailef.snapadmin.smoketest; + +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.server.LocalServerPort; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +class SmokeTestApplicationTests { + + @LocalServerPort + private int port; + + @Test + void contextLoadsAndAdminPanelIsServed() throws Exception { + HttpClient client = HttpClient.newHttpClient(); + + HttpResponse index = get(client, "/admin"); + assertThat(index.statusCode()).isEqualTo(200); + + HttpResponse model = get(client, "/admin/model/tech.ailef.snapadmin.smoketest.SmokeTestEntity"); + assertThat(model.statusCode()).isEqualTo(200); + } + + private HttpResponse get(HttpClient client, String path) throws Exception { + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create("http://localhost:" + port + path)) + .GET() + .build(); + return client.send(request, HttpResponse.BodyHandlers.ofString()); + } +} diff --git a/src/test/java/tech/ailef/snapadmin/smoketest/SmokeTestEntity.java b/src/test/java/tech/ailef/snapadmin/smoketest/SmokeTestEntity.java new file mode 100644 index 00000000..f58a3a71 --- /dev/null +++ b/src/test/java/tech/ailef/snapadmin/smoketest/SmokeTestEntity.java @@ -0,0 +1,27 @@ +package tech.ailef.snapadmin.smoketest; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; + +@Entity +public class SmokeTestEntity { + + @Id + @GeneratedValue + private Long id; + + private String name; + + public Long getId() { + return id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties new file mode 100644 index 00000000..d16f1c53 --- /dev/null +++ b/src/test/resources/application.properties @@ -0,0 +1,9 @@ +spring.datasource.url=jdbc:h2:mem:smoketest;DB_CLOSE_DELAY=-1 +spring.datasource.driver-class-name=org.h2.Driver +spring.datasource.username=sa +spring.datasource.password= + +snapadmin.enabled=true +snapadmin.baseUrl=admin +snapadmin.modelsPackage=tech.ailef.snapadmin.smoketest +snapadmin.testMode=true