| \htmlhr |
| \chapterAndLabel{Introduction}{introduction} |
| |
| The Checker Framework enhances Java's type system to make it more powerful |
| and useful. |
| This lets software developers detect and |
| prevent errors in their Java programs. |
| |
| A ``checker'' is a tool that warns you about certain errors or gives you a |
| guarantee that those errors do not occur. |
| The Checker Framework comes with checkers for specific types of errors: |
| |
| \begin{enumerate} |
| % If you update this list, also update the list in advanced-features.tex . |
| |
| \item |
| \ahrefloc{nullness-checker}{Nullness Checker} for null pointer errors |
| (see \chapterpageref{nullness-checker}) |
| \item |
| \ahrefloc{initialization-checker}{Initialization Checker} to ensure all |
| \<@NonNull> fields are set in the constructor (see |
| \chapterpageref{initialization-checker}) |
| \item |
| \ahrefloc{map-key-checker}{Map Key Checker} to track which values are |
| keys in a map (see \chapterpageref{map-key-checker}) |
| \item |
| \ahrefloc{optional-checker}{Optional Checker} for errors in using the |
| \sunjavadoc{java.base/java/util/Optional.html}{Optional} type (see |
| \chapterpageref{optional-checker}) |
| \item |
| \ahrefloc{interning-checker}{Interning Checker} for errors in equality |
| testing and interning (see \chapterpageref{interning-checker}) |
| \item |
| \ahrefloc{lock-checker}{Lock Checker} for concurrency and lock errors |
| (see \chapterpageref{lock-checker}) |
| \item |
| \ahrefloc{index-checker}{Index Checker} for array accesses |
| (see \chapterpageref{index-checker}) |
| \item |
| \ahrefloc{fenum-checker}{Fake Enum Checker} to allow type-safe fake enum |
| patterns and type aliases or typedefs (see \chapterpageref{fenum-checker}) |
| \item |
| \ahrefloc{tainting-checker}{Tainting Checker} for trust and security errors |
| (see \chapterpageref{tainting-checker}) |
| \item |
| \ahrefloc{regex-checker}{Regex Checker} to prevent use of syntactically |
| invalid regular expressions (see \chapterpageref{regex-checker}) |
| \item |
| \ahrefloc{formatter-checker}{Format String Checker} to ensure that format |
| strings have the right number and type of \<\%> directives (see |
| \chapterpageref{formatter-checker}) |
| \item |
| \ahrefloc{i18n-formatter-checker}{Internationalization Format String Checker} |
| to ensure that i18n format strings have the right number and type of |
| \<\{\}> directives (see \chapterpageref{i18n-formatter-checker}) |
| \item |
| \ahrefloc{propkey-checker}{Property File Checker} to ensure that valid |
| keys are used for property files and resource bundles (see |
| \chapterpageref{propkey-checker}) |
| \item |
| \ahrefloc{i18n-checker}{Internationalization Checker} to |
| ensure that code is properly internationalized (see |
| \chapterpageref{i18n-checker}) |
| % The Compiler Message Key Checker is neither here nor in the advanced |
| % type system features chapter because it is really meant for |
| % Checker Framework developers and as sample code, and is not meant |
| % for Checker Framework users at large. |
| \item |
| \ahrefloc{signature-checker}{Signature String Checker} to ensure that the |
| string representation of a type is properly used, for example in |
| \<Class.forName> (see \chapterpageref{signature-checker}) |
| \item |
| \ahrefloc{guieffect-checker}{GUI Effect Checker} to ensure that non-GUI |
| threads do not access the UI, which would crash the application |
| (see \chapterpageref{guieffect-checker}) |
| \item |
| \ahrefloc{units-checker}{Units Checker} to ensure operations are |
| performed on correct units of measurement |
| (see \chapterpageref{units-checker}) |
| \item |
| \ahrefloc{signedness-checker}{Signedness Checker} to |
| ensure unsigned and signed values are not mixed |
| (see \chapterpageref{signedness-checker}) |
| \item |
| \ahrefloc{purity-checker}{Purity Checker} to identify whether |
| methods have side effects (see \chapterpageref{purity-checker}) |
| \item |
| \ahrefloc{constant-value-checker}{Constant Value Checker} to determine |
| whether an expression's value can be known at compile time |
| (see \chapterpageref{constant-value-checker}) |
| \item |
| \ahrefloc{reflection-resolution}{Reflection Checker} to determine |
| whether an expression's value (of type \<Method> or \<Class>) can be known at compile time |
| (see \chapterpageref{reflection-resolution}) |
| \item |
| \ahrefloc{initialized-fields-checker}{Initialized Fields Checker} to ensure all |
| fields are set in the constructor (see |
| \chapterpageref{initialization-checker}) |
| \item |
| \ahrefloc{aliasing-checker}{Aliasing Checker} to identify whether |
| expressions have aliases (see \chapterpageref{aliasing-checker}) |
| \item |
| \ahrefloc{must-call-checker}{Must Call Checker} to over-approximate the |
| methods that should be called on an object before it is de-allocated (see \chapterpageref{must-call-checker}) |
| \item |
| \ahrefloc{subtyping-checker}{Subtyping Checker} for customized checking without |
| writing any code (see \chapterpageref{subtyping-checker}) |
| % \item |
| % \ahrefloc{typestate-checker}{Typestate checker} to ensure operations are |
| % performed on objects that are in the right state, such as only opened |
| % files being read (see \chapterpageref{typestate-checker}) |
| \item |
| \ahrefloc{third-party-checkers}{Third-party checkers} that are distributed |
| separately from the Checker Framework |
| (see \chapterpageref{third-party-checkers}) |
| |
| \end{enumerate} |
| |
| \noindent |
| These checkers are easy to use and are invoked as arguments to \<javac>. |
| |
| |
| The Checker Framework also enables you to write new checkers of your |
| own; see Chapters~\ref{subtyping-checker} and~\ref{creating-a-checker}. |
| |
| |
| \sectionAndLabel{How to read this manual}{how-to-read-this-manual} |
| |
| If you wish to get started using some particular type system from the list |
| above, then the most effective way to read this manual is: |
| |
| \begin{itemize} |
| \item |
| Read all of the introductory material |
| (Chapters~\ref{introduction}--\ref{using-a-checker}). |
| \item |
| Read just one of the descriptions of a particular type system and its |
| checker (Chapters~\ref{nullness-checker}--\ref{third-party-checkers}). |
| \item |
| Skim the advanced material that will enable you to make more effective |
| use of a type system |
| (Chapters~\ref{polymorphism}--\ref{troubleshooting}), so that you will |
| know what is available and can find it later. Skip |
| Chapter~\ref{creating-a-checker} on creating a new checker. |
| \end{itemize} |
| |
| |
| \sectionAndLabel{How it works: Pluggable types}{pluggable-types} |
| |
| Java's built-in type-checker finds and prevents many errors --- but it |
| doesn't find and prevent \emph{enough} errors. The Checker Framework lets you |
| define new type systems and run them as a plug-in to the javac compiler. Your |
| code stays completely backward-compatible: your code compiles with any |
| Java compiler, it runs on any JVM, and your coworkers don't have to use the |
| enhanced type system if they don't want to. You can check part of |
| your program, or the whole thing. Type inference tools exist to help you annotate your |
| code; see Section~\ref{type-inference}. |
| |
| Most programmers will use type systems created by other people, such as |
| those listed at the start of the introduction (\chapterpageref{introduction}). |
| Some people, called ``type system designers'', create new type systems |
| (\chapterpageref{creating-a-checker}). |
| The Checker Framework is useful both to programmers who |
| wish to write error-free code, and to type system designers who wish to |
| evaluate and deploy their type systems. |
| |
| This document uses the terms ``checker'' and ``type-checking compiler |
| plugin'' as synonyms. |
| |
| \sectionAndLabel{Installation}{installation} |
| |
| This section describes how to install the Checker Framework. |
| \begin{itemize} |
| \item |
| If you use a build system that automatically downloads dependencies, |
| such as Gradle or Maven, \textbf{no installation is necessary}; just see |
| \chapterpageref{external-tools}. |
| \item |
| If you wish to try the Checker Framework without installing it, use the |
| \href{http://eisop.uwaterloo.ca/live/}{Checker Framework Live Demo} webpage. |
| \item |
| This section describes how to install the Checker Framework from its |
| distribution. The Checker Framework release contains everything that you |
| need, both to run checkers and to write your own checkers. |
| \item |
| Alternately, you can build the latest development version from source |
| (Section~\refwithpage{build-source}). |
| \end{itemize} |
| |
| |
| \textbf{Requirement:} |
| % Keep in sync with build.gradle and SourceChecker.init. |
| You must have \textbf{JDK 8} or \textbf{JDK 11} installed. |
| % Possible replacement for the above. |
| % You must have a supported LTS JDK installed: \textbf{JDK 8} or \textbf{JDK 11}. |
| The Checker Framework processes code written for either of those versions. |
| |
| The installation process has two required steps and one |
| optional step. |
| \begin{enumerate} |
| \item |
| Download the Checker Framework distribution: |
| %BEGIN LATEX |
| \\ |
| %END LATEX |
| \url{https://checkerframework.org/checker-framework-3.13.0.zip} |
| |
| \item |
| Unzip it to create a \code{checker-framework-\ReleaseVersion{}} directory. |
| |
| \item |
| \label{installation-configure-step}% |
| Configure your IDE, build system, or command shell to include the Checker |
| Framework on the classpath. Choose the appropriate section of |
| Chapter~\ref{external-tools}. |
| |
| |
| \end{enumerate} |
| |
| Now you are ready to start using the checkers. |
| |
| We recommend that you work through the |
| \ahreforurl{https://checkerframework.org/tutorial/}{Checker |
| Framework tutorial}, which demonstrates the Nullness, Regex, and Tainting Checkers. |
| |
| Section~\ref{example-use} walks you through a simple example. More detailed |
| instructions for using a checker appear in Chapter~\ref{using-a-checker}. |
| |
| \label{version-number} |
| The Checker Framework is released on a monthly schedule. The minor version |
| (the middle number in the version number) is incremented if there are any |
| incompatibilities |
| % Sometimes, we permit trivial incompatibilities, or ones that are unlikely |
| % to affect users, without changing the minor version. |
| with the previous version, including in user-visible |
| behavior or in methods that a checker implementation might call. |
| |
| |
| \sectionAndLabel{Example use: detecting a null pointer bug}{example-use} |
| |
| This section gives a very simple example of running the Checker Framework. |
| There is also a \ahreforurl{https://checkerframework.org/tutorial/}{tutorial} |
| that you can work along with. |
| |
| Let's consider this very simple Java class. The local variable \<ref>'s type is |
| annotated as \refqualclass{checker/nullness/qual}{NonNull}, indicating that \<ref> must be a reference to a |
| non-null object. Save the file as \<GetStarted.java>. |
| |
| \begin{Verbatim} |
| import org.checkerframework.checker.nullness.qual.*; |
| |
| public class GetStarted { |
| void sample() { |
| @NonNull Object ref = new Object(); |
| } |
| } |
| \end{Verbatim} |
| |
| If you run the Nullness Checker (Chapter~\ref{nullness-checker}), the |
| compilation completes without any errors. |
| |
| Now, introduce an error. Modify \<ref>'s assignment to: |
| \begin{alltt} |
| @NonNull Object ref = \textbf{null}; |
| \end{alltt} |
| |
| If you run the Nullness Checker again, it emits |
| the following error: |
| \begin{Verbatim} |
| GetStarted.java:5: incompatible types. |
| found : @Nullable <nulltype> |
| required: @NonNull Object |
| @NonNull Object ref = null; |
| ^ |
| 1 error |
| \end{Verbatim} |
| |
| This is a trivially simple example. Even an unsound bug-finding tool like |
| SpotBugs or Error Prone could have detected this bug. The |
| Checker Framework's analysis is more powerful than those tools and detects |
| more code defects than they do. |
| |
| Type qualifiers such as \<@NonNull> are permitted anywhere |
| that you can write a type, including generics and casts; see |
| Section~\ref{writing-annotations}. Here are some examples: |
| |
| \begin{alltt} |
| \underline{@Interned} String intern() \ttlcb{} ... \ttrcb{} // return value |
| int compareTo(\underline{@NonNull} String other) \ttlcb{} ... \ttrcb{} // parameter |
| \underline{@NonNull} List<\underline{@Interned} String> messages; // non-null list of interned Strings |
| \end{alltt} |
| |
| |
| \htmlhr |
| \chapterAndLabel{Using a checker}{using-a-checker} |
| |
| A pluggable type-checker enables you to detect certain bugs in your code, |
| or to prove that they are not present. The verification happens at compile |
| time. |
| |
| |
| Finding bugs, or verifying their absence, with a checker is a two-step process, whose steps are |
| described in Sections~\ref{writing-annotations} and~\ref{running}. |
| |
| \begin{enumerate} |
| |
| \item The programmer writes annotations, such as \refqualclass{checker/nullness/qual}{NonNull} and |
| \refqualclass{checker/interning/qual}{Interned}, that specify additional information about Java types. |
| (Or, the programmer uses an inference tool to automatically infer |
| annotations that are consistent with their code: see Section~\ref{type-inference}.) |
| It is possible to annotate only part of your code: see |
| Section~\ref{unannotated-code}. |
| |
| \item The checker reports whether the program contains any erroneous code |
| --- that is, code that is inconsistent with the annotations. |
| |
| \end{enumerate} |
| |
| This chapter is structured as follows: |
| \begin{itemize} |
| \item Section~\ref{writing-annotations}: How to write annotations |
| \item Section~\ref{running}: How to run a checker |
| \item Section~\ref{checker-guarantees}: What the checker guarantees |
| \item Section~\ref{tips-about-writing-annotations}: Tips about writing annotations |
| \end{itemize} |
| |
| Additional topics that apply to all checkers are covered later in the manual: |
| \begin{itemize} |
| \item Chapter~\ref{advanced-type-system-features}: Advanced type system features |
| \item Chapter~\ref{suppressing-warnings}: Suppressing warnings |
| \item Chapter~\ref{annotating-libraries}: Annotating libraries |
| \item Chapter~\ref{creating-a-checker}: How to create a new checker |
| \item Chapter~\ref{external-tools}: Integration with external tools |
| \end{itemize} |
| |
| |
| There is a |
| \ahreforurl{https://checkerframework.org/tutorial/}{tutorial} |
| that walks you through using the Checker Framework on the |
| command line. |
| |
| % The annotations have to be on your classpath even when you are not using |
| % the -processor, because of the existence of the import statement for |
| % the annotations. |
| |
| |
| \sectionAndLabel{Where to write type annotations}{writing-annotations} |
| |
| You may write a type annotation immediately before any |
| use of a type, including in generics and casts. Because array levels are |
| types and receivers have types, you can also write type annotations on |
| them. Here are a few examples of type annotations: |
| |
| %BEGIN LATEX |
| \begin{smaller} |
| %END LATEX |
| \begin{alltt} |
| \underline{@Interned} String intern() \ttlcb{} ... \ttrcb{} // return value |
| int compareTo(\underline{@NonNull} String other) \ttlcb{} ... \ttrcb{} // parameter |
| String toString(\underline{@Tainted} MyClass this) \ttlcb{} ... \ttrcb{} // receiver ("this" parameter) |
| \underline{@NonNull} List<\underline{@Interned} String> messages; // generics: non-null list of interned Strings |
| \underline{@Interned} String \underline{@NonNull} [] messages; // arrays: non-null array of interned Strings |
| myDate = (\underline{@Initialized} Date) beingConstructed; // cast |
| \end{alltt} |
| %BEGIN LATEX |
| \end{smaller} |
| %END LATEX |
| |
| You only need to write type annotations on method signatures, fields, and some type arguments. |
| Most annotations within method bodies are inferred for you; for more details, |
| see Section~\ref{type-refinement}. |
| |
| The Java Language Specification also defines |
| declaration annotations, such as \<@Deprecated> and \<@Override>, which apply |
| to a class, method, or field but do not apply to the method's return type |
| or the field's type. They should be written on their own line in the |
| source code, before the method's signature. |
| |
| |
| \sectionAndLabel{Running a checker}{running} |
| |
| To run a checker, run the compiler \code{javac} as usual, |
| but either pass the \code{-processor \emph{plugin\_class}} command-line |
| option, or use auto-discovery as described in |
| Section~\ref{checker-auto-discovery}. |
| (If your project already uses auto-discovery for some annotation processor, |
| such as AutoValue, then you should use auto-discovery.) |
| A concrete example of using \code{-processor} to run the Nullness Checker is: |
| |
| \begin{Verbatim} |
| javac -processor nullness MyFile.java |
| \end{Verbatim} |
| |
| \noindent |
| where \<javac> is as specified in Section~\ref{javac-wrapper}. |
| |
| You can also run a checker from within your favorite IDE or build system. See |
| Chapter~\ref{external-tools} for details about build tools such as |
| Ant (Section~\ref{ant-task}), |
| Buck (Section~\ref{buck}), |
| Gradle (Section~\ref{gradle}), |
| Maven (Section~\ref{maven}), and |
| sbt (Section~\ref{sbt}); |
| IDEs such as |
| Eclipse (Section~\ref{eclipse}), |
| IntelliJ IDEA (Section~\ref{intellij}), |
| NetBeans (Section~\ref{netbeans}), |
| and |
| tIDE (Section~\ref{tide}); |
| and about customizing other IDEs and build tools. |
| |
| The checker is run on only the Java files that javac compiles. |
| This includes all Java files specified on the command line and those |
| created by another annotation processor. It may also include other of |
| your Java files, if they are more recent than the corresponding \code{.class} file. |
| Even when the checker does not analyze a class (say, the class was |
| already compiled, or source code is not available), it does check |
| the \emph{uses} of those classes in the source code being compiled. |
| Type-checking works modularly and intraprocedurally: when verifying a |
| method, it examines only the signature (including annotations) of other |
| methods, not their implementations. When analyzing a variable use, it |
| relies on the type of the variable, not any dataflow outside the current |
| method that produced the value. |
| |
| After you compile your code while running a checker, the resulting |
| \<.class> and \<.jar> files can be used for pluggable type-checking of client code. |
| |
| If you compile code without the \code{-processor} |
| command-line option, no checking of the type |
| annotations is performed. Furthermore, only explicitly-written annotations |
| are written to the \<.class> file; defaulted annotations are not, and this |
| will interfere with type-checking of clients that use your code. |
| Therefore, to create |
| \<.class> files that will be distributed or compiled against, you should run the |
| type-checkers for all the annotations that you have written. |
| |
| |
| \subsectionAndLabel{Using annotated libraries}{annotated-libraries-using} |
| |
| When your code uses a library that is not currently being compiled, the |
| Checker Framework looks up the library's annotations in its class files or |
| in a stub file. |
| |
| Some projects are already distributed with type annotations by their |
| maintainers, so you do not need to do anything special. |
| An example is all the libraries in \url{https://github.com/plume-lib/}. |
| Over time, this should become more common. |
| |
| For some other libraries, the Checker Framework developers have provided an |
| annotated version of the library, either as a stub file or as compiled class files. |
| (If some library is not available in either of these forms, |
| you can contribute by annotating it, which will |
| help you and all other Checker Framework users; see |
| \chapterpageref{annotating-libraries}.) |
| |
| Some stub files are used automatically by a checker, without any action on |
| your part. For others, you must pass the \<-Astubs=...> command-line argument. |
| As a special case, if an \<.astub> file appears in |
| \<checker/resources/>, then pass the command-line option |
| use \<-Astubs=checker.jar/\emph{stubfilename.astub}>. |
| The ``\<checker.jar>'' should be literal --- don't provide a path. |
| This special syntax only works for ``\<checker.jar>''. |
| %% There aren't any such libraries at the moment. |
| % (Examples of such libraries are: |
| % % This list appears here to make it searchable/discoverable. |
| % ... |
| % .) |
| |
| The annotated libraries that are provided as class files appear in |
| \ahref{https://search.maven.org/search?q=org.checkerframework.annotatedlib}{the |
| \<org.checkerframework.annotatedlib> group in the Maven Central Repository}. |
| The annotated library has \emph{identical} behavior to the upstream, |
| unannotated version; the source code is identical other than added |
| annotations. |
| % |
| (Some of the annotated libraries are |
| % This list appears here to make it searchable/discoverable. |
| bcel, |
| commons-csv, |
| commons-io, |
| guava, |
| and |
| java-getopt.) |
| |
| To use an annotated library: |
| |
| \begin{itemize} |
| \item |
| If your project stores \<.jar> files locally, then |
| \ahref{https://search.maven.org/search?q=org.checkerframework.annotatedlib}{download |
| the \<.jar> file from the Maven Central Repository}. |
| |
| \item |
| If your project manages dependencies using a tool such as Gradle or Maven, |
| then update your buildfile to use the \<org.checkerframework.annotatedlib> |
| group. For example, in \<build.gradle>, change |
| |
| \begin{Verbatim} |
| api group: 'org.apache.bcel', name: 'bcel', version: '6.3.1' |
| api group: 'commons-io', name: 'commans-io', version: '2.6' |
| \end{Verbatim} |
| |
| \noindent |
| to |
| |
| \begin{Verbatim} |
| api group: 'org.checkerframework.annotatedlib', name: 'bcel', version: '6.3.1' |
| api group: 'org.checkerframework.annotatedlib', name: 'commons-io', version: '2.6.0.1' |
| \end{Verbatim} |
| |
| \noindent |
| Usually use the same version number. (Sometimes you will use a slightly larger |
| number, if the Checker Framework developers have improved the type |
| annotations since the last release by the upstream maintainers.) If a |
| newer version of the upstream library is available but that version is not |
| available in \<org.checkerframework.annotatedlib>, then |
| \ahrefloc{reporting-bugs}{open an issue} requesting that the |
| \<org.checkerframework.annotatedlib> version be updated. |
| \end{itemize} |
| |
| %% This is for paranoid users. |
| % During type-checking, you should use the |
| % annotated version of the library to improve type-checking results (to issue |
| % fewer false positive warnings). When doing ordinary compilation or while |
| % running your code, you can use either the annotated library or the regular |
| % distributed version of the library --- they behave identically. |
| |
| There is one special case. If an \<.astub> file is shipped with the |
| Checker Framework in \<checker/resources/>, then you can |
| use \<-Astubs=checker.jar/\emph{stubfilename.astub}>. |
| The ``\<checker.jar>'' should be literal --- don't provide a path. |
| (This special syntax only works for ``\<checker.jar>''.) |
| |
| |
| \subsectionAndLabel{Summary of command-line options}{checker-options} |
| |
| You can pass command-line arguments to a checker via \<javac>'s standard \<-A> |
| option (``\<A>'' stands for ``annotation''). All of the distributed |
| checkers support the following command-line options. |
| Each checker may support additional command-line options; see the checker's |
| documentation. |
| |
| To pass an option to only a particular checker, |
| prefix the option with the canonical or simple name |
| of a checker, followed by an underscore ``\<\_>''. |
| Such an option will apply only to a checker with that name or any subclass of that checker. |
| For example, you can use |
| \begin{Verbatim} |
| -ANullnessChecker_lint=redundantNullComparison |
| -Aorg.checkerframework.checker.guieffect.GuiEffectChecker_lint=debugSpew |
| \end{Verbatim} |
| |
| \noindent |
| to pass different lint options to the Nullness and GUI Effect Checkers. A |
| downside is that, in this example, the Nullness Checker will issue a |
| ``The following options were not recognized by any processor'' warning |
| about the second option and the GUI Effect Checker will issue a |
| ``The following options were not recognized by any processor'' warning |
| about the first option. |
| |
| % This list should be kept in sync with file |
| % framework/src/main/java/org/checkerframework/framework/source/SourceChecker.java |
| |
| Unsound checking: ignore some errors |
| \begin{itemize} |
| \item \<-AsuppressWarnings> |
| Suppress all errors and warnings matching the given key; see |
| Section~\ref{suppresswarnings-command-line}. |
| \item \<-AskipUses>, \<-AonlyUses> |
| Suppress all errors and warnings at all uses of a given class --- or at all |
| uses except those of a given class. See Section~\ref{askipuses}. |
| \item \<-AskipDefs>, \<-AonlyDefs> |
| Suppress all errors and warnings within the definition of a given class |
| --- or everywhere except within the definition of a given class. See |
| Section~\ref{askipdefs}. |
| \item \<-AassumeSideEffectFree>, \<-AassumeDeterministic>, \<-AassumePure> |
| Unsoundly assume that every method is side-effect-free, deterministic, or |
| both; see |
| Section~\ref{type-refinement-purity}. |
| \item \<-AassumeAssertionsAreEnabled>, \<-AassumeAssertionsAreDisabled> |
| Whether to assume that assertions are enabled or disabled; see Section~\ref{type-refinement-assertions}. |
| \item \<-AignoreRangeOverflow> |
| Ignore the possibility of overflow for range annotations such as |
| \<@IntRange>; see Section~\ref{value-checker-overflow}. |
| \item \<-Awarns> |
| Treat checker errors as warnings. If you use this, you may wish to also |
| supply \code{-Xmaxwarns 10000}, because by default \<javac> prints at |
| most 100 warnings. If you use this, don't supply \code{-Werror}, |
| which is a javac argument to halt compilation if a warning is issued. |
| \item \<-AignoreInvalidAnnotationLocations> |
| Ignore annotations in bytecode that have invalid annotation locations. |
| \end{itemize} |
| |
| \label{unsound-by-default} |
| More sound (strict) checking: enable errors that are disabled by default |
| \begin{itemize} |
| \item \<-AcheckPurityAnnotations> |
| Check the bodies of methods marked |
| \refqualclass{dataflow/qual}{SideEffectFree}, |
| \refqualclass{dataflow/qual}{Deterministic}, |
| and \refqualclass{dataflow/qual}{Pure} |
| to ensure the method satisfies the annotation. By default, |
| the Checker Framework unsoundly trusts the method annotation. See |
| Section~\ref{type-refinement-purity}. |
| \item \<-AinvariantArrays> |
| Make array subtyping invariant; that is, two arrays are subtypes of one |
| another only if they have exactly the same element type. By default, |
| the Checker Framework unsoundly permits covariant array subtyping, just |
| as Java does. See Section~\ref{invariant-arrays}. |
| \item \<-AcheckCastElementType> |
| In a cast, require that parameterized type arguments and array elements |
| are the same. By default, the Checker Framework unsoundly permits them |
| to differ, just as Java does. See Section~\ref{covariant-type-parameters} |
| and Section~\ref{invariant-arrays}. |
| \item \<-AuseConservativeDefaultsForUncheckedCode> |
| Enables conservative defaults, and suppresses all type-checking warnings, |
| in unchecked code. Takes arguments ``source,bytecode''. |
| ``-source,-bytecode'' is the (unsound) default setting. |
| \begin{itemize} |
| \item |
| ``bytecode'' specifies |
| whether the checker should apply conservative defaults to |
| bytecode (that is, to already-compiled libraries); see |
| Section~\ref{defaults-classfile}. |
| \item |
| Outside the scope of any relevant |
| \refqualclass{framework/qual}{AnnotatedFor} annotation, ``source'' specifies whether conservative |
| default annotations are applied to source code and suppress all type-checking warnings; see |
| Section~\ref{compiling-libraries}. |
| \end{itemize} |
| \item \<-AconcurrentSemantics> |
| Whether to assume concurrent semantics (field values may change at any |
| time) or sequential semantics; see Section~\ref{faq-concurrency}. |
| \item \<-AconservativeUninferredTypeArguments> |
| Whether an error should be issued if type arguments could not be inferred and |
| whether method type arguments that could not be inferred should use |
| conservative defaults. |
| By default, such type arguments are (largely) ignored in later |
| checks. |
| Passing this option uses a conservative value instead. |
| See \href{https://github.com/typetools/checker-framework/issues/979}{Issue |
| 979}. |
| \item \<-AignoreRawTypeArguments=false> |
| Do not ignore subtype tests for type arguments that were inferred for a |
| raw type. Must also use \<-AconservativeUninferredTypeArguments>. See |
| Section~\ref{generics-raw-types}. |
| \item \<-processor org.checkerframework.common.initializedfields.InitializedFieldsChecker,...> |
| Ensure that all fields are initialized by the constructor. See |
| \chapterpageref{initialized-fields-checker}. |
| \end{itemize} |
| |
| Type-checking modes: enable/disable functionality |
| \begin{itemize} |
| \item \<-Alint> |
| Enable or disable optional checks; see Section~\ref{lint-options}. |
| \item \<-AsuggestPureMethods> |
| Suggest methods that could be marked |
| \refqualclass{dataflow/qual}{SideEffectFree}, |
| \refqualclass{dataflow/qual}{Deterministic}, |
| or \refqualclass{dataflow/qual}{Pure}; see |
| Section~\ref{type-refinement-purity}. |
| \item \<-AresolveReflection> |
| Determine the target of reflective calls, and perform more precise |
| type-checking based no that information; see |
| Chapter~\ref{reflection-resolution}. \<-AresolveReflection=debug> causes |
| debugging information to be output. |
| \item \<-Ainfer=\emph{outputformat}> |
| Output suggested annotations for method signatures and fields. |
| These annotations may reduce the number of type-checking |
| errors when running type-checking in the future; see |
| Section~\ref{whole-program-inference}. |
| Using \<-Ainfer=jaifs> produces \<.jaif> files. |
| Using \<-Ainfer=stubs> produces \<.astub> files. |
| Using \<-Ainfer=ajava> produces \<.ajava> files. |
| You must also supply \<-Awarns>, or the inference output may be incomplete. |
| \item \<-AshowSuppressWarningsStrings> |
| With each warning, show all possible strings to suppress that warning. |
| \item \<-AwarnUnneededSuppressions> |
| Issue a warning if a \<@SuppressWarnings> did not suppress a warning |
| issued by the checker. This only warns about |
| \<@SuppressWarnings> strings that contain a checker name |
| (Section~\ref{suppresswarnings-annotation-syntax}). The |
| \<-ArequirePrefixInWarningSuppressions> command-line argument ensures |
| that all \<@SuppressWarnings> strings contain a checker name. |
| \item \<-AwarnUnneededSuppressionsExceptions=\emph{regex}> disables |
| \<-AwarnUnneededSuppressions> for \<@SuppressWarnings> strings that |
| contain a match for the regular expression. Most users don't need this. |
| \item \<-ArequirePrefixInWarningSuppressions> |
| Require that the string in a warning suppression annotation begin with a checker |
| name. Otherwise, the suppress warning annotation does not |
| suppress any warnings. For example, if this command-line option is |
| supplied, then \<@SuppressWarnings("assignment")> has no effect, but |
| \<@SuppressWarnings("nullness:assignment")> does. |
| \end{itemize} |
| |
| Partially-annotated libraries |
| \begin{itemize} |
| |
| % \item \<-AprintUnannotatedMethods> |
| % List library methods that need to be annotated; see |
| % Section~\ref{annotating-libraries}. |
| |
| \item \<-Astubs> |
| List of stub files or directories; see Section~\ref{stub-using}. |
| |
| \item |
| \<-AstubWarnIfNotFound>, |
| \<-AstubWarnIfNotFoundIgnoresClasses>, |
| %% Uncomment when https://tinyurl.com/cfissue/2759 is fixed. |
| % \<-AstubWarnIfOverwritesBytecode>, |
| \<-AstubWarnIfRedundantWithBytecode>, |
| \<-AstubWarnNote>, |
| Warn about problems with stub files; see Section~\ref{stub-troubleshooting}. |
| |
| \item \<-AmergeStubsWithSource> |
| If both a stub file and a source file for a class are available, trust |
| both and use the greatest lower bound of their annotations. The default |
| behavior (without this flag) is to ignore types from the stub file if |
| source is available. See Section~\ref{stub-multiple-specifications}. |
| % note to maintainers: GLB of the two types was chosen to support |
| % using this flag in combination with \<-Ainfer=stubs>. |
| |
| % This item is repeated above: |
| \item \<-AuseConservativeDefaultsForUncheckedCode=source> |
| Outside the scope of any relevant |
| \refqualclass{framework/qual}{AnnotatedFor} annotation, use conservative |
| default annotations and suppress all type-checking warnings; see |
| Section~\ref{compiling-libraries}. |
| |
| \end{itemize} |
| |
| Debugging |
| \begin{itemize} |
| \item |
| \<-AprintAllQualifiers>, |
| \<-AprintVerboseGenerics>, |
| \<-Anomsgtext>, |
| \<-AdumpOnErrors> |
| Amount of detail in messages; see Section~\ref{creating-debugging-options-detail}. |
| |
| \item |
| \<-Adetailedmsgtext> |
| Format of diagnostic messages; see Section~\ref{creating-debugging-options-format}. |
| |
| \item |
| \<-Aignorejdkastub>, |
| \<-ApermitMissingJdk>, |
| \<-AparseAllJdk>, |
| \<-AstubDebug> |
| Stub and JDK libraries; see Section~\ref{creating-debugging-options-libraries}. |
| |
| \item |
| \<-Afilenames>, |
| \<-Ashowchecks>, |
| \<-AshowInferenceSteps> |
| Progress tracing; see Section~\ref{creating-debugging-options-progress}. |
| |
| \item |
| \<-AoutputArgsToFile> |
| Output the compiler command-line arguments to a file. Useful when the |
| command line is generated and executed by a tool, such as a build system. |
| This produces a standalone command line that can be executed independently |
| of the tool that generated it (such as a build system). |
| That command line makes it easier to reproduce, report, and debug issues. |
| For example, the command line can be modified to enable attaching a debugger. |
| See Section~\ref{creating-debugging-options-output-args}. |
| |
| \item |
| \<-Aflowdotdir>, |
| \<-Averbosecfg>, |
| \<-Acfgviz> |
| Draw a visualization of the CFG (control flow graph); see |
| Section~\ref{creating-debugging-dataflow-graph}. |
| |
| \item |
| \<-AresourceStats>, |
| \<-AatfDoNotCache>, |
| \<-AatfCacheSize> |
| Miscellaneous debugging options; see Section~\ref{creating-debugging-options-misc}. |
| |
| \item |
| \<-Aversion> |
| Print the Checker Framework version. |
| |
| \item |
| \<-AprintGitProperties> |
| Print information about the git repository from which the Checker Framework |
| was compiled. |
| |
| \end{itemize} |
| |
| |
| \noindent |
| Some checkers support additional options, which are described in that |
| checker's manual section. |
| % Search for "@SupportedOptions" in the implementation to find them all. |
| For example, \<-Aquals> tells |
| the Subtyping Checker (see Chapter~\ref{subtyping-checker}) and the Fenum Checker |
| (see Chapter~\ref{fenum-checker}) which annotations to check. |
| |
| |
| Here are some standard javac command-line options that you may find useful. |
| Many of them contain the word ``processor'', because in javac jargon, a |
| checker is an ``annotation processor''. |
| |
| \begin{itemize} |
| \item \<-processor> Names the checker to be |
| run; see Sections~\ref{running} and~\ref{shorthand-for-checkers}. |
| May be a comma-separated list of multiple checkers. Note that javac |
| stops processing an indeterminate time after detecting an error. When |
| providing multiple checkers, if one checker detects any error, subsequent |
| checkers may not run. |
| \item \<-processorpath> Indicates where to search for the |
| checker. This should also contain any classes used by type-checkers, |
| such as qualifiers used by the Subtyping Checker (see |
| Section~\ref{subtyping-example}) and classes that define |
| statically-executable methods used by the Constant Value Checker (see |
| Section~\ref{constant-value-staticallyexecutable-annotation}). |
| \item \<-proc:>\{\<none>,\<only>\} Controls whether checking |
| happens; \<-proc:none> |
| means to skip checking; \<-proc:only> means to do only |
| checking, without any subsequent compilation; see |
| Section~\ref{checker-auto-discovery}. |
| \item \<-implicit:class> Suppresses warnings about implicitly compiled files |
| (not named on the command line); see Section~\ref{ant-task} |
| \item \<-J> Supply an argument to the JVM that is running javac; |
| for example, \<-J-Xmx2500m> to increase its maximum heap size |
| \item \<-doe> To ``dump on error'', that is, output a stack trace |
| whenever a compiler warning/error is produced. Useful when debugging |
| the compiler or a checker. |
| \end{itemize} |
| |
| The Checker Framework does not support \<-source 1.7> or earlier. You must |
| supply \<-source 1.8> or later, or no \<-source> command-line argument, |
| when running \<javac>. |
| |
| |
| \subsectionAndLabel{Checker auto-discovery}{checker-auto-discovery} |
| |
| ``Auto-discovery'' makes the \code{javac} compiler always run an |
| annotation processor, such as a checker |
| plugin without explicitly passing the \code{-processor} |
| command-line option. This can make your command line shorter, and it ensures |
| that your code is checked even if you forget the command-line option. |
| |
| If the \<javac> command line specifies any \<-processor> command-line |
| option, then auto-discovery is disabled. This means that if your project |
| currently uses auto-discovery, you should use auto-discovery for the |
| Checker Framework too. |
| |
| \begin{sloppypar} |
| To enable auto-discovery, place a configuration file named |
| \code{META-INF/services/javax.annotation.processing.Processor} |
| in your classpath. The file contains the names of the checkers to |
| be used, listed one per line. For instance, to run the Nullness Checker and the |
| Interning Checker automatically, the configuration file should contain: |
| \end{sloppypar} |
| |
| %BEGIN LATEX |
| \begin{smaller} |
| %END LATEX |
| \begin{Verbatim} |
| org.checkerframework.checker.nullness.NullnessChecker |
| org.checkerframework.checker.interning.InterningChecker |
| \end{Verbatim} |
| %BEGIN LATEX |
| \end{smaller} |
| %END LATEX |
| |
| You can disable this auto-discovery mechanism by passing the |
| \code{-proc:none} command-line option to \<javac>, which disables all |
| annotation processing including all pluggable type-checking. |
| |
| %% Auto-discovering all the distributed checkers by default would be |
| %% problematic: the nullness and mutability checkers would issue lots of |
| %% errors for unannotated code, and that would be irritating. So, leave it |
| %% up to the user to enable auto-discovery. |
| |
| |
| \subsectionAndLabel{Shorthand for built-in checkers}{shorthand-for-checkers} |
| |
| % TODO: this feature only works for our javac script, not when using |
| % the standard javac. Should this be explained? |
| |
| Ordinarily, javac's \code{-processor} flag requires fully-qualified class names. |
| When using the Checker Framework javac wrapper (Section~\ref{javac-wrapper}), you may |
| omit the package name and the \<Checker> suffix. |
| The following three commands are equivalent: |
| |
| \begin{alltt} |
| javac -processor \textbf{org.checkerframework.checker.nullness.NullnessChecker} MyFile.java |
| javac -processor \textbf{NullnessChecker} MyFile.java |
| javac -processor \textbf{nullness} MyFile.java |
| \end{alltt} |
| |
| This feature also works when multiple checkers are specified. |
| Their names are separated by commas, with no surrounding space. |
| For example: |
| |
| \begin{alltt} |
| javac -processor NullnessChecker,RegexChecker MyFile.java |
| javac -processor nullness,regex MyFile.java |
| \end{alltt} |
| |
| This feature does not apply to javac \href{https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javac.html#commandlineargfile}{@argfiles}. |
| |
| |
| \sectionAndLabel{What the checker guarantees}{checker-guarantees} |
| |
| A checker guarantees two things: type annotations reflect facts about |
| run-time values, and illegal operations are not performed. |
| |
| For example, the Nullness Checker (Chapter~\ref{nullness-checker}) |
| guarantees lack of null pointer exceptions (Java \<NullPointerException>). |
| More precisely, it guarantees |
| that expressions whose type is annotated with |
| \refqualclass{checker/nullness/qual}{NonNull} never evaluate to null, |
| and it forbids other expressions from being dereferenced. |
| |
| As another example, the Interning Checker (Chapter~\ref{interning-checker}) |
| guarantees that correct equality tests are performed. |
| More precisely, it guarantees that |
| every expression whose type is an \refqualclass{checker/interning/qual}{Interned} type |
| evaluates to an interned value, and it forbids |
| \<==> on other expressions. |
| |
| The guarantee holds only if you run the checker on every part of your |
| program and the checker issues no warnings anywhere in the code. |
| You can also verify just part of your program. |
| |
| There are some limitations to the guarantee. |
| |
| |
| \begin{itemize} |
| |
| \item |
| A compiler plugin can check only those parts of your program that you run |
| it on. If you compile some parts of your program without running the |
| checker, then there is no guarantee that the entire program satisfies the |
| property being checked. Some examples of un-checked code are: |
| |
| \begin{itemize} |
| \item |
| Code compiled without the \code{-processor} switch. This includes |
| external libraries supplied as a \code{.class} file and native methods |
| (because the implementation is not Java code, it cannot be checked). |
| \item |
| Code compiled with the \code{-AskipUses}, \code{-AonlyUses}, \code{-AskipDefs} or \code{-AonlyDefs} |
| command-line arguments (see Chapter~\ref{suppressing-warnings}). |
| \item |
| Dynamically generated code, such as generated by Spring or MyBatis. |
| Its bytecode is directly generated and run, not compiled by javac and |
| not visible to the Checker Framework. |
| % https://github.com/typetools/checker-framework/issues/3139 |
| \end{itemize} |
| |
| In each of these cases, any \emph{use} of the code is checked --- for |
| example, a call to a native method must be compatible with any |
| annotations on the native method's signature. |
| However, the annotations on the un-checked code are trusted; there is no |
| verification that the implementation of the native method satisfies the |
| annotations. |
| |
| \item |
| You can suppress warnings, such as via the \code{@SuppressWarnings} |
| annotation (\chapterpageref{suppressing-warnings}). If you do so |
| incorrectly, the checker's guarantee no longer holds. |
| |
| \item |
| The Checker Framework is, by default, unsound in a few places where a |
| conservative analysis would issue too many false positive warnings. |
| These are listed in Section~\ref{unsound-by-default}. |
| You can supply a command-line argument to make the Checker Framework |
| sound for each of these cases. |
| |
| %% This isn't an unsoundness in the Checker Framework: for any type system |
| %% that does not include a conservative library annotation for |
| %% Method.invoke, it is a bug in that particular type-checker. |
| % \item |
| % Reflection can violate the Java type system, and |
| % the checkers are not sophisticated enough to reason about the possible |
| % effects of reflection. Similarly, deserialization and cloning can |
| % create objects that could not result from normal constructor calls, and |
| % that therefore may violate the property being checked. |
| |
| \item |
| Specific checkers may have other limitations; see their documentation for |
| details. |
| |
| \end{itemize} |
| |
| In order to avoid a flood of unhelpful warnings, many of the checkers avoid |
| issuing the same warning multiple times. For example, consider this code: |
| |
| \begin{Verbatim} |
| @Nullable Object x = ...; |
| x.toString(); // warning |
| x.toString(); // no warning |
| \end{Verbatim} |
| |
| \noindent |
| The second call to \<toString> cannot possibly throw a null |
| pointer warning --- \<x> is non-null if control flows to the second |
| statement. |
| In other cases, a checker avoids issuing later warnings with the same cause |
| even when later code in a method might also fail. |
| This does not |
| affect the soundness guarantee, but a user may need to examine more |
| warnings after fixing the first ones identified. (Often, |
| a single fix corrects all the warnings.) |
| |
| % It might be worthwhile to permit a user to see every warning --- though I |
| % would not advocate this setting for daily use. |
| |
| If you find that a checker fails to issue a warning that it |
| should, then please report a bug (see Section~\ref{reporting-bugs}). |
| |
| |
| \sectionAndLabel{Tips about writing annotations}{tips-about-writing-annotations} |
| |
| Section~\ref{library-tips} gives additional tips that are |
| specific to annotating a third-party library. |
| |
| |
| \subsectionAndLabel{Write annotations before you run a checker}{annotate-before-checking} |
| |
| Before you run a checker, annotate the code, based on its documentation. |
| Then, run the checker to uncover bugs in the code or the documentation. |
| |
| Don't do the opposite, which is to run the checker and then add annotations |
| according to the warnings issued. This approach is less systematic, so you |
| may overlook some annotations. It often leads to confusion and poor |
| results. It leads users to make changes not for any principled reason, but |
| to ``make the type-checker happy'', even when the changes are in conflict |
| with the documentation or the code. Also see |
| \ahref{#get-started-annotations-are-a-specification}{``Annotations are a |
| specification''}, below. |
| |
| |
| \subsectionAndLabel{How to get started annotating legacy code}{get-started-with-legacy-code} |
| |
| Annotating an entire existing program may seem like a daunting task. But, |
| if you approach it systematically and do a little bit at a time, you will |
| find that it is manageable. |
| |
| \subsubsectionAndLabel{Start small}{get-started-start-small} |
| |
| Start small. Focus on one specific property that matters to you; in |
| other words, run just one checker rather than multiple ones. You may |
| choose a different checker for different programs. |
| Focus on |
| the most mission-critical or error-prone part of your code; don't try to |
| annotate your whole program at first. |
| |
| It is easiest to add annotations if you know the code or the |
| code contains documentation. While adding annotations, you will spend most of your time |
| understanding the code, and less time actually writing annotations |
| or running the checker. |
| |
| Don't annotate the whole program, but work module by module. |
| Start annotating classes at the leaves of the call tree --- |
| that is, |
| start with classes/packages that have few dependencies on other |
| code. |
| Annotate supertypes before you |
| annotate classes that extend or implement them. |
| The reason for this rule is that it is |
| easiest to annotate a class if the code it depends on has already been |
| annotated. |
| Sections~\ref{askipuses} and~\ref{askipdefs} give ways to skip |
| checking of some files, directories, or packages. |
| Section~\ref{unannotated-code} gives advice about handling calls from |
| annotated code into unannotated code. |
| |
| When annotating, be systematic; we recommend |
| annotating an entire class or module at a time (not just some of the methods) |
| so that you don't lose track of your work or redo work. For example, |
| working class-by-class avoids confusion about whether an unannotated type use |
| means you determined that the default is desirable, or it means you didn't |
| yet examine that type use. |
| |
| Don't overuse pluggable type-checking. If the regular Java type system can |
| verify a property using Java subclasses, then that is a better choice than |
| pluggable type-checking (see Section~\ref{faq-typequals-vs-subtypes}). |
| |
| |
| \subsubsectionAndLabel{Annotations are a specification}{get-started-annotations-are-a-specification} |
| |
| When you write annotations, you are writing a specification, and you should |
| think about them that way. Start out by understanding the program so that |
| you can write an accurate specification. |
| Sections~\ref{annotate-normal-behavior} |
| and~\ref{annotations-are-a-contract} give more tips about writing |
| specifications. |
| |
| For each class, read its Javadoc. For instance, if you are adding |
| annotations for the Nullness Checker (Section~\ref{nullness-checker}), then |
| you can search the documentation for ``null'' and then add \<@Nullable> |
| anywhere appropriate. Start by annotating signatures and fields, but not |
| method bodies. The only reason to even |
| \emph{read} the method bodies yet is to determine signature annotations for |
| undocumented methods --- |
| for example, if the method returns null, you know its return type should be |
| annotated \<@Nullable>, and a parameter that is compared against \<null> |
| may need to be annotated \<@Nullable>. |
| |
| The specification should state all facts that are relevant to callees. |
| When checking a method, the checker uses only the specification, not the |
| implementation, of other methods. (Equivalently, type-checking is |
| ``modular'' or ``intraprocedural''.) When analyzing a variable use, the |
| checker relies on the type of the variable, not any dataflow outside the |
| current method that produced the value. |
| |
| After you have annotated all the signatures, run the checker. |
| Then, fix bugs in code and add/modify annotations as necessary. |
| % If signature annotations are necessary, then you may want |
| % to fix the documentation that did not indicate the property; but this isn't |
| % strictly necessary, since the annotations that you wrote provide that |
| % documentation. |
| Don't get discouraged if you see many type-checker warnings at first. |
| Often, adding just a few missing annotations will eliminate many warnings, |
| and you'll be surprised how fast the process goes overall (assuming that |
| you understand the code, of course). |
| |
| It is usually not a good idea to experiment with adding and removing |
| annotations in order to understand their effect. It is better to reason |
| about the desired design. However, to avoid having to manually examine all |
| callees, a more automated approach is to save the checker output before |
| changing an annotation, then compare it to the checker output after |
| changing the annotation. |
| |
| Chapter~\ref{annotating-libraries} tells you how to annotate libraries that |
| your code uses. Section~\ref{handling-warnings} and |
| Chapter~\ref{suppressing-warnings} tell you what to do when you are unable |
| to eliminate checker warnings by adding annotations. |
| |
| |
| \subsubsectionAndLabel{Write good code}{get-started-write-good-code} |
| |
| Avoid complex code, which is more error-prone. If you write your code to |
| be simple and clear enough for the type-checker to verify, then it will |
| also be easier for programmers to understand. When you verify your code, a |
| side benefit is improving your code's structure. |
| |
| Your code should compile cleanly under the regular Java compiler. As a |
| specific example, your code should not use raw types like \code{List}; use |
| parameterized types like \code{List<String>} instead |
| (Section~\ref{generics-raw-types}). If you suppress Java compiler |
| warnings, then the Checker Framework will issue more warnings, and its |
| messages will be more confusing. (Also, if you are not willing to write |
| code that type-checks in Java, then you might not be willing to use an even |
| more powerful type system.) |
| |
| Do not write unnecessary annotations. |
| \begin{itemize} |
| \item |
| Do not annotate local variables unless necessary. The checker infers |
| annotations for local variables (see Section~\ref{type-refinement}). |
| Usually, you only need to annotate fields and method signatures. You |
| should add annotations inside method bodies only if the checker is unable |
| to infer the correct annotation (usually on type arguments or array |
| element types, rather than |
| on top-level types). |
| % or if |
| % you need to suppress a warning (see Chapter~\ref{suppressing-warnings}). |
| |
| \item |
| Do not write annotations that are redundant with defaults. For example, |
| when checking nullness (\chapterpageref{nullness-checker}), the default |
| annotation is \<@NonNull>, in most locations other than some type bounds |
| (Section~\ref{climb-to-top}). When you are starting out, it might seem |
| helpful to write redundant annotations as a reminder, but that's like |
| when beginning programmers write a comment about every simple piece of |
| code: |
| |
| \begin{Verbatim} |
| // The below code increments variable i by adding 1 to it. |
| i++; |
| \end{Verbatim} |
| |
| As you become comfortable with pluggable type-checking, you will find |
| redundant annotations to be distracting clutter, so avoid putting them in |
| your code in the first place. |
| |
| \item |
| Avoid writing \<@SuppressWarnings> annotations unless there is no |
| alternative. It is tempting to think that your code is right and the |
| checker's warnings are false positives. Sometimes they are, but slow |
| down and convince yourself of that before you dismiss them. |
| Section~\ref{handling-warnings} discusses what to do when a checker |
| issues a warning about your code. |
| |
| \end{itemize} |
| |
| |
| \subsectionAndLabel{Annotations indicate non-exceptional behavior}{annotate-normal-behavior} |
| |
| You should use annotations to specify \emph{normal} behavior. The |
| annotations indicate all the values that you \emph{want} to flow to a |
| reference --- not every value that might possibly flow there if your |
| program has a bug. |
| |
| |
| \subsubsectionAndLabel{Methods that crash when passed certain values}{annotate-normal-behavior-always-crash} |
| |
| \paragraphAndLabel{Nullness example}{annotate-normal-behavior-nullness-example} |
| As an example, consider the Nullness Checker. Its goal is to guarantee that your |
| program does not crash due to a null value. |
| |
| This method crashes if \<null> is passed to it: |
| |
| \begin{Verbatim} |
| /** @throws NullPointerException if arg is null */ |
| void m1(Object arg) { |
| arg.toString(); |
| ... |
| } |
| \end{Verbatim} |
| |
| \noindent |
| Therefore, the type of \<arg> |
| should be \<@NonNull Object> (which you can write as just \<Object>, because |
| \<@NonNull> is the default). The Nullness Checker (\chapterpageref{nullness-checker}) |
| prevents null pointer exceptions by warning you whenever a client passes a |
| value that might cause \<m1> to crash. |
| |
| Here is another method: |
| |
| \begin{Verbatim} |
| /** @throws NullPointerException if arg is null */ |
| void m2(Object arg) { |
| Objects.requireNonNull(arg); |
| ... |
| } |
| \end{Verbatim} |
| |
| Method \<m2> behaves just like \<m1> in that it throws |
| \<NullPointerException> if a client passes \<null>. Therefore, their |
| specifications should be identical (the argument is \<@NonNull>), so the |
| checker will issue the same warning if a client might pass \<null>. |
| |
| The same argument applies to any method that is guaranteed to throw an exception |
| if it receives \code{null} as an argument. Examples include: |
| |
| \begin{Verbatim} |
| com.google.common.base.Preconditions.checkNotNull(Object) |
| java.lang.Double.valueOf(String) |
| java.lang.Objects.requireNonNull(Object) |
| java.lang.String.contains(CharSequence) |
| org.junit.Assert.assertNotNull(Object) |
| \end{Verbatim} |
| |
| Their formal parameter type is annotated as \<@NonNull>, because otherwise the |
| program might crash. Adding a call to a method like \<requireNonNull> |
| never prevents a crash: your code still crashes, but with a slightly |
| different stack trace. In order to prevent all exceptions in your program |
| caused by null pointers, you need to prevent those thrown by methods including |
| \<requireNonNull>. |
| |
| (One might argue that the formal parameter should be annotated as |
| \refqualclass{checker/nullness/qual}{Nullable} because passing \code{null} has a |
| well-defined semantics (throw an exception) and such an execution may be |
| possible if your program has a bug. However, it is never the programmer's |
| intent for \<null> to flow there. Preventing such bugs is the purpose of |
| the Nullness Checker.) |
| |
| A method like \<requireNonNull> is useless for making your code correct, |
| but it does have a benefit: its stack trace may help developers to track |
| down the bug. (For users, the stack trace is scary, confusing, and usually |
| non-actionable.) But if you are using the Checker Framework, you can |
| prevent errors rather than needing extra help in debugging the ones that |
| occur at run time. |
| |
| |
| \paragraphAndLabel{Optional example}{annotate-normal-behavior-optional-example} |
| Another example is the Optional Checker (\chapterpageref{optional-checker}) |
| and the \sunjavadoc{java.base/java/util/Optional.html\#orElseThrow()}{orElseThrow} method. |
| The goal of the Optional Checker is to ensure that the program does not |
| crash due to use of a non-present Optional value. Therefore, the receiver |
| of |
| \<orElseThrow> is annotated as |
| \refqualclass{checker/optional/qual}{Present}, |
| and the Optional Checker issues a warning if the client calls |
| \<orElseThrow> on a \refqualclass{checker/optional/qual}{MaybePresent} value. |
| |
| |
| \paragraphAndLabel{Permitting crashes in called methods}{annotate-normal-behavior-skip-libraries} |
| You can make a checker ignore crashes in library code (such as |
| \<assertNotNull()>) that occur as a result of misuse by your code. |
| This invalidates the checker's guarantee that your program will not crash. |
| (Programmers and users typically care about all crashes, no matter which |
| method is at the top of the call stack when the exception is thrown.) |
| The checker will still warn you about crashes in your own code. |
| |
| \begin{itemize} |
| \item |
| The \<-AskipUses> command-line argument (Section~\ref{askipuses}) skips |
| checking all method calls to one or more classes. |
| \item |
| A stub file (Section~\ref{stub}) can override the library's annotations, |
| for one or more methods. |
| \item |
| Don't type-check clients of the method. For example, JUnit's |
| \<assertNotNull()> is typically called only in test code; its clients are |
| the tests. If you type-check only your main program, then the annotation |
| on \<assertNotNull()> is irrelevant. |
| \end{itemize} |
| |
| |
| \subsubsectionAndLabel{Methods that sometimes crash when passed certain values}{annotate-normal-behavior-sometimes-crash} |
| |
| %% TODO: This text should be revised when @NullableWhen or @NonNullWhen is implemented. |
| % This is only an issue for code with unchecked, trusted annotations such as |
| % library methods; if the method is type-checked, then the type-checker |
| % warnings will lead you to leave the formal parameter as the default, which |
| % means \<@NonNull>. |
| If a method can \emph{possibly} throw an exception because its parameter |
| is \<null>, then that parameter's type should be \<@NonNull>, which |
| guarantees that the type-checker will issue a warning for every client |
| use that has the potential to cause an exception. Don't write |
| \<@Nullable> on the parameter just because there exist some executions that |
| don't necessarily throw an exception. |
| |
| % (The note at |
| % http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/base/Preconditions.html |
| % argues that the parameter could be marked as @Nullable, since it is |
| % possible for null to flow there at run time. However, since that is an |
| % erroneous case, the annotation would be counterproductive rather than |
| % useful.) |
| |
| |
| \subsectionAndLabel{Subclasses must respect superclass annotations}{annotations-are-a-contract} |
| |
| An annotation indicates a guarantee that a client can depend upon. A subclass |
| is not permitted to \emph{weaken} the contract; for example, |
| if a method accepts \code{null} as an argument, then every overriding |
| definition must also accept \code{null}. |
| A subclass is permitted to \emph{strengthen} the contract; for example, |
| if a method does \emph{not} accept \code{null} as an argument, then an |
| overriding definition is permitted to accept \code{null}. |
| |
| %% TODO: Revise when @NullableWhen or @NonNullWhen is implemented |
| \begin{sloppypar} |
| As a bad example, consider an erroneous \code{@Nullable} annotation in |
| \href{https://github.com/google/guava/blob/master/guava/src/com/google/common/collect/Multiset.java\#L129}{\code{com/google/common/collect/Multiset.java}}: |
| \end{sloppypar} |
| |
| \begin{Verbatim} |
| 101 public interface Multiset<E> extends Collection<E> { |
| ... |
| 122 /** |
| 123 * Adds a number of occurrences of an element to this multiset. |
| ... |
| 129 * @param element the element to add occurrences of; may be {@code null} only |
| 130 * if explicitly allowed by the implementation |
| ... |
| 137 * @throws NullPointerException if {@code element} is null and this |
| 138 * implementation does not permit null elements. Note that if {@code |
| 139 * occurrences} is zero, the implementation may opt to return normally. |
| 140 */ |
| 141 int add(@Nullable E element, int occurrences); |
| \end{Verbatim} |
| |
| There exist implementations of Multiset that permit \code{null} elements, |
| and implementations of Multiset that do not permit \code{null} elements. A |
| client with a variable \code{Multiset ms} does not know which variety of |
| Multiset \code{ms} refers to. However, the \code{@Nullable} annotation |
| promises that \code{ms.add(null, 1)} is permissible. (Recall from |
| Section~\ref{annotate-normal-behavior} that annotations should indicate |
| normal behavior.) |
| |
| If parameter \code{element} on line 141 were to be annotated, the correct |
| annotation would be \code{@NonNull}. Suppose a client has a reference to |
| same Multiset \code{ms}. The only way the client can be sure not to throw an exception is to pass |
| only non-\code{null} elements to \code{ms.add()}. A particular class |
| that implements Multiset could declare \code{add} to take a |
| \code{@Nullable} parameter. That still satisfies the original contract. |
| It strengthens the contract by promising even more: a client with such a |
| reference can pass any non-\code{null} value to \code{add()}, and may also |
| pass \code{null}. |
| |
| \textbf{However}, the best annotation for line 141 is no annotation at all. |
| The reason is that each implementation of the Multiset interface should |
| specify its own nullness properties when it specifies the type parameter |
| for Multiset. For example, two clients could be written as |
| |
| \begin{Verbatim} |
| class MyNullPermittingMultiset implements Multiset<@Nullable Object> { ... } |
| class MyNullProhibitingMultiset implements Multiset<@NonNull Object> { ... } |
| \end{Verbatim} |
| |
| \noindent |
| or, more generally, as |
| |
| \begin{Verbatim} |
| class MyNullPermittingMultiset<E extends @Nullable Object> implements Multiset<E> { ... } |
| class MyNullProhibitingMultiset<E extends @NonNull Object> implements Multiset<E> { ... } |
| \end{Verbatim} |
| |
| Then, the specification is more informative, and the Checker Framework is |
| able to do more precise checking, than if line 141 has an annotation. |
| |
| It is a pleasant feature of the Checker Framework that in many cases, no |
| annotations at all are needed on type parameters such as \code{E} in \<MultiSet>. |
| |
| |
| \subsectionAndLabel{What to do if a checker issues a warning about your code}{handling-warnings} |
| |
| When you run a type-checker on your code, it is likely to issue warnings or |
| errors. Don't panic! |
| If you have trouble understanding a Checker Framework warning message, you |
| can search for its text in this manual. |
| There are three general causes for the warnings: |
| |
| \begin{description} |
| \item[You found a bug] |
| There is a bug in your code, such as a possible null dereference. Fix |
| your code to prevent that crash. |
| |
| \item[Wrong annotations] |
| The annotations are too strong (they are incorrect) or too weak (they |
| are imprecise). Improve the |
| annotations, usually by writing more annotations in order to better |
| express the specification. |
| Only write annotations that accurately describe the intended behavior of |
| the software --- don't write inaccurate annotations just for the purpose |
| of eliminating type-checker warnings. |
| |
| Usually you need to improve the annotations in your source code. |
| Sometimes you need to improve annotations in a library that your program |
| uses (see \chapterpageref{annotating-libraries}). |
| |
| \item[Type-checker weakness] |
| There is a weakness in the type-checker. Your code is safe --- it never |
| suffers the error at run time --- but the checker cannot prove this fact. |
| (The checker is not omniscient, and it works modularly: when type-checking a |
| method \<m>, it relies on the types, but not the code, of variables and |
| methods used by \<m>.) |
| |
| If possible, rewrite your code to be simpler for the checker to analyze; |
| this is likely to make it easier for people to understand, too. |
| If that is not possible, suppress the warning (see |
| \chapterpageref{suppressing-warnings}); be sure to include a code |
| comment explaining how you know the code is correct even though the |
| type-checker cannot deduce that fact. |
| |
| (Do not add an \<if> test that can never fail, just to suppress a |
| warning. Adding a gratuitous \<if> clutters the code and confuses |
| readers. A reader should assume that every \<if> condition can evaluate to true |
| or false. There is one exception to this rule: an \<if> test may have a |
| condition that you think will never evaluate to true, if its body just throws a |
| descriptive error message.) |
| \end{description} |
| |
| For each warning issued by the checker, you need to determine which of the |
| above categories it falls into. Here is an effective methodology to do so. |
| It relies mostly on manual code examination, but you may also find it |
| useful to write test cases for your code or do other kinds of analysis, to |
| verify your reasoning. |
| (Also see |
| Section~\ref{common-problems-typechecking} and |
| Chapter~\ref{troubleshooting}, Troubleshooting. |
| In particular, Section~\ref{common-problems-typechecking} explains this |
| same methodology in different words.) |
| |
| |
| \paragraphAndLabel{Step 1: Explain correctness: write a proof}{handling-warnings-step1} |
| Write an explanation of why your code is correct and it |
| never suffers the error at run time. In other words, this is an informal proof |
| that the type-checker's warning is incorrect. Write it in natural language |
| (e.g., English). |
| |
| Don't skip any steps in your proof. |
| (For example, don't write an unsubstantiated claim such as ``\<x> is |
| non-null here''; instead, give a justification.) |
| Don't let your reasoning rely on |
| facts that you do not write down explicitly. For example, remember that |
| calling a method might change the values of object fields; your proof |
| might need to state that certain methods have no side effects. |
| |
| If you cannot write a proof, then there is a bug |
| in your code (you should fix the bug) or your code is too complex for you |
| to understand (you should improve its documentation and/or design). |
| |
| |
| \paragraphAndLabel{Step 2: Translate the proof into annotations.}{handling-warnings-step2} |
| Here are some examples of the translation. |
| |
| \begin{itemize} |
| \item |
| If your proof includes ``variable \<x> is never \<null> |
| at run time'', then annotate \<x>'s type with |
| \refqualclass{checker/nullness/qual}{NonNull}. |
| \item |
| If your proof |
| includes ``method \<foo> always returns a legal regular expression'', |
| then annotate \<foo>'s return type with |
| \refqualclass{checker/regex/qual}{Regex}. |
| \item |
| If your proof includes ``if method \<join>'s first argument is |
| non-null, then \<join> returns a non-null result'', then annotate |
| \<join>'s first parameter and return type with |
| \refqualclass{checker/nullness/qual}{PolyNull}. |
| \item |
| If your proof includes ``method \<processOptions> has already been called and it |
| set field \<tz1>'', then annotate \<processOptions>'s declaration with |
| \refqualclasswithparams{checker/nullness/qual}{EnsuresNonNull}{"tz1"}. |
| \item |
| If your proof includes ``method \<isEmpty> returned false, so its |
| argument must have been non-null'', then annotate \<isEmpty>'s |
| declaration with |
| \refqualclasswithparams{checker/nullness/qual}{EnsuresNonNullIf}{expression="\#1",result=false}. |
| \item |
| If your proof includes ``method \<m> has no side effects'', |
| then annotate \<m>'s declaration with |
| \refqualclass{dataflow/qual}{SideEffectFree}. |
| \item |
| If your proof includes ``each call to method \<m> returns the same value'', |
| then annotate \<m>'s declaration with |
| \refqualclass{dataflow/qual}{Deterministic}. |
| \end{itemize} |
| |
| All of these are examples of correcting weaknesses in the annotations you wrote. |
| The Checker Framework provides many other powerful annotations; you may |
| be surprised how many proofs you can express in annotations. |
| If you need to annotate a method that is defined in a |
| library that your code uses, see \chapterpageref{annotating-libraries}. |
| |
| Don't omit any parts of your proof. When the Checker Framework analyzes |
| a method, it examines only the specifications (not the implementations) |
| of other methods. |
| |
| If there are complex facts in your proof that cannot be expressed as |
| annotations, then that is a weakness in the type-checker. For example, |
| the Nullness Checker cannot express ``in list \<lst>, elements stored at |
| even indices are always non-\<null>, but elements stored at odd elements |
| might be \<null>.'' In this case, you have two choices. |
| % |
| First, you can suppress the warning |
| (\chapterpageref{suppressing-warnings}); be sure to write a comment |
| explaining your reasoning for suppressing the warning. You may wish to |
| submit a feature request (Section~\ref{reporting-bugs}) asking for |
| annotations that handle your use case. |
| % |
| Second, you can rewrite the code to make the proof simpler; |
| in the above example, it might be better to use a list of pairs |
| rather than a heterogeneous list. |
| |
| \paragraphAndLabel{Step 3: Re-run the checker}{handling-warnings-step3} |
| At this point, all the steps in your proof have been formalized as |
| annotations. Re-run the checker and repeat the process for any new or |
| remaining warnings. |
| |
| If every step of your proof can be expressed in annotations, but the |
| checker cannot make one of the deductions (it cannot follow one of the |
| steps), then that is a weakness in the type-checker. First, double-check |
| your reasoning. Then, suppress the warning, along with a comment |
| explaining your reasoning (\chapterpageref{suppressing-warnings}). |
| The comment is an excerpt from your informal proof, and the proof guides |
| you to the best place to suppress the warning. |
| Please submit a bug report so that the checker can be improved |
| in the future (Section~\ref{reporting-bugs}). |
| |
| |
| |
| |
| \subsectionAndLabel{Calls to unannotated code (legacy libraries)}{unannotated-code} |
| |
| Sometimes, you wish to type-check only part of your program. |
| You might focus on the most mission-critical or error-prone part of your |
| code. When you start to use a checker, you may not wish to annotate |
| your entire program right away. |
| % Not having source code is *not* a reason. |
| You may not have |
| enough knowledge to annotate poorly-documented libraries that your program uses. |
| Or, the code you are annotating may call into unannotated libraries. |
| |
| If annotated code uses unannotated code, then the checker may issue |
| warnings. For example, the Nullness Checker (Chapter~\ref{nullness-checker}) will |
| warn whenever an unannotated method result is used in a non-null context: |
| |
| \begin{Verbatim} |
| @NonNull myvar = unannotated_method(); // WARNING: unannotated_method may return null |
| \end{Verbatim} |
| |
| If the call \emph{can} return null, you should fix the bug in your program by |
| removing the \refqualclass{checker/nullness/qual}{NonNull} annotation in your own program. |
| |
| If the call \emph{never} returns null, you have two choices: annotate the library |
| or suppress warnings. |
| \begin{enumerate} |
| \item To annotate the library: |
| \begin{itemize} |
| \item |
| If the unannotated code is in your program, you can write annotations |
| but not type-check them yet. Two ways to prevent the type-checking are |
| via a \code{@SuppressWarnings} annotation |
| (Section~\ref{suppresswarnings-annotation}) or by not running the |
| checker on that file, for example via the \<-AskipDefs> command-line |
| option (Section~\ref{askipdefs}). |
| \item |
| To annotate a library whose source code you do not have or cannot |
| change, see Chapter~\ref{annotating-libraries}. |
| \end{itemize} |
| \item To suppress all warnings related to uses of |
| \code{unannotated\_method}, use the \code{-AskipUses} command-line option |
| (see Section~\ref{askipuses}). Beware: a carelessly-written regular |
| expression may suppress more warnings than you intend. |
| \end{enumerate} |
| |
| |
| % LocalWords: NonNull zipfile processor classfiles annotationname javac htoc |
| % LocalWords: SuppressWarnings un skipUses java plugins plugin TODO cp io |
| % LocalWords: nonnull langtools sourcepath classpath OpenJDK pre jsr lst |
| % LocalWords: Djsr qual Alint javac's dotequals nullable supertype JLS Papi |
| % LocalWords: deserialization Mahmood Telmo Correa changelog txt nullness ESC |
| % LocalWords: Nullness unselect checkbox unsetting PolyNull typedefs arg |
| % LocalWords: bashrc IDE xml buildfile PolymorphicQualifier enum API elts INF |
| % LocalWords: type-checker proc discoverable Xlint util QualifierDefaults Foo |
| % LocalWords: DefaultQualifier SoyLatte GetStarted Formatter bcel csv sbt |
| % LocalWords: Dcheckers Warski MyClass ProcessorName compareTo toString myDate |
| % LocalWords: int XDTA newdir Awarns signedness urgin bytecodes gradle m1 |
| % LocalWords: subpackages bak tIDE Multiset NullPointerException AskipUses |
| % LocalWords: html JCIP MultiSet Astubs Afilenames Anomsgtext Ashowchecks tex |
| % LocalWords: Aquals processorpath regex RegEx Xmaxwarns com astub jaifs |
| % LocalWords: IntelliJ assertNotNull checkNotNull Goetz antipattern subclassed |
| % LocalWords: callees Xmx unconfuse fenum propkey forName |
| % LocalWords: bootclasspath AonlyUses AskipDefs AonlyDefs AcheckPurityAnnotations |
| % LocalWords: AsuppressWarnings AassumeSideEffectFree Adetailedmsgtext m2 |
| % LocalWords: AignoreRawTypeArguments AsuggestPureMethods ApermitMissingJdk |
| % LocalWords: AassumeAssertionsAreEnabled AassumeAssertionsAreDisabled |
| % LocalWords: AconcurrentSemantics AstubWarnIfNotFound AnoPrintErrorStack |
| % LocalWords: AprintAllQualifiers Aignorejdkastub AstubDebug Aflowdotdir |
| % LocalWords: AresourceStats jls r78 JDKs i18n AignoreRangeOverflow L129 |
| % LocalWords: AinvariantArrays AcheckCastElementType formatter pathname |
| % LocalWords: typedef guieffect Gradle jdk8 javadoc MyFile argfiles tz1 |
| % LocalWords: AshowSuppressWarningsStrings AoutputArgsToFile RegexChecker |
| % LocalWords: NullnessChecker commandlineargfile AnnotatedFor Xmx2500m |
| % LocalWords: AsafeDefaultsForUnannotatedBytecode Signedness Werror jaif |
| % LocalWords: AuseSafeDefaultsForUnannotatedSourceCode beingConstructed |
| % LocalWords: AuseConservativeDefaultsForUncheckedCode AresolveReflection Ainfer |
| % LocalWords: AconservativeUninferredTypeArguments Averbosecfg Acfgviz |
| % LocalWords: AstubWarnIfOverwritesBytecode AprintVerboseGenerics here'' |
| % LocalWords: AatfDoNotCache AatfCacheSize IntRange AwarnIfNotFound ajava |
| % LocalWords: AwarnUnneededSuppressions AshowInferenceSteps BHCJEIBB |
| % LocalWords: AstubWarnIfNotFoundIgnoresClasses processOptions getopt |
| % LocalWords: EnsuresNonNull EnsuresNonNullIf checkername orElseThrow |
| % LocalWords: ArequirePrefixInWarningSuppressions MaybePresent checker'' |
| % LocalWords: AignoreInvalidAnnotationLocations AprintGitProperties |
| % LocalWords: AstubWarnIfRedundantWithBytecode annotation'' AassumePure |
| % LocalWords: AassumeDeterministic stubfilename outputformat AparseAllJdk |
| % LocalWords: AmergeStubsWithSource MyBatis AdumpOnErrors AutoValue |
| % LocalWords: specification'' AwarnUnneededSuppressionsExceptions |
| % LocalWords: requireNonNull |