From e6f515afb6aaba1e6ef47b8457a62d940285108c Mon Sep 17 00:00:00 2001 From: johnycho Date: Sat, 10 Jan 2026 17:24:37 +0900 Subject: [PATCH 1/3] Improve serialVersionUID check in tests Signed-off-by: johnycho --- .../security/SpringSecurityCoreVersionSerializableTests.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/config/src/test/java/org/springframework/security/SpringSecurityCoreVersionSerializableTests.java b/config/src/test/java/org/springframework/security/SpringSecurityCoreVersionSerializableTests.java index 98b1d346eee..36fbca95c1e 100644 --- a/config/src/test/java/org/springframework/security/SpringSecurityCoreVersionSerializableTests.java +++ b/config/src/test/java/org/springframework/security/SpringSecurityCoreVersionSerializableTests.java @@ -36,6 +36,7 @@ import java.util.Arrays; import java.util.HashSet; import java.util.List; +import java.util.Objects; import java.util.Set; import java.util.stream.Stream; @@ -208,8 +209,8 @@ void allSerializableClassesShouldHaveSerialVersionOrSuppressWarnings() throws Ex .map(Field::getName) .anyMatch((n) -> n.equals("serialVersionUID")); SuppressWarnings suppressWarnings = clazz.getAnnotation(SuppressWarnings.class); - boolean hasSerialIgnore = suppressWarnings == null - || Arrays.asList(suppressWarnings.value()).contains("Serial"); + boolean hasSerialIgnore = Objects.nonNull(suppressWarnings) + && Arrays.asList(suppressWarnings.value()).contains("serial"); if (!hasSerialVersion && !hasSerialIgnore) { classes.add(clazz); continue; From c13556aedd71cce8399a1941c9f3bdc2ad9ffa78 Mon Sep 17 00:00:00 2001 From: Josh Cummings <3627351+jzheaux@users.noreply.github.com> Date: Mon, 30 Mar 2026 17:14:03 -0600 Subject: [PATCH 2/3] Update Test to find SuppressWarnings Signed-off-by: Josh Cummings <3627351+jzheaux@users.noreply.github.com> --- ...gSecurityCoreVersionSerializableTests.java | 60 +++++++++++++++++-- 1 file changed, 54 insertions(+), 6 deletions(-) diff --git a/config/src/test/java/org/springframework/security/SpringSecurityCoreVersionSerializableTests.java b/config/src/test/java/org/springframework/security/SpringSecurityCoreVersionSerializableTests.java index 36fbca95c1e..8ce925cdc38 100644 --- a/config/src/test/java/org/springframework/security/SpringSecurityCoreVersionSerializableTests.java +++ b/config/src/test/java/org/springframework/security/SpringSecurityCoreVersionSerializableTests.java @@ -33,11 +33,10 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashSet; import java.util.List; -import java.util.Objects; import java.util.Set; +import java.util.regex.Pattern; import java.util.stream.Stream; import org.apache.commons.lang3.ObjectUtils; @@ -208,10 +207,7 @@ void allSerializableClassesShouldHaveSerialVersionOrSuppressWarnings() throws Ex boolean hasSerialVersion = Stream.of(clazz.getDeclaredFields()) .map(Field::getName) .anyMatch((n) -> n.equals("serialVersionUID")); - SuppressWarnings suppressWarnings = clazz.getAnnotation(SuppressWarnings.class); - boolean hasSerialIgnore = Objects.nonNull(suppressWarnings) - && Arrays.asList(suppressWarnings.value()).contains("serial"); - if (!hasSerialVersion && !hasSerialIgnore) { + if (!hasSerialVersion && !hasSuppressSerialInSource(clazz)) { classes.add(clazz); continue; } @@ -250,6 +246,58 @@ static Stream> getClassesToSerialize() throws Exception { return classes.stream(); } + private static boolean hasSuppressSerialInSource(Class clazz) { + try { + Class fileClass = clazz; + while (fileClass.getEnclosingClass() != null) { + fileClass = fileClass.getEnclosingClass(); + } + var codeSource = fileClass.getProtectionDomain().getCodeSource(); + if (codeSource == null) { + return false; + } + Path sourceFile = findSourceFile(Path.of(codeSource.getLocation().toURI()), fileClass); + if (sourceFile == null) { + return false; + } + return hasSuppressSerialAnnotation(Files.readAllLines(sourceFile), clazz.getSimpleName()); + } + catch (Exception ex) { + return false; + } + } + + private static Path findSourceFile(Path start, Class clazz) { + String relativePath = clazz.getName().replace('.', '/') + ".java"; + Path dir = start; + for (int i = 0; i < 10 && dir != null; i++) { + for (String sourceRoot : List.of("src/main/java", "src/test/java")) { + Path candidate = dir.resolve(sourceRoot).resolve(relativePath); + if (Files.exists(candidate)) { + return candidate; + } + } + dir = dir.getParent(); + } + return null; + } + + private static boolean hasSuppressSerialAnnotation(List lines, String simpleClassName) { + Pattern classDeclaration = Pattern + .compile("\\b(?:class|interface|enum|record)\\s+" + Pattern.quote(simpleClassName) + "\\b"); + for (int i = 0; i < lines.size(); i++) { + if (classDeclaration.matcher(lines.get(i)).find()) { + for (int j = Math.max(0, i - 5); j < i; j++) { + String line = lines.get(j); + if (line.contains("@SuppressWarnings") && line.contains("\"serial\"")) { + return true; + } + } + } + } + return false; + } + private static String getCurrentVersion() { String version = System.getProperty("springSecurityVersion"); String[] parts = version.split("\\."); From 5a314d3b2ab2b989d708f4d1a9a89804ab3a695e Mon Sep 17 00:00:00 2001 From: Josh Cummings <3627351+jzheaux@users.noreply.github.com> Date: Mon, 30 Mar 2026 17:29:08 -0600 Subject: [PATCH 3/3] Suppress Serialization Warnings Signed-off-by: Josh Cummings <3627351+jzheaux@users.noreply.github.com> --- .../springframework/security/cas/jackson/CasJacksonModule.java | 1 + .../security/authentication/NonBuildableAuthenticationToken.java | 1 + .../oauth2/core/endpoint/TestOidcAuthorizationRequest.java | 1 + .../web/authentication/DefaultEqualsGrantedAuthority.java | 1 + 4 files changed, 4 insertions(+) diff --git a/cas/src/main/java/org/springframework/security/cas/jackson/CasJacksonModule.java b/cas/src/main/java/org/springframework/security/cas/jackson/CasJacksonModule.java index 0e5e2cc4d16..a7e8bdd1643 100644 --- a/cas/src/main/java/org/springframework/security/cas/jackson/CasJacksonModule.java +++ b/cas/src/main/java/org/springframework/security/cas/jackson/CasJacksonModule.java @@ -48,6 +48,7 @@ * @since 7.0 * @see SecurityJacksonModules */ +@SuppressWarnings("serial") public class CasJacksonModule extends SecurityJacksonModule { public CasJacksonModule() { diff --git a/core/src/test/java/org/springframework/security/authentication/NonBuildableAuthenticationToken.java b/core/src/test/java/org/springframework/security/authentication/NonBuildableAuthenticationToken.java index 8099b826f38..ef4e4161587 100644 --- a/core/src/test/java/org/springframework/security/authentication/NonBuildableAuthenticationToken.java +++ b/core/src/test/java/org/springframework/security/authentication/NonBuildableAuthenticationToken.java @@ -16,6 +16,7 @@ package org.springframework.security.authentication; +@SuppressWarnings("serial") public class NonBuildableAuthenticationToken extends TestingAuthenticationToken { public NonBuildableAuthenticationToken(String user, String password, String... authorities) { diff --git a/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/endpoint/TestOidcAuthorizationRequest.java b/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/endpoint/TestOidcAuthorizationRequest.java index 54b14a22319..37aa3e557fd 100644 --- a/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/endpoint/TestOidcAuthorizationRequest.java +++ b/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/endpoint/TestOidcAuthorizationRequest.java @@ -23,6 +23,7 @@ /** * @author Joe Grandja */ +@SuppressWarnings("serial") public class TestOidcAuthorizationRequest extends OAuth2AuthorizationRequest { private final String nonce; diff --git a/web/src/test/java/org/springframework/security/web/authentication/DefaultEqualsGrantedAuthority.java b/web/src/test/java/org/springframework/security/web/authentication/DefaultEqualsGrantedAuthority.java index 1970ea26916..0220e66767b 100644 --- a/web/src/test/java/org/springframework/security/web/authentication/DefaultEqualsGrantedAuthority.java +++ b/web/src/test/java/org/springframework/security/web/authentication/DefaultEqualsGrantedAuthority.java @@ -25,6 +25,7 @@ * @author Rob Winch * @since 7.0 */ +@SuppressWarnings("serial") public class DefaultEqualsGrantedAuthority implements GrantedAuthority { public static final String AUTHORITY = "CUSTOM_AUTHORITY";