Browse Source

Use canonical names for types in synthesized annotation toString

My proposal for the same change in the JDK is currently targeted for
JDK 19.

- https://bugs.openjdk.java.net/browse/JDK-8281462
- https://bugs.openjdk.java.net/browse/JDK-8281568
- https://github.com/openjdk/jdk/pull/7418

See gh-28015
pull/28119/head
Sam Brannen 3 years ago
parent
commit
ce87285be5
  1. 9
      spring-core/src/main/java/org/springframework/core/annotation/SynthesizedMergedAnnotationInvocationHandler.java
  2. 20
      spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsTests.java
  3. 6
      spring-test/src/test/java/org/springframework/test/context/BootstrapUtilsTests.java

9
spring-core/src/main/java/org/springframework/core/annotation/SynthesizedMergedAnnotationInvocationHandler.java

@ -177,7 +177,7 @@ final class SynthesizedMergedAnnotationInvocationHandler<A extends Annotation> i @@ -177,7 +177,7 @@ final class SynthesizedMergedAnnotationInvocationHandler<A extends Annotation> i
private String annotationToString() {
String string = this.string;
if (string == null) {
StringBuilder builder = new StringBuilder("@").append(this.type.getName()).append('(');
StringBuilder builder = new StringBuilder("@").append(getName(this.type)).append('(');
for (int i = 0; i < this.attributes.size(); i++) {
Method attribute = this.attributes.get(i);
if (i > 0) {
@ -202,7 +202,7 @@ final class SynthesizedMergedAnnotationInvocationHandler<A extends Annotation> i @@ -202,7 +202,7 @@ final class SynthesizedMergedAnnotationInvocationHandler<A extends Annotation> i
return ((Enum<?>) value).name();
}
if (value instanceof Class) {
return ((Class<?>) value).getName() + ".class";
return getName((Class<?>) value) + ".class";
}
if (value.getClass().isArray()) {
StringBuilder builder = new StringBuilder("{");
@ -277,6 +277,11 @@ final class SynthesizedMergedAnnotationInvocationHandler<A extends Annotation> i @@ -277,6 +277,11 @@ final class SynthesizedMergedAnnotationInvocationHandler<A extends Annotation> i
return (A) Proxy.newProxyInstance(classLoader, interfaces, handler);
}
private static String getName(Class<?> clazz) {
String canonicalName = clazz.getCanonicalName();
return (canonicalName != null ? canonicalName : clazz.getName());
}
private static boolean isVisible(ClassLoader classLoader, Class<?> interfaceClass) {
if (classLoader == interfaceClass.getClassLoader()) {

20
spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsTests.java

@ -1887,15 +1887,22 @@ class MergedAnnotationsTests { @@ -1887,15 +1887,22 @@ class MergedAnnotationsTests {
// Formatting common to Spring and JDK 9+
assertThat(string)
.startsWith("@" + RequestMapping.class.getName() + "(")
.contains("value={\"/test\"}", "path={\"/test\"}", "name=\"bar\"", "clazz=java.lang.Object.class")
.contains("value={\"/test\"}", "path={\"/test\"}", "name=\"bar\"")
.endsWith(")");
if (webMapping instanceof SynthesizedAnnotation) {
assertThat(string).as("Spring uses Enum#name()").contains("method={GET, POST}");
assertThat(string).as("Spring formatting")
.startsWith("@org.springframework.core.annotation.MergedAnnotationsTests.RequestMapping(")
.contains("method={GET, POST}",
"clazz=org.springframework.core.annotation.MergedAnnotationsTests.RequestMethod.class",
"classes={org.springframework.core.annotation.MergedAnnotationsTests.RequestMethod.class}");
}
else {
assertThat(string).as("JDK uses Enum#toString()").contains("method={method: get, method: post}");
assertThat(string).as("JDK 9-18 formatting")
.startsWith("@org.springframework.core.annotation.MergedAnnotationsTests$RequestMapping(")
.contains("method={method: get, method: post}",
"clazz=org.springframework.core.annotation.MergedAnnotationsTests$RequestMethod.class",
"classes={org.springframework.core.annotation.MergedAnnotationsTests$RequestMethod.class}");
}
}
@ -2989,8 +2996,9 @@ class MergedAnnotationsTests { @@ -2989,8 +2996,9 @@ class MergedAnnotationsTests {
RequestMethod[] method() default {};
// clazz is only used for testing annotation toString() implementations
Class<?> clazz() default Object.class;
Class<?> clazz() default RequestMethod.class;
Class<?>[] classes() default {RequestMethod.class};
}
@Retention(RetentionPolicy.RUNTIME)

6
spring-test/src/test/java/org/springframework/test/context/BootstrapUtilsTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2022 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.
@ -72,8 +72,8 @@ class BootstrapUtilsTests { @@ -72,8 +72,8 @@ class BootstrapUtilsTests {
assertThatIllegalStateException().isThrownBy(() ->
resolveTestContextBootstrapper(bootstrapContext))
.withMessageContaining("Configuration error: found multiple declarations of @BootstrapWith")
.withMessageContaining(FooBootstrapper.class.getName())
.withMessageContaining(BarBootstrapper.class.getName());
.withMessageContaining(FooBootstrapper.class.getCanonicalName())
.withMessageContaining(BarBootstrapper.class.getCanonicalName());
}
@Test

Loading…
Cancel
Save