From 13b09e6f3c7fa6f6807285500927a44302ffaa65 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Thu, 8 May 2025 14:20:01 -0700 Subject: [PATCH] Ensure only immediate member classes are only included Update `ClassFileClassMetadata` so that member classes only include immediate children. This aligns with the other `ClassMetadata` implementations. Closes gh-34869 --- .../classreading/ClassFileClassMetadata.java | 18 +++++++-------- .../type/AbstractAnnotationMetadataTests.java | 23 +++++++++++++++++++ 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/spring-core/src/main/java24/org/springframework/core/type/classreading/ClassFileClassMetadata.java b/spring-core/src/main/java24/org/springframework/core/type/classreading/ClassFileClassMetadata.java index 39908947c6c..369511513bb 100644 --- a/spring-core/src/main/java24/org/springframework/core/type/classreading/ClassFileClassMetadata.java +++ b/spring-core/src/main/java24/org/springframework/core/type/classreading/ClassFileClassMetadata.java @@ -268,18 +268,16 @@ class ClassFileClassMetadata implements AnnotationMetadata { void nestMembers(String currentClassName, InnerClassesAttribute innerClasses) { for (InnerClassInfo classInfo : innerClasses.classes()) { String innerClassName = classInfo.innerClass().name().stringValue(); - // skip parent inner classes - if (!innerClassName.startsWith(currentClassName)) { - continue; - } - // the current class is an inner class - else if (currentClassName.equals(innerClassName)) { + if (currentClassName.equals(innerClassName)) { + // the current class is an inner class this.innerAccessFlags = classInfo.flags(); } - // collecting data about actual inner classes - else { - this.memberClassNames.add(ClassUtils.convertResourcePathToClassName(innerClassName)); - } + classInfo.outerClass().ifPresent(outerClass -> { + if (outerClass.name().stringValue().equals(currentClassName)) { + // collecting data about actual inner classes + this.memberClassNames.add(ClassUtils.convertResourcePathToClassName(innerClassName)); + } + }); } } diff --git a/spring-core/src/test/java/org/springframework/core/type/AbstractAnnotationMetadataTests.java b/spring-core/src/test/java/org/springframework/core/type/AbstractAnnotationMetadataTests.java index eb6edc94aa7..31fb6e7e317 100644 --- a/spring-core/src/test/java/org/springframework/core/type/AbstractAnnotationMetadataTests.java +++ b/spring-core/src/test/java/org/springframework/core/type/AbstractAnnotationMetadataTests.java @@ -184,6 +184,13 @@ public abstract class AbstractAnnotationMetadataTests { TestMemberClass.TestMemberClassInnerClass.class.getName(), TestMemberClass.TestMemberClassInnerInterface.class.getName()); } + @Test + void getMemberClassNamesWhenHasNestedMemberClassesReturnsOnlyFirstLevel() { + assertThat(get(TestNestedMemberClass.class).getMemberClassNames()).containsOnly( + TestNestedMemberClass.TestMemberClassInnerClassA.class.getName(), + TestNestedMemberClass.TestMemberClassInnerClassB.class.getName()); + } + @Test void getMemberClassNamesWhenHasNoMemberClassesReturnsEmptyArray() { assertThat(get(TestClass.class).getMemberClassNames()).isEmpty(); @@ -220,6 +227,22 @@ public abstract class AbstractAnnotationMetadataTests { } + public static class TestNestedMemberClass { + + public static class TestMemberClassInnerClassA { + + public static class TestMemberClassInnerClassAA { + + } + + } + + public static class TestMemberClassInnerClassB { + + } + + } + } @Nested