From a092dc055e1d773f63f500e7cb6237ee44567b31 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 6 Aug 2019 18:06:00 +0200 Subject: [PATCH 1/2] Check for instanceof Throwable in AnnotationAttributes#assertNotException Prior to this commit, AnnotationAttributes#assertNotException checked if the attribute value was an instance of Exception. Although this was typically sufficient, the scope was not always broad enough -- for example, if AnnotationReadingVisitorUtils#convertClassValues stored a Throwable in the map (such as a LinkageError). This commit fixes this by checking for an instance of Throwable in AnnotationAttributes#assertNotException. Closes gh-23424 --- .../core/annotation/AnnotationAttributes.java | 4 ++-- .../core/annotation/AnnotationAttributesTests.java | 10 +++++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationAttributes.java b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationAttributes.java index f1bcf9fd3f..39ca02b7bc 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationAttributes.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationAttributes.java @@ -353,10 +353,10 @@ public class AnnotationAttributes extends LinkedHashMap { } private void assertNotException(String attributeName, Object attributeValue) { - if (attributeValue instanceof Exception) { + if (attributeValue instanceof Throwable) { throw new IllegalArgumentException(String.format( "Attribute '%s' for annotation [%s] was not resolvable due to exception [%s]", - attributeName, this.displayName, attributeValue), (Exception) attributeValue); + attributeName, this.displayName, attributeValue), (Throwable) attributeValue); } } diff --git a/spring-core/src/test/java/org/springframework/core/annotation/AnnotationAttributesTests.java b/spring-core/src/test/java/org/springframework/core/annotation/AnnotationAttributesTests.java index cfa212c81e..8b112e924b 100644 --- a/spring-core/src/test/java/org/springframework/core/annotation/AnnotationAttributesTests.java +++ b/spring-core/src/test/java/org/springframework/core/annotation/AnnotationAttributesTests.java @@ -77,13 +77,21 @@ public class AnnotationAttributesTests { } @Test - public void unresolvableClass() throws Exception { + public void unresolvableClassWithClassNotFoundException() throws Exception { attributes.put("unresolvableClass", new ClassNotFoundException("myclass")); exception.expect(IllegalArgumentException.class); exception.expectMessage(containsString("myclass")); attributes.getClass("unresolvableClass"); } + @Test + public void unresolvableClassWithLinkageError() throws Exception { + attributes.put("unresolvableClass", new LinkageError("myclass")); + exception.expect(IllegalArgumentException.class); + exception.expectMessage(containsString("myclass")); + attributes.getClass("unresolvableClass"); + } + @Test public void singleElementToSingleElementArrayConversionSupport() throws Exception { Filter filter = FilteredClass.class.getAnnotation(Filter.class); From 30ebc3b8e2185c56791531507e0f430972f82b51 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 6 Aug 2019 18:10:13 +0200 Subject: [PATCH 2/2] Remove superfluous AnnotationAttributes#putIfAbsent implementation Since Java 8, putIfAbsent() is a standard method in java.util.Map. We therefore no longer need the custom implementation that overrides the standard implementation in HashMap. --- .../core/annotation/AnnotationAttributes.java | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationAttributes.java b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationAttributes.java index 39ca02b7bc..d6941f9ac3 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationAttributes.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationAttributes.java @@ -369,26 +369,6 @@ public class AnnotationAttributes extends LinkedHashMap { } } - /** - * Store the supplied {@code value} in this map under the specified - * {@code key}, unless a value is already stored under the key. - * @param key the key under which to store the value - * @param value the value to store - * @return the current value stored in this map, or {@code null} if no - * value was previously stored in this map - * @see #get - * @see #put - * @since 4.2 - */ - @Override - public Object putIfAbsent(String key, Object value) { - Object obj = get(key); - if (obj == null) { - obj = put(key, value); - } - return obj; - } - @Override public String toString() { Iterator> entries = entrySet().iterator();