diff --git a/spring-core/src/main/java/org/springframework/core/annotation/AnnotatedElementUtils.java b/spring-core/src/main/java/org/springframework/core/annotation/AnnotatedElementUtils.java index 216cf1630bc..4d5312a6389 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/AnnotatedElementUtils.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/AnnotatedElementUtils.java @@ -864,12 +864,12 @@ public abstract class AnnotatedElementUtils { @Override public Annotation[] getAnnotations() { - return this.annotations; + return this.annotations.clone(); } @Override public Annotation[] getDeclaredAnnotations() { - return this.annotations; + return this.annotations.clone(); } }; diff --git a/spring-core/src/test/java/org/springframework/core/annotation/AnnotatedElementUtilsTests.java b/spring-core/src/test/java/org/springframework/core/annotation/AnnotatedElementUtilsTests.java index 8774e6ae2db..4aaf682b36d 100644 --- a/spring-core/src/test/java/org/springframework/core/annotation/AnnotatedElementUtilsTests.java +++ b/spring-core/src/test/java/org/springframework/core/annotation/AnnotatedElementUtilsTests.java @@ -23,9 +23,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.lang.reflect.AnnotatedElement; -import java.lang.reflect.Constructor; import java.lang.reflect.Method; -import java.util.Date; import java.util.List; import java.util.Set; import javax.annotation.Resource; @@ -43,6 +41,7 @@ import org.springframework.util.MultiValueMap; import static java.util.Arrays.*; import static java.util.stream.Collectors.*; +import static org.assertj.core.api.Assertions.assertThat; import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; import static org.springframework.core.annotation.AnnotatedElementUtils.*; @@ -736,6 +735,15 @@ public class AnnotatedElementUtilsTests { assertNotNull(order); } + @Test // gh-22655 + public void forAnnotationsCreatesCopyOfArrayOnEachCall() { + AnnotatedElement element = AnnotatedElementUtils.forAnnotations(ForAnnotationsClass.class.getDeclaredAnnotations()); + // Trigger the NPE as originally reported in the bug + AnnotationsScanner.getDeclaredAnnotations(element, false); + AnnotationsScanner.getDeclaredAnnotations(element, false); + // Also specifically test we get different instances + assertThat(element.getDeclaredAnnotations()).isNotSameAs(element.getDeclaredAnnotations()); + } // ------------------------------------------------------------------------- @@ -1301,4 +1309,10 @@ public class AnnotatedElementUtilsTests { } } + @Deprecated + @ComponentScan + class ForAnnotationsClass { + + } + }