Download Document

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Java Annotations for
Invariant Specification
RICE UNIVERSITY
COMPUTER
SCIENCE
Mathias Ricken
September 22, 2008
COMP 617 Seminar
1
Comments are dumb
class HashMap {
// returns null if no mapping for key
Object get(Object key) { … }
}
HashMap m = new HashMap();
Object o = m.get("foo");
String s = o.toString();
NullPointerException at runtime:
o is null
2
Types are smart
class HashMap {
// returns null if no mapping for key
Object|null get(Object key) { … }
}
Compiler Error:
Return type Object|null
HashMap m = new HashMap();
incompatible with type
Object
Object o = m.get("foo");
String s = o.toString();
This is not Java!
3
Annotations can make Java smarter
class HashMap {
// returns null if no mapping for key
@Nullable Object get(Object key) { … }
}
HashMap m = new HashMap();
Compiler Warning:
Return value may be null,
assigned to non-null variable.
Object o = m.get("foo");
String s = o.toString();
Pluggable type systems in Java 5 7?
4
Annotation Targets in Java 5
@A package some.package.name;
@B class MyClass {
@NonNull Object field;
@C MyClass(@NonNull Object param) {
field = param;
}
@NonNull Object method() {
@NonNull Object localVar = field;
return localVar;
}
}
Note:
Local variable annotations are completely ignored.
5
Concurrency Invariants
interface TableModel {
// may only be called from event thread
void setValueAt(…);
}
TableModel m;
// from outside event thread…
m.setValueAt(…);
Possible race condition.
6
Invariant Specification
interface TableModel {
@OnlyEventThread
void setValueAt(…);
}
TableModel m;
// from outside event thread…
m.setValueAt(…);
Invariant Violation Warning at Runtime
(but still possible race condition)
7
Comparison to assert
void setValueAt(…) {
assert (EventQueue.isDispatchThread());
…
Similarity
 Debug mode – disabled in production code
@OnlyEventThread
void setValueAt(…) { … }
8
Annotations are Easier to Find

Javadoc produces invariant index
9
Inherited Invariants
TableModel
Object getValueAt(…)
@OnlyEventThread void setValueAt(…)
Implied
@OnlyEventThread
AbstractTableModel
Object getValueAt(…)
void setValueAt(…)
DefaultTableModel
Object getValueAt(…)
void setValueAt(…)
Implied
@OnlyEventThread
MySpecialTableModel
Object getValueAt(…)
void setValueAt(…)
Implied
@OnlyEventThread
10
Inherited Invariants
@OnlyEventThread TableModel
Object getValueAt(…)
void setValueAt(…)
Implied
@OnlyEventThread
AbstractTableModel
Object getValueAt(…)
void setValueAt(…)
DefaultTableModel
Object getValueAt(…)
void setValueAt(…)
Implied
@OnlyEventThread
Implied
@OnlyEventThread
MySpecialTableModel
Object getValueAt(…)
void setValueAt(…)
Implied
@OnlyEventThread
11
Limited Universality

A few supplied invariant annotations
@OnlyEventThread
@OnlyThreadWithName
@OnlySynchronizedThis

@NotEventThread
@NotThreadWithName
@NotSynchronizedThis
assert can test an arbitrary predicate
assert (someComplexPredicate());
12
Predicate Invariant Annotations
@PredicateLink(value=Predicates.class, method="eval")
public @interface OnlyThreadWithName {
String value;
}
1.
@OnlyThreadWithName("main")
void myMethod() { … }
Return true or false
to indicate violation
3.
2.
Call predicate method and
pass as arguments:
• this (nor null if static)
• data in invariant annotation
public class Predicates {
public static boolean eval(Object this0, String name) {
return Thread.currentThread().getName().
equals(name);
}
}
13
Further Limitation of Annotations

One occurrence of an annotation class per
target
@OnlyThreadWithName("main") // illegal; and is
@OnlyThreadWithName("other") // this "and" or "or"?
void myMethod() { … }

Suggestion
@Or({
@OnlyThreadWithName("main"),
@OnlyThreadWithName("other")
})
void myMethod() { … }
14
Annotation Members
extends OtherAnnotation
not allowed  no subtyping
@interface MyAnnotation {
int
String
Class
SomeEnum
intMember;
stringMember;
classMember;
enumMember;
//
//
//
//
primitives
strings
class literals
enums
// annotions
OnlyThreadWithName annotMember;
// arrays of the above
OnlyThreadWithName[] arrayMember;
}
15
No Annotation Subtyping in Java
@interface Or { OnlyThreadWithName[] value; }
@Or({@OnlyThreadWithName("main"),
@OnlyThreadWithName("other")})
void myMethod() { … } // legal
@Or({@OnlyThreadWithName("main"),
@NotThreadWithName("other")})
void otherMethod() { … } // illegal
No
common supertype for annotations
16
xajavac Modified Compiler
@interface Base {}
@interface OnlyThreadWithName extends Base {
String value;
}
@interface NotThreadWithName extends Base {
String value;
}
@interface Or extends Base {
Base[] value;
}
17
Results

Annotations with Subtyping
 Minimal
changes to the compiler
 No changes to class file format
 Reduced invariant checker by ~1500 lines
 Improved code reuse
18
Results

Invariant Annotations
 Annotated
part of Swing and DrJava
 Discovered and fixed some bugs in DrJava
 Hard to do retroactively and without inside
knowledge
19
Future Work

Reflection library for annotations with
subtyping
 Annotation
getAnnotation(Class c)
currently returns the annotation of class c
 Annotation[]
getAnnotations(Class c)
should be added to return all annotations of
class c and its subclasses

Modify JSR 308 prototype compiler to
support subtyping
20
More Information and Download

Invariant Specification
 http://www.concutest.org/tc/

Annotations with Subtyping
 http://www.cs.rice.edu/~mgricken/research/xajavac/