Infer @Nullable/@NotNull and other annotations from byte code
If you have a Java library binaries (e.g. jar-files), KAnnotator can analyze them and tell you some information about contracts of the methods in this library. For example:
- Does this method admit
null
as a value for this parameter? - Does this method ever return
null
? - Does this method mutate this collection passed to it?
The contracts are represented as annotations on Java method, hence the name of the project. Since libraries under analysis are not under user's control, the annotations can not be added to their code directly, so KAnnotator stores them in one of the two formats:
- XML-based External annotation definitions supported by IntelliJ IDEA
.jaif
-files, supported by Checkers Framework
KAnnotator was originally created to support Kotlin — a JVM-targeted programming language that has null-safety built into its type system. Our experience has shown that external annotations are not a good fit for the Kotlin workflow, so we've removed support for external annotations from Kotlin and added support for platform types instead.
If you're using Kotlin, you do not need KAnnotator
With JSR 308 and Checkers Framework coming soon, KAnnotator gets another application area: the annotations it infers for Java libraries can be used by Java code checkers to verify Java code that uses these libraries.
KAnnotator binaries are available from the github release page
Additionally, IntelliJ IDEA plugin is available though a plugin repository
KAnnotator can be run by different means:
- IntelliJ IDEA plug-in: install and follow the instruction from here.
- Command line
$ java -jar kannotator-cli.jar
-f --format=<enum> - output format: jaif or xml [default XML]
-n --nullability=<boolean> - produce nullability annotations [default false]
-m --mutability=<boolean> - produce mutability annotations [default false]
-v --verbose=<boolean> - be verbose and show progress indicator [default false]
-c --one-directory-tree=<boolean> - do not create specific subdirectories for each library [default false]
-o --output-path=<string> - output path [default annotations/]