Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Synthesized annotation toString() doesn't match non-synthesized annotation on Java 9+ #28015

Closed
jeff-miller-cfa opened this issue Feb 7, 2022 · 5 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: enhancement A general enhancement
Milestone

Comments

@jeff-miller-cfa
Copy link

jeff-miller-cfa commented Feb 7, 2022

Synthesized annotations that contain arrays and/or strings do not generate the same toString() value as the non-synthesized version.

The non-synthesized annotation's toString() method returns a string which is a code equivalent version of that annotation meaning that you can take the result of the toString(), copy and paste it into code, and have it compile. This is very convenient when writing a code generation library since it allows you to copy annotations.

This does not work with synthesized annotations though as the way the array gets serialized in toString() doesn't match.

Actual Annotation:

@Bean("testValue")

Non-Synthesized Annotation toString():

@org.springframework.context.annotation.Bean(value = {"testValue"})

Synthesized Annotation toString():

@org.springframework.context.annotation.Bean(value = [testValue])

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Feb 7, 2022
@jhoeller jhoeller added in: core Issues in core modules (aop, beans, core, context, expression) type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Feb 8, 2022
@jhoeller jhoeller added this to the 5.3.16 milestone Feb 8, 2022
@sbrannen
Copy link
Member

sbrannen commented Feb 8, 2022

This is actually by design.

The result of invoking toString() on a synthesized annotation is identical to the result of invoking toString() on the same non-synthesized annotation on Java 8. In fact we used to have tests in place to verify that, but those broke once we started building the framework on Java 9, since Java 9 changed the output format for toString() in annotations.

See:

In any case, it does not appear that the JDK format has changed since Java 9, so I'll go ahead and update to the newer format.

@sbrannen sbrannen changed the title Synthesized annotation toString() doesn't match non-synthesized annotation. Synthesized annotation toString() doesn't match non-synthesized annotation on Java 9+ Feb 8, 2022
@sbrannen sbrannen added type: enhancement A general enhancement and removed type: bug A general bug labels Feb 8, 2022
@sbrannen sbrannen self-assigned this Feb 8, 2022
@jhoeller
Copy link
Contributor

jhoeller commented Feb 8, 2022

Ah ok, I wasn't aware of the change between JDK 8 and 9 there. If 5.3.x is currently aligned with the JDK 8 toString format there, we could also simply upgrade to the JDK 9+ format for 6.0.

@sbrannen
Copy link
Member

sbrannen commented Feb 8, 2022

Interestingly enough, it turns out there are actually 2 bugs (🐛) lurking behind the scenes here.

  1. Spring's toString() for synthesized annotations in fact did not match the JDK 8 behavior for class attributes. Spring used Class#getName; JDK 8 used Class#toString.
  2. JDK 9+ incorrectly invokes Enum#toString for enum attributes; whereas, the commit I am about to push will use Enum#name, since an enum can in fact override toString() (for example, with return name().toLowerCase()).

I'll see if the OpenJDK team is willing to update the toString() implementation for annotations to use Enum#name.

@sbrannen
Copy link
Member

sbrannen commented Feb 8, 2022

I'll see if the OpenJDK team is willing to update the toString() implementation for annotations to use Enum#name.

See: https://bugs.openjdk.java.net/browse/JDK-8281462

@sbrannen
Copy link
Member

Reopening to address additional shortcomings in the toString() implementation for synthesized annotations.

@sbrannen sbrannen reopened this Feb 10, 2022
sbrannen added a commit to sbrannen/spring-framework that referenced this issue Feb 11, 2022
sbrannen added a commit to sbrannen/spring-framework that referenced this issue Feb 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

4 participants