X

Musings on JDK development

JDK 6 Build 101 JSR 269 API Changes

There haven't been any API changes in JSR 269 since href="http://blogs.sun.com/darcy/entry/jdk_6_build_97_jsr">build
98 and the href="http://jcp.org/aboutJava/communityprocess/pfd/jsr269/index.html">proposed
final draft; however, build 101 includes a sample annotation
processor showing how the API can be used to check program structure.

The sample file is under

sample/javac/processing/src/CheckNameProcessor.java

from the root JDK installation directory.

As the name suggests, this processor checks that the source being
processed follows the naming conventions discussed in the language
specification. This name checking is meant to be representative of a
class of properties that could be checked for at build time by
annotation processors.

A few stylistic points to note in the sample:

  • Extending AbstractProcessor:
    The AbstractProcessor class is provided to make writing
    annotation processors more convenient by eliminating repeated
    boilerplate code. Generally, the results of the
    getSupportedFoo methods can be specified by
    applying a @SupportedFoo annotation to the class.
    The @Override annotations help ensure the methods of the
    class are behaving as expected. To initialize fields for objects that
    will persist for life of the processor object, such as the
    Messager and Filer retrieved from the
    ProcessingEnvironment, assign the fields in the
    overridden init method after super.init has
    been called.
  • Implement functionality with a visitor, but expose the
    functionality with its own entry point:

    The NameChecker class provides a checkNames
    method for clients to pass an element to get its names checked. While
    this checking is implemented using a visitor, exposing that
    implementation detail is not friendly to clients.
  • Have a policy for future language versions:
    The JSR 269 API models the current language, but the language will be
    changing in some future release and annotation processors written
    today could be run against new language constructs of the future. Two
    basic policies are:
    1. Write the processor to only work with the current language
      version.
    2. Write the processor to cope with unknown future constructs.

    The sample processor does the latter. It does this by returning
    SourceVersion.latest rather than a particular version
    constant and by having the visitor's visitUnknown method
    be non-fatal if called. The visitUnknown method will be
    called when encountering a construct newer than the platform version
    the visitor was written to.

For production use, the heuristicallyConstant method
probably needs some tweaking; leave comments detailing any changes you
find useful.

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.