-
Notifications
You must be signed in to change notification settings - Fork 5
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
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].
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.
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.
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.)
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>