therapi-runtime-javadoc: RuntimeJavadoc.getJavadoc(Method) fails if parameter has annotation

I’m on 0.9.0 and since I’m heavily relying on all the api and quirks from that version I’m not ready to upgrade until I’m on Java 8.

However, the following simply stops returning data, Everything works fine when compiled with Java 1.7, but is completely empty when compiled with Java 1.8 (and not just params, but everything):

image

You can easily reproduce this problem as follows:

  1. check out https://github.com/bbottema/simple-java-mail.git (default branch develop)
  2. add the following property to the root pom: <java.version>1.8</java.version>
  3. run mvn clean test (I’m running with Maven 3.5.0 and jdk1.8.0_241)

It fails on the cli-module’s unit tests. I get the same error in IntelliJ. Any idea what might cause this?

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 25 (25 by maintainers)

Commits related to this issue

Most upvoted comments

It’s 01:00 AM where I live so I’ll probably catch the release proper 😃

Btw, happy new year!

Symptoms

Depending on the JDK vendor and version, you might see:

  • RuntimeJavadoc.getJavadoc(Method) returns an empty MethodJavadoc if the method has an annotated parameter, and the annotation has a target of TYPE_USE.

  • When iterating over the methods in a ClassJavadoc, the annotation names can leak into the strings returned by MethodJavadoc.getParamTypes().

Root Cause Analysis

In JsonJavadocBuilder.getParamErasures the annotation processor gets parameter type names using TypeMirror.toString() whose return value is documented as “informative” (meaning the structure is essentially unspecified). The string returned by that method can vary between JDKs, and might or might not include the names of annotations. Additionally, if the result includes an annotation, the delimiter between the annotation name and the parameter class might be " :: " as @bbottema observed, or it might simply be a space.

As a point of reference, AdoptOpenJdk 1.8.0_262 includes the parameter annotations, but only for annotations whose target includes ElementType.TYPE_USE. It does not use a " :: " delimiter. Here’s a sample TypeMirror.toString() value from this JDK:

"@com.example.SomeAnnotation java.lang.String"

Possible Remediation

Borrow JavaPoet’s strategy as referenced in the comments of this StackOverflow post