Invariant Specification and Multi-Staging using Java Annotations
Poster
Java annotations allow programmers to attach metadata to programs. During normal execution, the annotations are ignored, but in contrast to comments in the source code, annotations can be manipulated programmatically at compile- or run-time. We propose two extensions -- subtyping and expression annotations -- for consideration in the Java specification request for annotations, and show how annotations can be used to express program invariants and multi-stage programs.
- 58 Views
Invariant Specification and Multi-Staging using Java Annotations
Java Annotations
Attach meta-data to program constructs Data about the program, not data in the program Formerly often specified as comments Can now be checked and processed automatically Avoids parsing of source code or strings Annotations act as “smart comments” Annotations are product types (“structs”) composed of constants primitives (int, double, etc.) enums strings class constants (Integer.class) other annotations arrays of the above @interface OnlyRunByThread { String value; } @interface NonNull { } @OnlyRunByThread(”main”) class MyClass { @NonNull Object field; MyClass(@NonNull Object param) { field = param; } @NonNull Object method() { @NonNull Object localVar = field; return localVar; } }
Corky Cartwright Mathias Ricken Walid Taha
// annotation definition // string member // “marker” annotation def. // class annotation // field annotation // parameter annotation // method annotation // local variable annotation
Subtyping
Invariant Specification
Program invariants can be encoded as annotations and checked automatically Similar to assert statements, but inherited into subclasses Generates log file instead of terminating program Simple generation of invariant index using Javadoc tool
Annotations in Java do not have a common supertype Cannot define an annotation that can contain ANY other annotation Added subtyping for annotations to Java Minimal changes to compiler, no changes to class file format Minor changes to reflection API to support additional features Integrates well with existing code Improves @DefaultQualifier annotation, which currently uses a string
interface TableModel { // invariant: must be called from within event thread @OnlyEventThread void setValueAt(...); } class MyTableModel implements TableModel { void setValueAt(...) { /* invariant automatically inherited */ } } // from outside event thread... TableModel m = new MyTableModel(...); m.setValueAt(...); // invariant violation, generates log entry
// former way to specify more than one default qualifier @interface DefaultQualifier { String value; } @interface DefaultQualifiers { DefaultQualifier[] value; } @interface NonNull { } @interface Interned { } @DefaultQualifiers({@DefaultQualifier(”NonNull”), // use of strings! @DefaultQualifier(”Interned”)}) class MyClass { ... } // specifying more than one default qualifier with subtyping @interface Annotation { } @interface DefaultQualifier { Annotation[] value; } @interface NonNull extends Annotation { } // subtyping @interface Interned extends Annotation { } // subtyping @DefaultQualifier({@NonNull, @Interned}} class MyClass { ... }
Multi-Staging
Multi-stage programming (MSP) is a paradigm for developing generic software witout paying a runtime penalty for this generality “Staging” moves computations into a code generation step before runtime Genericly written code (e.g. power) is optimized for special cases (e.g. square) Use annotations to mark how expressions and statements should be staged @Code code to be generated (.. in MetaOCaml, ”brackets”) @Escape code to be spliced together (.~x in MetaOCaml) @Run run generated code (.!x in MetaOCaml) Staging annotations can be ignored to yield unstaged program // staged power function in Java @Code double power(@Code double x, int n) { if (n==0) return @Code (1.0); else return @Code (@Escape (x) * @Escape (power(x, n-1))); } double square(double x) { return @Run (power(@Code (x), 2)); } let rec power (x, n) = (* staged power function in MetaOCaml *) match n with 0 -> .<1>. | n -> .<.~x * .~(power (x, n-1))>.;; let square = .! . .~(power (.., 2))>.;;
Additional Targets
Annotations in Java cannot be attached to statements or expressions Allow additional targets for annotations block statements parenthetical expressions @Contained { // block annotation // block of code that does not spawn async. tasks (”contained”) } int i = -5; int j = @AlwaysPositive (i*i); // paren. expression annotation
Readers

Like (1)
Add Comment