Thursday, December 23, 2010

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.

No comments: