浏览代码

Add Test to Report Missing serialVersionUID

Issue gh-16276
Josh Cummings 8 月之前
父节点
当前提交
7592483654

+ 11 - 0
config/spring-security-config.gradle

@@ -172,6 +172,17 @@ configure(project.tasks.withType(Test)) {
 	}
 }
 
+test {
+	onOutput { descriptor, event ->
+		if (!project.hasProperty('serialization')) {
+			return
+		}
+		if (descriptor.name=='listClassesMissingSerialVersion()') {
+			logger.lifecycle(event.message)
+		}
+	}
+}
+
 tasks.register("opensaml5Test", Test) {
 	filter {
 		includeTestsMatching "org.springframework.security.config.annotation.web.configurers.saml2.*"

+ 36 - 0
config/src/test/java/org/springframework/security/SpringSecurityCoreVersionSerializableTests.java

@@ -25,6 +25,7 @@ import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.io.ObjectStreamClass;
 import java.io.Serializable;
+import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
 import java.nio.file.Files;
 import java.nio.file.Path;
@@ -36,6 +37,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
 import org.apereo.cas.client.validation.AssertionImpl;
@@ -44,6 +46,7 @@ import org.instancio.InstancioApi;
 import org.instancio.Select;
 import org.instancio.generator.Generator;
 import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.MethodSource;
 
@@ -289,6 +292,39 @@ class SpringSecurityCoreVersionSerializableTests {
 		return Files.list(previousVersionFolder);
 	}
 
+	@Test
+	void listClassesMissingSerialVersion() throws Exception {
+		ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
+		provider.addIncludeFilter(new AssignableTypeFilter(Serializable.class));
+		List<Class<?>> classes = new ArrayList<>();
+
+		Set<BeanDefinition> components = provider.findCandidateComponents("org/springframework/security");
+		for (BeanDefinition component : components) {
+			Class<?> clazz = Class.forName(component.getBeanClassName());
+			boolean isAbstract = Modifier.isAbstract(clazz.getModifiers());
+			if (isAbstract) {
+				continue;
+			}
+			if (clazz.isEnum()) {
+				continue;
+			}
+			if (clazz.getName().contains("Tests")) {
+				continue;
+			}
+			boolean hasSerialVersion = Stream.of(clazz.getDeclaredFields())
+				.map(Field::getName)
+				.anyMatch((n) -> n.equals("serialVersionUID"));
+			if (!hasSerialVersion) {
+				classes.add(clazz);
+			}
+		}
+		if (!classes.isEmpty()) {
+			System.out
+				.println("Found " + classes.size() + " Serializable classes that don't declare a seriallVersionUID");
+			System.out.println(classes.stream().map(Class::getName).collect(Collectors.joining("\r\n")));
+		}
+	}
+
 	static Stream<Class<?>> getClassesToSerialize() throws Exception {
 		ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
 		provider.addIncludeFilter(new AssignableTypeFilter(Serializable.class));