diff --git a/spring-core/src/main/java/org/springframework/core/annotation/AttributeMethods.java b/spring-core/src/main/java/org/springframework/core/annotation/AttributeMethods.java index c24f51b6ab..fb8c2bda38 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/AttributeMethods.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/AttributeMethods.java @@ -136,7 +136,7 @@ final class AttributeMethods { } catch (Throwable ex) { throw new IllegalStateException("Could not obtain annotation attribute value for " + - get(i).getName() + " declared on " + annotation.annotationType(), ex); + get(i).getName() + " declared on @" + getName(annotation.annotationType()), ex); } } } @@ -300,4 +300,9 @@ final class AttributeMethods { return "attribute '" + attributeName + "'" + in; } + private static String getName(Class clazz) { + String canonicalName = clazz.getCanonicalName(); + return (canonicalName != null ? canonicalName : clazz.getName()); + } + } diff --git a/spring-core/src/main/java/org/springframework/core/annotation/SynthesizedMergedAnnotationInvocationHandler.java b/spring-core/src/main/java/org/springframework/core/annotation/SynthesizedMergedAnnotationInvocationHandler.java index 32a75d7286..2319be3b6d 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/SynthesizedMergedAnnotationInvocationHandler.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/SynthesizedMergedAnnotationInvocationHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -211,7 +211,7 @@ final class SynthesizedMergedAnnotationInvocationHandler i Class type = ClassUtils.resolvePrimitiveIfNecessary(method.getReturnType()); return this.annotation.getValue(attributeName, type).orElseThrow( () -> new NoSuchElementException("No value found for attribute named '" + attributeName + - "' in merged annotation " + this.annotation.getType().getName())); + "' in merged annotation " + getName(this.annotation.getType()))); }); // Clone non-empty arrays so that users cannot alter the contents of values in our cache. diff --git a/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java b/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java index c23f989644..fbe14caec7 100644 --- a/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java +++ b/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java @@ -546,12 +546,16 @@ public class TypeDescriptor implements Serializable { public String toString() { StringBuilder builder = new StringBuilder(); for (Annotation ann : getAnnotations()) { - builder.append('@').append(ann.annotationType().getName()).append(' '); + builder.append('@').append(getName(ann.annotationType())).append(' '); } builder.append(getResolvableType()); return builder.toString(); } + private static String getName(Class clazz) { + String canonicalName = clazz.getCanonicalName(); + return (canonicalName != null ? canonicalName : clazz.getName()); + } /** * Create a new type descriptor for an object. diff --git a/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsTests.java b/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsTests.java index 161ee2de20..90372bf25b 100644 --- a/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsTests.java +++ b/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsTests.java @@ -1960,7 +1960,7 @@ class MergedAnnotationsTests { assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(() -> MergedAnnotation.of(AnnotationWithoutDefaults.class, attributes).synthesize().text()) .withMessage("No value found for attribute named 'text' in merged annotation " + - AnnotationWithoutDefaults.class.getName()); + AnnotationWithoutDefaults.class.getCanonicalName()); } @Test diff --git a/spring-expression/src/test/java/org/springframework/expression/spel/IndexingTests.java b/spring-expression/src/test/java/org/springframework/expression/spel/IndexingTests.java index 5feed1c904..5ee8a2d2b0 100644 --- a/spring-expression/src/test/java/org/springframework/expression/spel/IndexingTests.java +++ b/spring-expression/src/test/java/org/springframework/expression/spel/IndexingTests.java @@ -71,7 +71,7 @@ class IndexingTests { SpelExpressionParser parser = new SpelExpressionParser(); Expression expression = parser.parseExpression("property"); assertThat(expression.getValueTypeDescriptor(this)).asString() - .isEqualTo("@%s java.util.HashMap", FieldAnnotation.class.getName()); + .isEqualTo("@%s java.util.HashMap", FieldAnnotation.class.getCanonicalName()); assertThat(expression.getValue(this)).isEqualTo(property); assertThat(expression.getValue(this, Map.class)).isEqualTo(property); expression = parser.parseExpression("property['foo']"); @@ -106,7 +106,7 @@ class IndexingTests { SpelExpressionParser parser = new SpelExpressionParser(); Expression expression = parser.parseExpression("property"); assertThat(expression.getValueTypeDescriptor(this)).asString() - .isEqualTo("@%s java.util.HashMap", FieldAnnotation.class.getName()); + .isEqualTo("@%s java.util.HashMap", FieldAnnotation.class.getCanonicalName()); assertThat(expression.getValue(this)).isEqualTo(property); expression = parser.parseExpression("property['foo']"); assertThat(expression.getValue(this)).isEqualTo("bar"); @@ -151,7 +151,7 @@ class IndexingTests { SpelExpressionParser parser = new SpelExpressionParser(); Expression expression = parser.parseExpression("property"); assertThat(expression.getValueTypeDescriptor(this)).asString() - .isEqualTo("@%s java.util.ArrayList", FieldAnnotation.class.getName()); + .isEqualTo("@%s java.util.ArrayList", FieldAnnotation.class.getCanonicalName()); assertThat(expression.getValue(this)).isEqualTo(property); expression = parser.parseExpression("property[0]"); assertThat(expression.getValue(this)).isEqualTo("bar"); @@ -165,7 +165,7 @@ class IndexingTests { SpelExpressionParser parser = new SpelExpressionParser(); Expression expression = parser.parseExpression("property"); assertThat(expression.getValueTypeDescriptor(this)).asString() - .isEqualTo("@%s java.util.ArrayList", FieldAnnotation.class.getName()); + .isEqualTo("@%s java.util.ArrayList", FieldAnnotation.class.getCanonicalName()); assertThat(expression.getValue(this)).isEqualTo(property); expression = parser.parseExpression("property[0]"); assertThat(expression.getValue(this)).isEqualTo(3); @@ -180,7 +180,7 @@ class IndexingTests { SpelExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true)); Expression expression = parser.parseExpression("property"); assertThat(expression.getValueTypeDescriptor(this)).asString() - .isEqualTo("@%s java.util.ArrayList", FieldAnnotation.class.getName()); + .isEqualTo("@%s java.util.ArrayList", FieldAnnotation.class.getCanonicalName()); assertThat(expression.getValue(this)).isEqualTo(property); Expression indexExpression = parser.parseExpression("property[0]"); @@ -257,7 +257,7 @@ class IndexingTests { SpelExpressionParser parser = new SpelExpressionParser(configuration); Expression expression = parser.parseExpression("property"); assertThat(expression.getValueTypeDescriptor(this)).asString() - .isEqualTo("@%s java.lang.Object", FieldAnnotation.class.getName()); + .isEqualTo("@%s java.lang.Object", FieldAnnotation.class.getCanonicalName()); assertThat(expression.getValue(this)).isNull(); Expression indexExpression = parser.parseExpression("property[0]"); @@ -274,7 +274,7 @@ class IndexingTests { SpelExpressionParser parser = new SpelExpressionParser(configuration); Expression expression = parser.parseExpression("property"); assertThat(expression.getValueTypeDescriptor(this)).asString() - .isEqualTo("@%s java.util.ArrayList", FieldAnnotation.class.getName()); + .isEqualTo("@%s java.util.ArrayList", FieldAnnotation.class.getCanonicalName()); assertThat(expression.getValue(this)).isEqualTo(property); Expression indexExpression = parser.parseExpression("property[0]"); @@ -306,7 +306,7 @@ class IndexingTests { SpelExpressionParser parser = new SpelExpressionParser(); Expression expression = parser.parseExpression("property"); assertThat(expression.getValueTypeDescriptor(this)).asString() - .isEqualTo("@%s java.lang.String[]", FieldAnnotation.class.getName()); + .isEqualTo("@%s java.lang.String[]", FieldAnnotation.class.getCanonicalName()); assertThat(expression.getValue(this)).isEqualTo(property); expression = parser.parseExpression("property[0]"); assertThat(expression.getValue(this)).isEqualTo("bar"); @@ -330,7 +330,7 @@ class IndexingTests { SpelExpressionParser parser = new SpelExpressionParser(); Expression expression = parser.parseExpression("listNotGeneric"); assertThat(expression.getValueTypeDescriptor(this)).asString() - .isEqualTo("@%s java.util.ArrayList", FieldAnnotation.class.getName()); + .isEqualTo("@%s java.util.ArrayList", FieldAnnotation.class.getCanonicalName()); assertThat(expression.getValue(this, String.class)).isEqualTo("5,6"); } @@ -339,7 +339,7 @@ class IndexingTests { SpelExpressionParser parser = new SpelExpressionParser(); Expression expression = parser.parseExpression("listNotGeneric"); assertThat(expression.getValueTypeDescriptor(this)).asString() - .isEqualTo("@%s java.util.List", FieldAnnotation.class.getName()); + .isEqualTo("@%s java.util.List", FieldAnnotation.class.getCanonicalName()); } @SuppressWarnings("unchecked") @@ -351,7 +351,7 @@ class IndexingTests { SpelExpressionParser parser = new SpelExpressionParser(); Expression expression = parser.parseExpression("mapNotGeneric"); assertThat(expression.getValueTypeDescriptor(this)).asString() - .isEqualTo("@%s java.util.HashMap", FieldAnnotation.class.getName()); + .isEqualTo("@%s java.util.HashMap", FieldAnnotation.class.getCanonicalName()); } @Test