Yona Appletree
Yona Appletree

Reputation: 9142

Can Kotlin emit JSR-305 annotations in class files

I'm using Kotlin with https://github.com/vojtechhabarta/typescript-generator to generate TypeScript definitions for my classes that are used in an API.

To preserve nullability information, typescript-generator can use annotations present on fields and methods. It supports arbitrary annotation class names, listed in the build script.

Kotlin, for some reason, annotates nullable fields with @org.jetbrains.annotations.Nullable rather than the JSR-305 annotation, @javax.annotation.Nullable.

While the JSR-305 annotation has RetentionPolicy.RUNTIME, the Jetbrains annotation has RetentionPolicy.CLASS, making it unsuitable for introspection by libraries which use Java Reflection to detect annotations.

Is it possible to have Kotlin generate standards-based annotations instead of the JetBrains proprietary annotations?

If not, I'm interested in simple solutions to handle the issue. Perhaps a Gradle plugin that can generate JSR-305 annotations from the JetBrains ones or similar. I would really prefer to not have to double-annotate everything with a ? and @Nullable.

Upvotes: 3

Views: 554

Answers (1)

Roman  Elizarov
Roman Elizarov

Reputation: 28668

Kotlin is designed to emit its own (JetBrains) annotations. This choise was made because JSR 305 was never released and there is no legal way for JetBrains to bundle JSR 305 annotations with compiler, since the license on (a dormant) JSR 305 does not allow it. The legal status of the com.google.code.findbugs:jsr305 maven artifact is likewise murky, since javax package namespace is specifically reserved for JSRs.

There are the following possible solutions:

  1. Write a custom Gradle plugin that post-processes Kotlin-compiled class files and changes org.jetbrains.annotations.* annotations to the corresponding javax.annotation.* annotations (NotNull to Nonnull and Nullable to Nullable) and changes the corresponding attiributes from runtime-invisible annotations to runtime-visible ones.

  2. Patch typescript-generator so that it used Kotlin reflection APIs in addition to Java Reflection to get nullablitity information from Kotlin classes. The entry point is for this task is kotlin extension of Java Class instance that allows to retrieve all the Kotlin metadata.

  3. Add jackson-module-kotlin to typescript-generator. This module is using Kotlin's reflection to get all the Kotlin specific information and feed it to Jackson, while typescript-generator is using Jackson bean introspection to get its type information, so it might just work.

Upvotes: 4

Related Questions