Skip to content

Commit

Permalink
Use canonical names for types in synthesized annotation toString
Browse files Browse the repository at this point in the history
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
- openjdk/jdk#7418

See spring-projectsgh-28015
  • Loading branch information
sbrannen committed Feb 10, 2022
1 parent 97582fd commit ce87285
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ private int getValueHashCode(Object value) {
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) {
Expand All @@ -202,7 +202,7 @@ private String toString(Object value) {
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("{");
Expand Down Expand Up @@ -277,6 +277,11 @@ static <A extends Annotation> A createProxy(MergedAnnotation<A> annotation, Clas
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()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1887,15 +1887,22 @@ private void assertToStringForWebMappingWithPathAndValue(RequestMapping webMappi

// 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}");
}
}

Expand Down Expand Up @@ -2989,8 +2996,9 @@ public String toString() {

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)
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -72,8 +72,8 @@ void resolveTestContextBootstrapperWithDoubleMetaBootstrapWithAnnotations() {
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
Expand Down

0 comments on commit ce87285

Please sign in to comment.