Skip to content

Commit 194f9dc

Browse files
committed
feat(spring-boot): upgrade to version 4
1 parent 057a9dd commit 194f9dc

File tree

47 files changed

+1079
-1454
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1079
-1454
lines changed

AGENTS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ SPDX-License-Identifier: CC-BY-NC-4.0
66

77
- `yarn test` must pass if `*.kts`, `*.java`, or `checkstyle/*.xml` has changed
88
- `yarn ug` updates gradle dependencies
9+
- gradle buildHealth task does not use JPMS, and can be incorrect if JPMS is having with its suggestions.
910
- architecture is hexagonal, CQRS

Makefile

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,19 @@
22
#
33
# SPDX-License-Identifier: MIT
44

5-
HEAD := $(shell git rev-parse --verify HEAD)
5+
HEAD = $(shell git rev-parse --verify HEAD)
6+
ENGINE ?= junie
67
SKILL_FILE := .ai/skills/commit-or-pr-message/SKILL.md
78

9+
# kimi uses --skills-dir for auto-discovery; other engines need --skill-file
10+
ifeq ($(ENGINE),kimi)
11+
SKILL_ARG :=
12+
else
13+
SKILL_ARG := --skill-file "$(SKILL_FILE)"
14+
endif
15+
816
define gh_head_run_id
9-
gh run list --workflow $(1) --commit $(HEAD) --json databaseId --jq '.[0].["databaseId"]'
17+
gh run list --workflow $(1) --commit $(HEAD) --json databaseId --jq '.[0].databaseId // ""'
1018
endef
1119

1220
.PHONY: build
@@ -16,9 +24,9 @@ build:
1624
.PHONY: merge
1725
merge: merge-head push
1826
@if gh pr view --json number > /dev/null 2>&1; then \
19-
$(MAKE) watch-full create-pr; \
27+
$(MAKE) watch-build create-pr; \
2028
else \
21-
$(MAKE) create-pr watch-full; \
29+
$(MAKE) create-pr watch-build; \
2230
fi
2331
@$(MAKE) merge-squash
2432

@@ -27,23 +35,23 @@ create-pr: build
2735
head_before=$$(git rev-parse HEAD); \
2836
if gh pr view --json number > /dev/null 2>&1; then \
2937
printf '%s\n' "Updating PR message..."; \
30-
./scripts/pr-message.sh --title-file "$$tmp_dir/title.txt" --body-file "$$tmp_dir/body.txt" \
31-
--skill-file "$(SKILL_FILE)" || exit 0; \
38+
./.share/bin/pr-message.sh --engine "$(ENGINE)" --title-file "$$tmp_dir/title.txt" --body-file "$$tmp_dir/body.txt" \
39+
$(SKILL_ARG) || exit 0; \
3240
head_after=$$(git rev-parse HEAD); \
3341
if [ "$$head_before" != "$$head_after" ]; then \
34-
./scripts/pr-message.sh --title-file "$$tmp_dir/title.txt" --body-file "$$tmp_dir/body.txt" \
35-
--skill-file "$(SKILL_FILE)" || exit 0; \
42+
./.share/bin/pr-message.sh --engine "$(ENGINE)" --title-file "$$tmp_dir/title.txt" --body-file "$$tmp_dir/body.txt" \
43+
$(SKILL_ARG) || exit 0; \
3644
fi; \
3745
title=$$(cat "$$tmp_dir/title.txt"); \
3846
gh pr edit --title "$$title" --body-file "$$tmp_dir/body.txt" || exit 0; \
3947
GH_PAGER=cat gh pr view; \
4048
else \
41-
./scripts/pr-message.sh --title-file "$$tmp_dir/title.txt" --body-file "$$tmp_dir/body.txt" \
42-
--skill-file "$(SKILL_FILE)" || exit 0; \
49+
./.share/bin/pr-message.sh --engine "$(ENGINE)" --title-file "$$tmp_dir/title.txt" --body-file "$$tmp_dir/body.txt" \
50+
$(SKILL_ARG) || exit 0; \
4351
head_after=$$(git rev-parse HEAD); \
4452
if [ "$$head_before" != "$$head_after" ]; then \
45-
./scripts/pr-message.sh --title-file "$$tmp_dir/title.txt" --body-file "$$tmp_dir/body.txt" \
46-
--skill-file "$(SKILL_FILE)" || exit 0; \
53+
./.share/bin/pr-message.sh --engine "$(ENGINE)" --title-file "$$tmp_dir/title.txt" --body-file "$$tmp_dir/body.txt" \
54+
$(SKILL_ARG) || exit 0; \
4755
fi; \
4856
title=$$(cat "$$tmp_dir/title.txt"); \
4957
gh pr create --title "$$title" --body-file "$$tmp_dir/body.txt" || exit 0; \
@@ -64,12 +72,25 @@ merge-squash:
6472
printf '%s\n' "WARNING: Uncommitted changes detected. Review before merge." 1>&2; \
6573
fi; \
6674
printf '%s' "Proceed with squash merge? [Y/n] "; \
67-
read -r reply; \
75+
read -r reply < /dev/tty; \
6876
case "$$reply" in \
69-
""|y|Y|yes|YES) ;; \
70-
*) printf '%s\n' "Merge cancelled."; exit 1 ;; \
77+
[Nn]|[Nn][Oo]) printf '%s\n' "Merge cancelled."; exit 1 ;; \
78+
*) ;; \
7179
esac; \
7280
gh pr merge --squash --delete-branch --auto
7381

74-
watch-full:
75-
@gh run watch $$($(call gh_head_run_id, "full")) --exit-status
82+
.PHONY: watch-build
83+
watch-build:
84+
@printf "Waiting for workflow 'build' to start on commit $(HEAD)...\n"
85+
@run_id=""; \
86+
for i in $$(seq 1 12); do \
87+
run_id=$$($(call gh_head_run_id, "build")); \
88+
if [ -n "$$run_id" ]; then break; fi; \
89+
printf "Run not found yet, retrying in 5s... ($$i/12)\n"; \
90+
sleep 5; \
91+
done; \
92+
if [ -z "$$run_id" ]; then \
93+
printf "Error: Workflow 'build' did not start within 60 seconds.\n" >&2; \
94+
exit 1; \
95+
fi; \
96+
gh run watch "$$run_id" --exit-status

build.gradle.kts

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import org.semver4j.Semver
22

3-
// SPDX-FileCopyrightText: Copyright © 2024 - 2026 Caleb Cushing
3+
// SPDX-FileCopyrightText: Copyright © 2024-2026 Caleb Cushing
44
//
55
// SPDX-License-Identifier: MIT
66

@@ -36,10 +36,38 @@ dependencyAnalysis {
3636
severity("fail")
3737
}
3838
onUnusedDependencies {
39-
exclude(sb.junit.jupiter.params)
40-
exclude(sb.org.junit.jupiter.junit.jupiter)
41-
exclude(sb.assertj.core)
42-
exclude(libs.jspecify)
39+
exclude(sbd4.junit.jupiter.params)
40+
exclude(sbd4.junit.jupiter)
41+
exclude(sbd4.assertj.core)
42+
exclude(sbd4.jspecify)
43+
}
44+
}
45+
// buildHealth does not understand JPMS module-info requires
46+
project(":test-authorization-server") {
47+
onUnusedDependencies {
48+
exclude(sbd4.spring.security.oauth2.authorization.server)
49+
}
50+
onIncorrectConfiguration {
51+
exclude(sbd4.spring.security.oauth2.core)
52+
}
53+
}
54+
// spring-boot-data-jpa-test has runtime components needed beyond compile-only
55+
project(":commons-jpa") {
56+
onCompileOnly {
57+
exclude(sbd4.spring.boot.data.jpa.test)
58+
}
59+
}
60+
project(":commons-model") {
61+
onCompileOnly {
62+
exclude(sbd4.spring.boot.data.jpa.test)
63+
}
64+
}
65+
project(":security-model") {
66+
onUnusedDependencies {
67+
exclude(sbd4.spring.boot.test.autoconfigure)
68+
}
69+
onCompileOnly {
70+
exclude(sbd4.spring.boot.data.jpa.test)
4371
}
4472
}
4573
}

buildSrc/build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// SPDX-FileCopyrightText: Copyright © 2023 - 2026 Caleb Cushing
1+
// SPDX-FileCopyrightText: Copyright © 2023-2026 Caleb Cushing
22
//
33
// SPDX-License-Identifier: MIT
44

@@ -12,7 +12,7 @@ dependencyLocking { lockAllConfigurations() }
1212

1313
dependencies {
1414
implementation(files(libs.javaClass.superclass.protectionDomain.codeSource.location))
15-
implementation(files(sb.javaClass.superclass.protectionDomain.codeSource.location))
15+
implementation(files(sbd4.javaClass.superclass.protectionDomain.codeSource.location))
1616
implementation(libs.plugin.convention.publish)
1717
implementation(libs.plugin.dependency.analysis)
1818
implementation(libs.plugin.errorprone)

buildSrc/settings.gradle.kts

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2026 Caleb Cushing
1+
// SPDX-FileCopyrightText: Copyright © 2026 Caleb Cushing
22
//
33
// SPDX-License-Identifier: MIT
44

@@ -9,6 +9,12 @@ dependencyResolutionManagement {
99
create("libs") {
1010
from(files("../gradle/libs.versions.toml"))
1111
}
12+
create("sbd4") {
13+
from("com.xenoterracide.gradle.vc:version-catalog-spring-boot:4.0.0")
14+
bundle("spring-test", listOf("spring-test", "spring-boot-test", "spring-boot-test-autoconfigure"))
15+
bundle("test-impl", listOf("junit-jupiter-api", "assertj-core", "junit-jupiter-params"))
16+
bundle("test-runtime", listOf("junit-platform-engine", "junit-platform-launcher"))
17+
}
1218
}
1319
}
1420

@@ -26,14 +32,3 @@ dependencyResolutionManagement {
2632
gradlePluginPortal() // this should only be necessary in buildSrc/settings.gradle.kts
2733
}
2834
}
29-
30-
dependencyResolutionManagement {
31-
versionCatalogs {
32-
create("sb") {
33-
from("com.xenoterracide.gradle.vc:version-catalog-spring-boot:3.5.0")
34-
bundle("spring-test", listOf("spring-test", "spring-boot-test", "spring-boot-test-autoconfigure"))
35-
bundle("test-impl", listOf("junit-jupiter-api", "assertj-core", "junit-jupiter-params"))
36-
bundle("test-runtime", listOf("junit-platform-engine", "junit-platform-launcher"))
37-
}
38-
}
39-
}

buildSrc/src/main/kotlin/our.bom.gradle.kts

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// SPDX-License-Identifier: MIT
44

55
import org.gradle.accessors.dm.LibrariesForLibs
6+
import org.gradle.accessors.dm.LibrariesForSbd4
67

78
plugins {
89
`java-library`
@@ -13,13 +14,19 @@ dependencyLocking {
1314
}
1415

1516
val libs = the<LibrariesForLibs>()
17+
var sbd4 = the<LibrariesForSbd4>()
1618

1719
configurations.configureEach {
1820
exclude(group = "org.slf4j", module = "slf4j-nop")
1921
exclude(group = "junit", module = "junit")
2022
exclude(group = "org.junit.jupiter", module = "junit-jupiter")
2123

2224
resolutionStrategy {
25+
capabilitiesResolution {
26+
withCapability("jakarta.el", "jakarta.el-impl") {
27+
select("org.apache.tomcat.embed:tomcat-embed-el:0")
28+
}
29+
}
2330
componentSelection {
2431
all {
2532
val nonRelease = Regex("^[\\d.]+-(RC|M|ea|beta|alpha).*$")
@@ -29,12 +36,6 @@ configurations.configureEach {
2936
} else if (candidate.version.matches(nonRelease)) {
3037
logger.info("allowing: {}", candidate)
3138
}
32-
33-
if (candidate.module == "jboss-logging") {
34-
if (candidate.version.startsWith("3.6")) {
35-
reject("broken with jpms")
36-
}
37-
}
3839
}
3940
}
4041
}
@@ -58,39 +59,35 @@ configurations.configureEach {
5859
dependencies {
5960
api(platform(libs.jakarta.bom))
6061
api(platform(libs.spring.bom))
61-
api(platform(libs.junit.bom))
6262
api(platform(libs.jmolecules.bom))
6363
api(platform(libs.spring.modulith.bom))
6464

6565
compileOnly(platform(libs.jakarta.bom))
6666
compileOnly(platform(libs.spring.bom))
67-
compileOnly(platform(libs.junit.bom))
6867
compileOnly(platform(libs.jmolecules.bom))
6968
compileOnly(platform(libs.spring.modulith.bom))
7069

7170
implementation(platform(libs.jakarta.bom))
7271
implementation(platform(libs.spring.bom))
73-
implementation(platform(libs.junit.bom))
7472
implementation(platform(libs.jmolecules.bom))
7573
implementation(platform(libs.spring.modulith.bom))
7674

7775
runtimeOnly(platform(libs.jakarta.bom))
7876
runtimeOnly(platform(libs.spring.bom))
79-
runtimeOnly(platform(libs.junit.bom))
8077
runtimeOnly(platform(libs.jmolecules.bom))
8178
runtimeOnly(platform(libs.spring.modulith.bom))
8279

83-
compileOnly(libs.jspecify)
80+
compileOnly(sbd4.jspecify)
8481
compileOnly(libs.jmolecules.architecture.layered)
8582

86-
// runtimeOnly(libs.starter.log4j2)
83+
runtimeOnly(sbd4.spring.boot.starter.log4j2)
8784

88-
// modules {
89-
// module("org.springframework.boot:spring-boot-starter-logging") {
90-
// replacedBy(
91-
// "org.springframework.boot:spring-boot-starter-log4j2",
92-
// "Use Log4j2 instead of Logback",
93-
// )
94-
// }
95-
// }
85+
modules {
86+
module("org.springframework.boot:spring-boot-starter-logging") {
87+
replacedBy(
88+
"org.springframework.boot:spring-boot-starter-log4j2",
89+
"Use Log4j2 instead of Logback",
90+
)
91+
}
92+
}
9693
}

buildSrc/src/main/kotlin/our.javatest.gradle.kts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,47 @@
1-
// SPDX-FileCopyrightText: Copyright © 2023 - 2026 Caleb Cushing
1+
// SPDX-FileCopyrightText: Copyright © 2023-2026 Caleb Cushing
22
//
33
// SPDX-License-Identifier: MIT
44

55
import org.gradle.accessors.dm.LibrariesForLibs
6-
import org.gradle.accessors.dm.LibrariesForSb
7-
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
8-
import org.gradle.api.tasks.testing.logging.TestLogEvent
6+
import org.gradle.accessors.dm.LibrariesForSbd4
97

108
plugins {
119
id("com.xenoterracide.gradle.convention.test")
1210
}
1311

1412
val libs = the<LibrariesForLibs>()
15-
val sb = the<LibrariesForSb>()
13+
val sbd4 = the<LibrariesForSbd4>()
1614

1715
dependencies {
1816
testFixturesImplementation(platform(libs.jakarta.bom))
1917
testFixturesImplementation(platform(libs.spring.bom))
2018
}
2119

20+
tasks.withType<Test>().configureEach {
21+
// https://bz.apache.org/bugzilla/show_bug.cgi?id=69958
22+
jvmArgs("--add-reads", "org.hibernate.validator=org.apache.tomcat.embed.el")
23+
}
24+
2225
testing {
2326
suites {
2427
withType<JvmTestSuite>().configureEach {
2528
dependencies {
2629
compileOnly(libs.jmolecules.architecture.layered)
2730
compileOnly(platform(libs.jakarta.bom))
2831
compileOnly(platform(libs.jmolecules.bom))
29-
compileOnly(platform(libs.junit.bom))
3032
compileOnly(platform(libs.spring.bom))
3133
compileOnly(platform(libs.spring.modulith.bom))
32-
compileOnly(libs.jspecify)
34+
compileOnly(sbd4.jspecify)
3335
implementation(platform(libs.jakarta.bom))
3436
implementation(platform(libs.jmolecules.bom))
35-
implementation(platform(libs.junit.bom))
3637
implementation(platform(libs.spring.bom))
3738
implementation(platform(libs.spring.modulith.bom))
38-
implementation.bundle(sb.bundles.test.impl)
39+
implementation.bundle(sbd4.bundles.test.impl)
3940
runtimeOnly(platform(libs.jakarta.bom))
4041
runtimeOnly(platform(libs.jmolecules.bom))
41-
runtimeOnly(platform(libs.junit.bom))
4242
runtimeOnly(platform(libs.spring.bom))
4343
runtimeOnly(platform(libs.spring.modulith.bom))
44-
runtimeOnly.bundle(sb.bundles.test.runtime)
44+
runtimeOnly.bundle(sbd4.bundles.test.runtime)
4545

4646
implementation.addConstraint(constraint(libs.jboss.logging))
4747
}

buildSrc/src/main/kotlin/our.jpamodel.gradle.kts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
// SPDX-FileCopyrightText: Copyright © 2023 - 2026 Caleb Cushing
1+
// SPDX-FileCopyrightText: Copyright © 2023-2026 Caleb Cushing
22
//
33
// SPDX-License-Identifier: MIT
44

55
import org.gradle.accessors.dm.LibrariesForLibs
6+
import org.gradle.accessors.dm.LibrariesForSbd4
67

78
plugins {
89
id("our.bom")
@@ -11,6 +12,7 @@ plugins {
1112
}
1213

1314
val libs = the<LibrariesForLibs>()
15+
val sbd4 = the<LibrariesForSbd4>()
1416

1517
dependencies {
1618
annotationProcessor(platform(libs.jakarta.bom))
@@ -37,7 +39,7 @@ dependencies {
3739

3840
testFixturesCompileOnly(platform(libs.immutables.bom))
3941
testFixturesCompileOnly(libs.bundles.immutables)
40-
testFixturesCompileOnly(libs.jspecify)
42+
testFixturesCompileOnly(sbd4.jspecify)
4143
}
4244

4345
testing {

0 commit comments

Comments
 (0)