diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index c2a0c0c..2d421de 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -12,7 +12,7 @@ jobs:
name: Build jar and test
uses: OHSU-OCTRI/shared-workflows/.github/workflows/java-build.yaml@main
with:
- java_version: '17'
+ java_version: '21'
publish_to_github_packages: ${{ github.ref == 'refs/heads/main' || github.ref == 'refs/heads/spring-boot-4' || github.ref_type == 'tag' }}
publish_to_maven_central: ${{ github.ref == 'refs/heads/main' || github.ref == 'refs/heads/spring-boot-4' || github.ref_type == 'tag' }}
secrets: inherit
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
index 936607c..671de83 100644
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -19,5 +19,5 @@ jobs:
with:
version: ${{ inputs.version }}
development_version: ${{ inputs.development_version }}
- java_version: '17'
+ java_version: '21'
secrets: inherit
\ No newline at end of file
diff --git a/.github/workflows/test-build.yaml b/.github/workflows/test-build.yaml
index af40e8f..7c55927 100644
--- a/.github/workflows/test-build.yaml
+++ b/.github/workflows/test-build.yaml
@@ -17,5 +17,5 @@ jobs:
name: Build jar and test
uses: OHSU-OCTRI/shared-workflows/.github/workflows/java-test-build.yaml@main
with:
- java_version: '17'
+ java_version: '21'
# Does not inherit secrets due to security changes in automated workflows
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1b04049..acdbdb8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add Spring Boot 4 branch to branches that publish artifacts (CIS-3896)
+### Dependencies
+
+- Upgrade to Spring Boot 4 and Java 21 (CIS-3896)
+
## [2.1.3] - 2026-08-21
### Changed
diff --git a/pom.xml b/pom.xml
index f824765..8037765 100644
--- a/pom.xml
+++ b/pom.xml
@@ -11,7 +11,7 @@
org.springframework.boot
spring-boot-starter-parent
- 3.5.16
+ 4.0.8
@@ -38,7 +38,7 @@
UTF-8
UTF-8
- 17
+ 21
5.11.1
5.5.1
@@ -69,7 +69,7 @@
org.springframework.boot
- spring-boot-starter-web
+ spring-boot-starter-webmvc
org.springframework.boot
@@ -84,6 +84,16 @@
com.opencsv
opencsv
${opencsv.version}
+
+
+ junit
+ junit
+
+
+ org.junit.vintage
+ junit-vintage-engine
+
+
org.apache.poi
@@ -97,7 +107,7 @@
org.webjars
- webjars-locator-core
+ webjars-locator-lite
org.webjars
diff --git a/src/main/java/org/octri/common/config/ViewConfig.java b/src/main/java/org/octri/common/config/ViewConfig.java
index 0ac7f2d..3ef999b 100644
--- a/src/main/java/org/octri/common/config/ViewConfig.java
+++ b/src/main/java/org/octri/common/config/ViewConfig.java
@@ -75,10 +75,10 @@ private Mustache.Formatter mustacheFormatter() {
return new Mustache.Formatter() {
public String format(Object value) {
- if (value instanceof LocalDate) {
- return dateFormatter.print((LocalDate) value);
- } else if (value instanceof LocalDateTime) {
- return dateTimeFormatter.print((LocalDateTime) value);
+ if (value instanceof LocalDate date) {
+ return dateFormatter.print(date);
+ } else if (value instanceof LocalDateTime time) {
+ return dateTimeFormatter.print(time);
} else {
return String.valueOf(value);
}
diff --git a/src/main/java/org/octri/common/domain/AbstractEntity.java b/src/main/java/org/octri/common/domain/AbstractEntity.java
index b9ea1d2..7fcb232 100644
--- a/src/main/java/org/octri/common/domain/AbstractEntity.java
+++ b/src/main/java/org/octri/common/domain/AbstractEntity.java
@@ -1,5 +1,6 @@
package org.octri.common.domain;
+import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDate;
import java.time.ZoneId;
@@ -28,6 +29,7 @@
@EntityListeners(AuditingEntityListener.class)
public abstract class AbstractEntity implements Serializable {
+ @Serial
private static final long serialVersionUID = 1L;
/**
diff --git a/src/main/java/org/octri/common/view/ViteManifest.java b/src/main/java/org/octri/common/view/ViteManifest.java
index c997317..473c5f5 100644
--- a/src/main/java/org/octri/common/view/ViteManifest.java
+++ b/src/main/java/org/octri/common/view/ViteManifest.java
@@ -7,18 +7,18 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
-
+import tools.jackson.databind.json.JsonMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
-import com.fasterxml.jackson.core.type.TypeReference;
-import com.fasterxml.jackson.databind.ObjectMapper;
+import tools.jackson.core.type.TypeReference;
+import tools.jackson.databind.ObjectMapper;
public class ViteManifest {
private static final Logger log = LoggerFactory.getLogger(ViteManifest.class);
- private static final ObjectMapper objectMapper = new ObjectMapper();
+ private static final ObjectMapper objectMapper = new JsonMapper();
private final Map chunkMap;
diff --git a/src/test/java/org/octri/common/validation/CurrentOrFutureDateValidatorTest.java b/src/test/java/org/octri/common/validation/CurrentOrFutureDateValidatorTest.java
index b805bc1..7740f22 100644
--- a/src/test/java/org/octri/common/validation/CurrentOrFutureDateValidatorTest.java
+++ b/src/test/java/org/octri/common/validation/CurrentOrFutureDateValidatorTest.java
@@ -1,11 +1,11 @@
package org.octri.common.validation;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import java.time.LocalDate;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
public class CurrentOrFutureDateValidatorTest {
@@ -13,22 +13,22 @@ public class CurrentOrFutureDateValidatorTest {
@Test
public void testCurrentDateIsValid() {
- assertTrue("Current LocalDate should be valid", validator.isValid(LocalDate.now(), null));
+ assertTrue(validator.isValid(LocalDate.now(), null), "Current LocalDate should be valid");
}
@Test
public void testFutureDateIsValid() {
- assertTrue("Future LocalDate should be valid", validator.isValid(LocalDate.now().plusDays(1), null));
+ assertTrue(validator.isValid(LocalDate.now().plusDays(1), null), "Future LocalDate should be valid");
}
@Test
public void testNullIsValid() {
- assertTrue("Null LocalDate should be valid", validator.isValid(null, null));
+ assertTrue(validator.isValid(null, null), "Null LocalDate should be valid");
}
@Test
public void testPastDateIsNotValid() {
- assertFalse("Past date should not be valid", validator.isValid(LocalDate.now().minusDays(1), null));
+ assertFalse(validator.isValid(LocalDate.now().minusDays(1), null), "Past date should not be valid");
}
}
diff --git a/src/test/java/org/octri/common/validation/CurrentOrPastDateValidatorTest.java b/src/test/java/org/octri/common/validation/CurrentOrPastDateValidatorTest.java
index 34995fc..ce2f388 100644
--- a/src/test/java/org/octri/common/validation/CurrentOrPastDateValidatorTest.java
+++ b/src/test/java/org/octri/common/validation/CurrentOrPastDateValidatorTest.java
@@ -1,11 +1,11 @@
package org.octri.common.validation;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import java.time.LocalDate;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
public class CurrentOrPastDateValidatorTest {
@@ -13,22 +13,22 @@ public class CurrentOrPastDateValidatorTest {
@Test
public void testCurrentDateIsValid() {
- assertTrue("Current LocalDate should be valid", validator.isValid(LocalDate.now(), null));
+ assertTrue(validator.isValid(LocalDate.now(), null), "Current LocalDate should be valid");
}
@Test
public void testPastDateIsValid() {
- assertTrue("Future LocalDate should be valid", validator.isValid(LocalDate.now().minusDays(1), null));
+ assertTrue(validator.isValid(LocalDate.now().minusDays(1), null), "Future LocalDate should be valid");
}
@Test
public void testNullIsValid() {
- assertTrue("Null LocalDate should be valid", validator.isValid(null, null));
+ assertTrue(validator.isValid(null, null), "Null LocalDate should be valid");
}
@Test
public void testFutureDateIsNotValid() {
- assertFalse("Past date should not be valid", validator.isValid(LocalDate.now().plusDays(1), null));
+ assertFalse(validator.isValid(LocalDate.now().plusDays(1), null), "Past date should not be valid");
}
}