Skip to content
David Bürgin edited this page Nov 4, 2015 · 38 revisions

Setup

Let's set things up and get started. I'm assuming you have the following ready.

  • Java 8
  • Maven
  • a Unix-like environment -- though give or take some minor adjustments this tutorial should work on Windows, too

Get the code

From this repo.

git clone ...

Now is a good time to check if we're starting out all green. But before we do this let's make a first commit e7ab16a and upgrade to Java 8 . Run the install Maven goal to compile, test, and install the web app locally. Then start the web server

mvn install
mvn tomcat7:run

You should see the 'BUILD SUCCESS' message at some point. Then go to http://localhost:9966/petclinic/ and browse around to get familiar with the app.

This is the Pet clinic.

Hit Control-C to stop the web server, and turn the page for [next chapter].

Install the Checker Framework

No, we're going to do this slightly differently. I like our use of the Checker Framework in this little project to be as unintrusive as possible.

A plain Maven approach it is.

Maven

We're going to do this a bit differently from the suggested installation at Checker Framework: compilation with checking is going to be separate from compilation for production.

The class files produced by the Checker Framework's compiler with annotation processing are different from the class files output by the standard compiler. This may not be an issue depending on your situation. With annotation-heavy frameworks like Spring and Hibernate there is a possibility of friction -- as it is here: I did not manage to run the code produced by the Checker Framework compiler.

Furthermore, it goes without saying that in many professional Java environments compiling with a different compiler is not an option. And if you're trying to convince your colleagues to get into checking, making it optional might actually be a boon.

Annotations

Instead of the Checker Framework's nullness annotations I'm going to use the ones from JSR 305. javax.annotation.Nullable is less powerful than its sibling org.checkerframework.checker.nullness.qual.Nullable though. Only the Checker Framework one supports usage as in List<@Nullable String>.

And of course you might want to try other appetising annotations like @Regex. Don't forget to add the appropriate dependency in your <dependencies> section if you decide to go this route.

Anyway, I'm adding the relevant JAR in the dependencies section in commit 4f7f00c. (Don't worry about the missing <version>, Spring fills that in.)

The checker profile

Now let's create a profile for running the Checker. This is a bit involved, but bear with me. It will pay off in the next chapter.

Add a <profiles> section at the bottom of the POM (pom.xml), right above the final <url> tag.

<profiles>
  <profile>
    <id>checker</id>
    <build>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.3</version>
          <configuration>
            <source>${java.version}</source>
            <target>${java.version}</target>
            <annotationProcessors>
              <annotationProcessor>org.checkerframework.checker.nullness.NullnessChecker</annotationProcessor>
            </annotationProcessors>
            <compilerArgs>
              <arg>-Xbootclasspath/p:${checkerframework.jdk8}</arg>
            </compilerArgs>
          </configuration>
        </plugin>
      </plugins>
    </build>
  </profile>
</profiles>

This is the checker profile. As you can see all this does is hook into the compilation process by adding an annotation processor. The NullnessChecker is the annotation processor that will perform the checking.

The Checker Framework comes with an annotated JDK, and we're putting it on the classpath for the annotation processor. The annotated JDK has all method signatures in the JDK, but annotated with things like @Nullable. The annotated JDK isn't strictly necessary but it does help reduce false positives.

If you know Maven, you'll have noticed that some things are still missing.

...

<properties>
  <checkerframework.jdk8>${org.checkerframework:jdk8:jar}</checkerframework.jdk8>
</properties>

...

<dependencies>
  <dependency>
    <groupId>org.checkerframework</groupId>
    <artifactId>checker</artifactId>
    <version>1.9.7</version>
  </dependency>
  <dependency>
    <groupId>org.checkerframework</groupId>
    <artifactId>jdk8</artifactId>
    <version>1.9.7</version>
    <scope>provided</scope>
  </dependency>
</dependencies>

Clone this wiki locally