JSR 308 Prototype Implementation README

Version 0.7.2 (26 Jun 2008)

For the latest version, see the JSR 308 webpage.

Contents:

Introduction

(If you are impatient, you can skip to the installation instructions.)

The JSR 308 “prototype implementation” (also called the “reference implementation”) is a version of the OpenJDK Java 7 “langtools” that have been updated to support JSR 308. JSR 308 is a backward-compatible extension of the Java language that permits annotations to appear on types.

You may use the JSR 308 implementation as a replacement for the OpenJDK or any other Java implementation. In particular, you may use the JSR 308 javac compiler as a drop-in replacement for the OpenJDK javac compiler or any other compiler for the Java 7 language.

JSR 308 makes it possible to create compiler plug-ins that check user-defined type qualifiers. The Checkers Framework makes such plug-ins easy to create, and it includes several example type qualifiers that you can start using right away.

The “Installing the JSR 308 compiler” section below contains instructions for installing, running, and testing the compiler.

IDEs such as Eclipse have not yet been updated to support JSR 308. To use the JSR 308 compiler with Eclipse, write an Ant buildfile that compiles your project (using the JSR 308 compiler), then build by running Ant. Problem markers will show up in the Eclipse IDE as normal. (You will lose a few Eclipse features, such as error checking as you type, until Eclipse's internal compiler is updated for JSR 308.)

Features of the JSR 308 prototype implementation

The JSR 308 prototype implementation is a Java compiler that supports the JSR 308 specification (PDF, HTML), which permits annotations to appear on any occurrence of a type.

The -typeprocessor javac command-line option

Note: In versions of the JSR 308 compiler 0.4 and following, the -typeprocessor option is no longer needed. It has been retained in 0.4 for backward compatibility, but it will be removed in a future release. For versions 0.4 and following, the -processor option may be used for all annotation processors, including type-checking plug-ins.

The JSR 308 compiler adds the -typeprocessor command-line option for running annotation processors. The -typeprocessor option is semantically similar to the standard -processor option: either option is followed by a list of the (fully-qualified) class names of the annotation processors to run. An example (using the Nullness checker) is:

  javac -typeprocessor checkers.nonnull.NonnullChecker MyFile.java

Annotation processors specified using the -typeprocessor option are invoked after the compiler's attribution phase (also known as type resolution), giving the processor access to completed symbols. By contrast, processors specified using the -processor option are invoked before the compiler's attribution phase.

Note: In the prototype implementation prior to version 0.4, the -typeprocessor and -processor options are mutually exclusive and should not be used simultaneously.

Writing annotations in comments for backward compatibility

The prototype implementation of the JSR 308 compiler allows annotations to be written in “/* */“ (C-style) comments, for example:

  List</*@NonNull*/ String> strings;

There must be no whitespace between the comment delimiters and the annotation name.

This mechanism allows developers to use JSR 308 annotations while maintaining the ability to compile their code with an unmodified Java compiler, including compilers for earlier versions of the Java language (such as Java 4, Java 5, or Java 6).

This temporary mechanism will not be part of the official Java language when JSR 308 is incorporated into it. It may or may not continue to be supported by the javac compiler.

The JSR 308 compiler does not (yet) read import statements that appear in comments, such as

/*import checkers.quals.*;*/

Because any import statement must appear uncommented, you may need to include one or more qualifier definitions (@interface declarations) on your classpath when compiling your code using a Java 4/5/6 compiler.

The -annotations javap command-line option

The JSR 308 javap tool adds the -annotations command-line option for displaying the properties of both JSR 175 and JSR 308 annotations. The OpenJDK javap tool normally displays annotations as raw hexadecimal strings; the modified tool parses annotations and displays their names, arguments, and other properties (including the internal fields of JSR 308 annotations as specified in Section 4 of the JSR 308 proposal).

Since annotation attributes are typically only displayed in conjunction with the -verbose command-line option, the -annotations option does nothing without the -verbose option.

Differences from the JSR 308 proposal

The JSR 308 prototype compiler implementation differs from the design specified in the JSR 308 proposal in the following ways, which will be corrected in the future:

Installing the JSR 308 compiler (“langtools”)

Use the following instructions to install the JSR 308 compiler.

Note that while these instructions install the JSR 308 compiler, you do not have to make the JSR 308 compiler your default compiler. For example, you could use the JSR 308 compiler only for running pluggable type-checkers. Also, you can use javac's -target argument to generate bytecodes that are compatible with earlier JVMs, so that you can work seamlessly with colleagues who are using an earlier version of Java.

If you use an Apple Macintosh computer, you must build the compiler from source.

The short instructions (for Linux only)

The following commands install the JSR 308 javac compiler and the Checker Framework, or update an existing installation. It currently works only on Linux, and is experimental. For more details, or if anything goes wrong, see the comments in the Makefile-jsr308-install file.

  1. Execute the following commands:
      cd
      wget -nv -N http://groups.csail.mit.edu/pag/jsr308/current/Makefile-jsr308-install
      make -f Makefile-jsr308-install
    
  2. Set some environment variables according to the instructions at the top of file ~/Makefile-jsr308-install.

The longer instructions

Requirements: These instructions assume that Ant is installed. If you use an Apple Macintosh computer, you must build the compiler from source.

  1. Install a new copy of OpenJDK. This new installation will be modified later (but no other copy of OpenJDK will be modified). You can put the new installation anywhere you want; a common place is in a new directory ~/jsr308.
    1. Download a JDK 7 binary snapshot: self-extracting JDK file (choose JDK, not JRE or DEBUG, and choose a binary, not a source distribution).
    2. Follow the installation instructions — essentially, just run the .exe, .sh, or .bin file that you downloaded and follow the directions.
      • Note for Linux users: After installing, set your JAVA_HOME environment variable to the top-level directory of the JDK 7 installation /path/to/jdk1.7.0, and augment your PATH with /path/to/jdk1.7.0/bin. Example:
        export JAVA_HOME=$HOME/jsr308/jdk1.7.0
        export PATH=$JAVA_HOME/bin:$PATH
        
        The shell uses the PATH variable to locate java, while Ant uses JAVA_HOME.
    3. Verify that your installation is correct: run javac -version, and the output should be javac 1.7.0-ea.
  2. Download the JSR 308 prototype implementation, and unpack it to create a langtools directory. Do not do this inside the JDK 7 installation (directory jdk1.7.0) that you downloaded in the preceding step. Example commands:
    cd ~/jsr308
    wget http://groups.csail.mit.edu/pag/jsr308/current/jsr308-langtools.zip
    unzip jsr308-langtools.zip
    
  3. Ensure that the JAVA_HOME environment variable points to the JDK you wish to patch, then patch your JDK 7 installation by running:
    cd langtools/binary
    ant install
    This step makes a backup copy of tools.jar and then modifies the original.

    (You shouldn't need to undo this step, but you can do so by running ant uninstall which puts back the original version of the tools.jar file.)

  4. Run
    javac -version
    
    and confirm that the output contains the string jsr308, such as javac 1.7.0-jsr308-0.6.2.
    If the output is does not contain jsr308 (e.g., javac 1.7.0-ea), but you are using the correct javac binary (in langtools/dist/bin), then it is possible that tools.jar is on your classpath. You should either remove tools.jar from your classpath, or else put langtools/dist/lib/javac.jar and/or langtools/dist/lib/javap.jar on your classpath before tools.jar.

When updating to a newer version of the JSR 308 compiler, you only have to follow steps 2, 3, and 4. In other words, you only have to redo step 1 if you want a newer version of OpenJDK.

Building the JSR 308 compiler from source

To build the JSR 308 compiler from source, replace step 3 from above by the following. Building from source is useful mainly for people who are developing compiler plug-ins or modifying the compiler itself. If you only want to use the compiler and plug-ins, it is sufficient to install the pre-compiled version.

Requirements: These instructions assume that Ant (version 1.7 or later) and JDK 6 are installed. You will use JDK 6 to compile OpenJDK, but will not use it thereafter. You can get JDK 6 from Sun or elsewhere. If you use an Apple Macintosh, then depending on your hardware and operating system, you can either use Apple's implementation or SoyLatte.

  1. Create a file ~/.openjdk/build.properties containing the following text, but replace /path/to/java/jdk by the location of your JDK 6 installation.
    boot.java.home = /path/to/java/jdk
    target.java.home = ${boot.java.home}
    
  2. Compile the JSR 308 javac compiler and the javap tool, from directory langtools/make:
    cd langtools/make
    ant clean build-javac build-javap
  3. Add the langtools/dist/bin directory to the front of your PATH environment variable.

The effect of the above commands is that the javac command invokes the JSR 308 Java compiler and the javap command invokes the JSR 308 javap, but the Java 7 OpenJDK is used for everything else.

Differences from the OpenJDK distribution

The JSR 308 distribution includes only the langtools portion of the OpenJDK distribution. The JSR 308 prototype implementation makes no modifications in other parts of the OpenJDK distribution, and the remaining parts of the distribution are not necessary to build and use the JSR 308 tools.

This JSR 308 distribution differs from the langtools portion of Sun's OpenJDK distribution in the following ways:

Additionally, your javac will not properly pass -J<flag> flags to the runtime system. This is a problem with the OpenJDK system, not with the JSR 308 changes. If you wish to adjust the arguments to the runtime system (i.e., java), then you will need to edit langtools/dist/bin/javac.

Determining a diff against the OpenJDK distribution

The JSR 308 distribution is a modification of the langtools portion of Sun's OpenJDK javac distribution. The version of OpenJDK on which the JSR 308 distribution is based is:

52 (20 June 2008)

The following commands determine the differences between the JSR 308 compiler and the OpenJDK compiler. The shell variable $VENDOR refers to the location of the unmodified source code and $JSR308 refers to the location of the extracted JSR 308 compiler distribution.

  1. If you do not have a checkout of the OpenJDK compiler, obtain one:
    
      export VENDOR=vendor-langtools
      hg clone -r52 http://hg.openjdk.java.net/jdk7/jdk7/langtools $VENDOR
      

    If you already have a checkout of the OpenJDK compiler, ensure that it is at the same revision as the modifications, using the following command in the $VENDOR directory:

    
      hg pull -r52
      
  2. Use one of these diff commands to generate the differences. The second shows the contents of new files, whereas the first only reports that the new file exists.
    
      diff -ur -x .hg -x dist -x build $VENDOR/src $JSR308/j2se/src
      diff -urN -x .hg -x dist -x build $VENDOR/src $JSR308/j2se/src
      

Contributing

We welcome bug fixes, new features, type-checking plug-ins, and other improvements. All contributions to javac (annotation-related or not) should follow the guidelines for contributing to javac. Any code contributed to javac or to the JSR 308 prototype implementation is contributed to Sun under Sun's Contributor Agreement (SCA).

How to report bugs

If you have any problems with the compiler, please let us know; we welcome bug reports and suggestions. We will fix all reported bugs in the JSR 308 prototype implementation. Examples of bugs include:

The JSR 308 compiler is built on Sun's OpenJDK compiler. If you find a bug in the JSR 308 compiler, it might be due to a bug in the OpenJDK compiler (in which case it should be reported to Sun), or it might be due to the JSR 308 modifications (in which case it should be reported to the JSR 308 compiler implementers). In some cases (such as a problem with processing annotations on types), the responsibility is clearly with the JSR 308 modifications. Otherwise, please determine who is responsible for the bug using this procedure:

  1. Obtain a copy of Mercurial reversion 52 of the OpenJDK compiler, using the commands in the diff section of this document.
  2. Try your test case using the OpenJDK compiler. If the problem is present, then search the bug database (use the “Java” category). If the problem is not in the bug database, then report your bug to Sun, using category “Java” and subcategory “compiler”.

If the problem is present in the JSR 308 compiler, but not in the OpenJDK compiler, then please report it to us. Send your bug report to jsr308-bugs@lists.csail.mit.edu. This is not a mailing list for general support or questions.

Please ensure that your bug report is clear and that it is complete. Otherwise, we may be unable to understand it or to reproduce it, either of which would prevent us from fixing the bug. Sun has a description of how to write a helpful bug report. Here are some crucial points:

Credits and changelog

The JSR 308 compiler was implemented by Matthew M. Papi as a modification of the Sun OpenJDK compiler. See above for how to report bugs.

Differences from previous versions of the JSR 308 implementation may be found in the changelog.


JSR 308 webpage