Mathias Ricken

Mathias Ricken


Home

Bio


CV/Resume


Curriculum Vitae (pdf)
(doc)  (txt)  (embedded)

Resume (pdf)
(doc)  (txt)  (embedded)


Publications


External linkArchive on A Concurrent Affair

RSSPublication RSS Feed


Research Projects


Concutest: A Framework for Testing Concurrent Programs

Mint: Multi-stage Programming for Java

xajavac: Extended Annotations-Enabled javac

LAPT-javac: Local Variable-Enabled javac

DrJava IDE

Programming for Change: The Temperature Calculator

Object-Oriented Design Festival

Design Patterns for Parsing

Assignments for an Objects-First Curriculum

Design Patterns for Marine Biology Simulation

Geometry Synthesis

DrC# IDE

Geometry Synthesis by Analogy

Teaching


External linkCOMP 410 - Software Engineering Methodology

Past Classes

Blog


External linkA Concurrent Affair


External linkMy Academia.edu
External linkPapers
External linkTalks
External linkTeaching

      LAPT-javac: Local Variable Annotation Enabled javac

Note: The JSR 308: Annotations on Java Types project has made a formal proposal available. This has made LAPT-javac obsolete.

The suggested changes in JSR 308 correctly deal with local variable annotations and by far surpasses the capabilities of LAPT-javac.

I suggest that anyone interested in processing local variable annotations implement the model described in the JSR 308 proposal.

Contents

Introduction

Java 5.0 introduced annotations, meta-data that can be attached to other parts of the program. According to the grammar found in the Java Language Specifications, 3rd Edition, annotations may target other annotation types, packages, types, constructors, methods, fields (including enum constants), parameters, and local variables. These annotations may be accessible in the source code only (using the apt Annotation Processing Tool); they may be encoded in the class file but remain invisible at runtime; or they may be accessible at runtime using reflection.

Unfortunately, both javac and apt completely ignore local annotations on local variables. In accordance with the grammar, they do not signal a syntax error, but annotations on local variables are neither accessible in the source or class files nor at runtime! In effect, an annotation on a local variable

void someMethod() {
  // ...
  
  @SomeAnnotation int myLocal = 123;
  
  // ...
}

behaves exactly the same as if it were written like this:

void someMethod() {
  // ...
  
  /* @SomeAnnotation */ int myLocal = 123;
  
  // ...
}

Annotations on local variables are comments, and comments only. They are not meta-data. This has annoyed me ever since I realized it about two years ago, when I first looked at annotations. I immediately thought this was a tremendous shortcoming, creating a huge gap in what could be done with annotations.

The reason Sun gives for not making local variables accessible in the class file or at runtime is that "there was simply no place to put it in the class file". That reason is completely bogus, since Sun introduced several new attributes, like the LocalVariableTypeTable (refer to this PDF, or view embedded) attribute, that provide additional information on local variables in the same version of Java. There is absolutely no reason why apt doesn't process annotations.

My work with the Thread Checker for the testing concurrent programs now virtually requires that local annotations be encoded into class files. It is simply unacceptable to ask the programmer to turn all local variables that require annotations into fields of the enclosing class. I therefore decided to examine the javac source code, released under the Java Research License 1.5, to see if I could implement this feature myself.

To my delight, I found that annotations on local variables were being parsed correctly, and all the information was available all through the very last stage, writing the class files. My change involved only four files (ClassWriter.java, ClassReader.java, Code.java and Name.java) and about 100 lines.

Below, I am making available a modified version of the javac compiler (javac 1.5.0_06) that encodes annotations on local variables in the class file. I also specify the format for two new, non-standard attributes, RuntimeVisibleLocalVariableAnnotations and RuntimeInvisibleLocalVariableAnnotations, on methods and constructors that closely mirror the format of the RuntimeVisibleParameterAnnotations and RuntimeInvisibleParameterAnnotations attributes that Sun introduced with Java 5.0.

The name LAPT-javac stands for "Local Annotation Processing Tool-javac" and is an artifact of the somewhat confused path the development took: I first created a stand-alone tool, LAPT, that was similar to apt, acted as a post-processing stage, and processed both Java source and class files. That program works reasonably well and is available upon request. When I realized that changing javac might be easier, I created a project to mimic what LAPT was already doing, and LAPT-javac was the result.

To use LAPT-javac, download the LAPT-javac binaries in the laptjavac.jar file below and execute it using Java 5.0:

java -jar laptjavac.jar <parameters>

where <parameters> matches the javac command line you would normally use.

Note: Even though I specify a RuntimeVisibleLocalVariableAnnotations attribute and encode annotations on local variable with RUNTIME retention as such, the original Java 5.0 reflection API is not be able to process these annotations, and I do not currently provide a modified reflection API.


Attribute Format Specification

LAPT-javac introduces two new attributes for the class File Format: RuntimeVisibleLocalVariableAnnotations and RuntimeInvisibleLocalVariableAnnotations. For your reference, the following text should be inserted after section 4.8.18 in the yet to be published Java Virtual Machine Specification, 3rd Edition (again, refer to this PDF, or view embedded):

4.8.19. The RuntimeVisibleLocalVariableAnnotations attribute

The RuntimeVisibleParameterAnnotations attribute is a variable length attribute in the attributes table of the method_info structure. The RuntimeVisibleParameterAnnotations attribute records runtime-visible Java programming language annotations on the local variables of the corresponding method. Each method_info structure may contain at most one RuntimeVisibleParameterAnnotations attribute, which records all the runtime-visible Java programming language annotations on the local variables of the corresponding method. The JVM must make these annotations available so they can be returned by the appropriate reflective APIs.

The RuntimeVisibleParameterAnnotations attribute has the following format:

RuntimeVisibleLocalVariableAnnotations_attribute
  u2 attribute_name_index;
  u4 attribute_length;
  u1 num_localVariables;
  {
    u2 variable_name_index;
    u2 num_annotations;
    annotation annotations[num_annotations];
  } local_variable_annotations[localVariables];
}

The items of the RuntimeVisibleLocalVariableAnnotations structure are as follows:

  • attribute_name_index
             The value of the attribute_name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure representing the string "RuntimeVisibleLocalVariableAnnotations".
  • attribute_length
             The value of the attribute_length item indicates the length of the attribute, excluding the initial six bytes. The value of the attribute_length item is thus dependent on the number of annotated local variables, the number of runtime-visible annotations on each local variable, and their values.
  • num_localVariables:
             The value of the num_localVariables item gives the number of local variables that have been annotated, have RUNTIME retention and occur within this attribute.
  • local_variable_annotations:
             Each value of the local_variable_annotations table represents all of the runtime-visible annotations on a single local variable. There are num_localVariables entries in this array. Each local_variable_annotations entry contains the following three items:
    • variable_name_index:
               The value of the variable_name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure representing the name of the local variable.
    • num_annotations:
               The value of the num_annotations item indicates the number of runtime-visible annotations on the local variable with the name specified by variable_name_index.
    • annotations:
               Each value of the annotations table represents a single runtime-visible annotation on the local variable with the name specified by variable_name_index.

     

4.8.20. The RuntimeInvisibleLocalVariableAnnotations attribute

The RuntimeInvisibleLocalVariableAnnotations attribute is similar to the RuntimeVisibleLocalVariableAnnotations attribute, except that the annotations represented by a RuntimeInvisibleLocalVariableAnnotations attribute must not be made available for return by reflective APIs, unless the the JVM has specifically been instructed to retain these annotations via some implementation specific mechanism such as a command line flag. In the absence of such instructions, the JVM ignores this attribute.

The RuntimeInvisibleLocalVariableAnnotations attribute is a variable length attribute in the attributes table of the method_info structure. The RuntimeInvisibleLocalVariableAnnotations attribute records runtime-invisible Java programming language annotations on the local variables of the corresponding method. Each method_info structure may contain at most one RuntimeInvisibleLocalVariableAnnotations attribute, which records all the runtime-invisible Java programming language annotations on the local-variables of the corresponding method.

The RuntimeInvisibleLocalVariableAnnotations attribute has the following format:

RuntimeInvisibleLocalVariableAnnotations_attribute
  u2 attribute_name_index;
  u4 attribute_length;
  u1 num_localVariables;
  {
    u2 variable_name_index;
    u2 num_annotations;
    annotation annotations[num_annotations];
  } local_variable_annotations[localVariables];
}

The items of the RuntimeInvisibleLocalVariableAnnotations structure are as follows:

  • attribute_name_index
             The value of the attribute_name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure representing the string "RuntimeInvisibleLocalVariableAnnotations".
  • attribute_length
             The value of the attribute_length item indicates the length of the attribute, excluding the initial six bytes. The value of the attribute_length item is thus dependent on the number of annotated local variables, the number of runtime-invisible annotations on each local variable, and their values.
  • num_localVariables:
             The value of the num_localVariables item gives the number of local variables that have been annotated, have RUNTIME retention and occur within this attribute.
  • local_variable_annotations:
             Each value of the local_variable_annotations table represents all of the runtime-invisible annotations on a single local variable. There are num_localVariables entries in this array. Each local_variable_annotations entry contains the following three items:
    • variable_name_index:
               The value of the variable_name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure representing the name of the local variable.
    • num_annotations:
               The value of the num_annotations item indicates the number of runtime-invisible annotations on the local variable with the name specified by variable_name_index.
    • annotations:
               Each value of the annotations table represents a single runtime-invisible annotation on the local variable with the name specified by variable_name_index.


Downloads

The binaries and source code to my modified version of javac are available for download here. IMPORTANT: WITH YOUR DOWNLOAD OF THESE FILES, YOU ACCEPT THE JAVA RESEARCH LICENSE 1.5 (review license agreement).


         
http://www.cs.rice.edu/research/laptjavac/index.shtml
Copyright © 2002-2011 by Mathias Ricken. All rights reserved.