Thursday, December 23, 2010

Getting JSR 308 Type Annotations Compiler working under Maven

Carrying on with the JSR 308 Type Annotations compiler, the instructions are out of date for Maven too.
I finally got it working after a fashion. I think the plugin is irredeemably about of date without editing it and recompiling. Hopefully this will get done at some point in the future, but until then I got it working by making the following changes.
Firstly, the groupId has changed to types.checkers in the repository, so the dependencies should be:


<dependency>
<groupid>types.checkers</groupid>
<artifactid>checkers-quals</artifactid>
<version>1.1.1</version>
</dependency>
Next as the plugin is broken you need to put an explicit link to the jsr308-all.jar location (which isn't very maven-like, but works).


<build>
<plugins>
<plugin>
<groupid>org.apache.maven.plugins</groupid>
<artifactid>maven-compiler-plugin</artifactid>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<fork>true</fork>
<executable>C:\Program Files\Java\jdk1.7.0\bin\javac.exe</executable>
<compilerargument>-Xbootclasspath/p:C:\Projects\units\checker-framework\checkers\binary\jsr308-all.jar</compilerargument>
<compilerarguments>
<processor>checkers.nullness.NullnessChecker</processor>
</compilerarguments>
</configuration>
</plugin>
</plugins>
</build>

JSR308 Type Annotations Compiler working in IntelliJ IDEA 10

I struggled to get IntelliJ IDEA 10 working with JSR-308 type annotations. The instructions at Jetbrains and at the JSR site were both out of date. I've reported the problem to Jetbrains (as a comment on that post) and to the JSR 308 team but while they work on it here is a workaround I've found.

By the way, if Java 8 is out, that will include type annotations and this post will be obselete.

The alternation proceeds in two stages - first modifying the compiler, and secondly enabling the annotations processor you are going to use.

Modifying the compiler

  1. Download the checkers framework as described in step 1 of the installation here.
  2. Unzip it. For the sake of this post I'll assume you are on Windows and you unzipped it to c:/checker-framework
  3. Install an OpenJDK 7 that you are willing to alter for type annotations. Download from here. I'll assume you install it to C:\Program Files\Java\jdk1.7.0
  4. In C:\Program Files\Java\jdk1.7.0\lib\ rename tools.jar to oldtools.jar (so you have it around in case you want to use it again).
  5. Copy C:\checker-framework\checkers\binary\jsr308-all.jar to C:\Program Files\Java\jdk1.7.0\lib\tools.jar

Enabling the Annotations Processor


In this case we are going to enable to nullness annotations processor, from the checkers framework. If you write your own, replace the jsr308-all.jar with your own processor.
  1. Open your IntelliJ project you want to use Annotations.
  2. Go to Project Structure, Project, and select the JDK 7 you just installed.
  3. Set language level to 8.
  4. Go to Libraries and add the jsr308-all.jar (from C:\checker-framework\checkers\binary)
  5. Go to Project Settings, Annotation Processors and tick Enable annotation processing
  6. Under Annotation Processors click Add, and add checkers.nullness.NullnessChecker
That should be it! Try compiling the following code, you should get "Error: (5, 31) incompatible types".



import checkers.nullness.quals.*;

public class GetStarted {
void sample() {
@NonNull Object ref = null;
}
}



It's all a bit complicated, but I'm sure Jetbrains will have it working in a much easier fashion soon - I thoroughly recommend IntelliJ IDEA.