Java Annotations for Class Constraints
Java Annotations for Class Constraints
Properties of Classes
1 Introduction
The term meta-information refers to information about other information. In
the context of programming languages it denotes information about program el-
ements, which in turn represent information about an application domain. Meta-
information on program elements is generally used by runtime environments and
tools.
In Java, numerous examples of proprietary mechanisms to add meta-informa-
tion to programs exist. Examples are tags like @author or @version used by the
Javadoc tool to generate the class documentation. A similar approach is used
by other tools such as XDoclet[1], Commons Attributes[2], JBoss AOP[3], or
SGen[4]. Another example of extensive use of meta-information in Java are the
various XML files in technologies such as Enterprise JavaBeans (EJBs)[5], Java
Data Objects (JDO)[6], or Java Management Extensions (JMX)[7]. This infor-
mation is used to configure the environment in which a class is to be deployed.
Currently, standard mechanisms are emerging to add meta-information to
source code. In C#, [8] meta-information for source code artifacts like classes,
methods, fields, etc. can be specified by means of attributes and in J2SE 5.0
by means of annotations [9]. The Java specification specifies six built-in annota-
tions, how to declare annotation types, how to annotate declarations, and how to
read those annotations later on. In addition to built-in annotations, there is also
support to create and use user-defined annotations. Each annotation is consid-
ered a Java modifier and can be applied to annotate package, type, constructor,
method, field, parameter, and local variable declarations. An annotation has a
type and defines zero or more member-value pairs, each of which associates a
value with a different member of the annotation type. E.g., in the following ex-
ample the declaration of the class CategoryX is annotated with the annotation
@Entity, whose member access is set to AccessType.FIELD, i.e., the container
should access the entity’s state using field access:
J2SE 5.0 annotations will have a fundamental effect on the way we program
in Java. This is indicated by current development efforts on future versions of
standard libraries. Major upcoming Java standards such as EJB 3.0[10], JDO
2.0[11], Java Web Services[12], or JDBC 4.0[13] will heavily rely on annotations.
Further, a specification request exists to develop a set of annotations that apply
across a variety of individual J2SE and J2EE technologies [14]. In the context
of these specifications, annotations will be used for different purposes such as
driving code generation, or supporting configuration. The rationale for the fast
and widespread adoption of annotations is the expectation that their use will
make the development process of components more lightweight and will flatten
the learning curve of the supporting technologies.
However, a fact that is overseen by these efforts is that the use of annotations
often imposes certain implementation restrictions on the decorated program con-
structs. Consider, e.g., the java.lang.Override annotation of Java 5, which can
be used to annotate non-abstract methods to state that they that must be over-
ridden in any subclass. Since java.lang.Override is a built-in annotation the
implied implementation restriction is enforced by the Java compiler.
This is, however, not true for user-defined domain-specific annotations. An
example for such annotations are those that will be part of the EJB 3.0 spec-
ification. In EJB 3.0, beans can be written as Java classes annotated with the
specified EJB annotations. Based on these annotations, the container will gener-
ate the corresponding home and remote interfaces and extract the configuration
information it needs. However, the effect of annotating a bean with, e.g., entity
should go beyond driving the generation of its interfaces and providing config-
uration information to the container. It should also mean that implementation
restrictions implied by the annotation, as explicitly stated in the specification,
should be checked for, just like restrictions implied by built-in annotations are
enforced by the compiler. An example of such a restriction on an entity bean is:
”An enterprise bean must not use thread synchronization primitives...”.
Using Annotations to Check Structural Properties of Classes 239
1
A prototype of the tool, including the checkers, is available as an Eclipse plug-
in and can be downloaded from http://www.st.informatik.tu-darmstadt.de/
pages/projects/Magellan.
240 M. Eichberg, T. Schäfer, and M. Mezini
The XML representation of this class, generated by BAT2 XML, is shown in list-
ing 1.2 from line 6 to line 28.2 The class itself is represented by the class element
in line 6, while the method (line 16) is represented by a method element, and a
field by a corresponding element (line 14). The attributes of these elements are
self-explaining and define the properties of the declarations. The implementa-
tion of the method is shown in line 22 - 25; the field read access (categoryId)
is represented by the get element (line 23).
1 <db:all>
2 <db:document type=”source”
3 documentID=”file:/[PATH]/xpetstore/domain/catalog/ejb/Category.class”
4 tag=”de.tud.xirc.processor.input.ClassFileInputProcessor” >
5
6 <class
7 name=”xpetstore.domain.catalog.ejb.Category” visibility =”public” ... >
8 <annotations> <runtime visible>
9 <annotation type=”javax.ejb.Entity”/>
10 </ runtime visible > </annotations>
11 < inherits > <class name=”java.lang.Object”/>
12 <interface name=”java.io.Serializable”/> </inherits>
13
14 <field type=”java.lang.Long” name=”categoryId” visibility=”private” .../ >
15
16 <method name=”getCategoryId” visibility=”public” ...>
17 <annotations> <runtime visible>
18 <annotation type=”javax.ejb.Id”/>
19 </ runtime visible > </annotations>
20 <signature> <returns type=”java.lang.Long”/> </signature>
21 <code>
22 <load index=”0” />
23 <get declaringClassName=”xpetstore.domain.catalog.ejb.Category”
24 fieldName=”categoryId” type=”java.lang.Long” />
25 <return />
26 </code>
27 </method>
28 </class>
29 </db:document>
30 </db:all>
Listing 1.2. XML representation of the byte code of the Category class in the database
The db:all element (line 1) is the root element of the database and the
db:document element (line 2 - 4) is used to structure all documents in the
2
The compiler generated default constructor is omitted for brevity.
242 M. Eichberg, T. Schäfer, and M. Mezini
database. Its attributes define necessary information that are required for main-
taining the database (line 3) and to enable further processing of query results
(line 4).
except that the result is again a sequence in document order, if required. The last
relevant feature of XQuery is its notion of a function definition. For illustration,
the function directSupertypes is shown below, which, being passed a set of
class definitions, returns the classes that are directly inherited.
1 let $ebs := $xirc : project − files / class [./ annotations//@type =”javax.ejb. Entity ”]
2 return $ebs[ @final = ”true”] union $ebs/method[@final =”true”]
The queries discussed so far could also be implemented using Java reflection,
though the corresponding Java implementation would be harder to read and
244 M. Eichberg, T. Schäfer, and M. Mezini
would require more effort: Explicit iteration over all classes and methods and
checking each class’ and method’s modifiers. Fully checking the following restric-
tion is no longer possible using Java Reflection because it requires information
about a method’s implementation, which is not exposed by Java Reflection. The
EJB 2.1 specification (which is referenced by EJB 3.0) states in section 25.1.2
[Programming Restrictions]:
An enterprise bean must not use thread synchronization primitives to
synchronize execution of multiple instances.
The following query checks that (a) no method is synchronized (line 2), that (b)
synchronize is not used (line 3) - using Java’s synchronize statement manifests
in monitorenter and monitorexist instructions at Java bytecode level -, and
that (c) none of the wait or notify methods is called (line 4 - 7).
The queries discussed so far are self-containing, i.e. the queries can be executed
as is against the database. However, during the development of the EJB 3.0
checkers we realized that many queries have identical parts. E.g., the queries to
check an entity bean’s implementation restriction nearly always started with a
path expression to determine all classes that are entity beans:
let $ebs := $xirc : project − files / class [./ annotations//@type =”javax.ejb. Entity ”]
4 Architecture
As mentioned before, our tool is based upon Magellan [15], an open, cross-
artifact information engineering platform integrated into the Eclipse IDE. Mag-
ellan provides the following services. Documents (in particular Java class files)
are converted into corresponding XML-based representations and stored into a
database. Changes to documents are tracked to keep the internal database up
to date. In addition, a basic query facility is provided. When a client executes
an XQuery query the corresponding XML nodes are returned as the result.
To check implementation restrictions our tool (XIRC) builds upon the Mag-
ellan platform and uses the provided services. For increased usability, XIRC is
also developed as an Eclipse plug-in; however, the concept is also applicable
to any other front-end, e.g., an integration with ANT. A user can enable the
checking functionality on a project basis. If checking is enabled, the tool then
creates special folders for managing the queries. Besides creating new query def-
initions in those folders and dropping existing query definitions in them it is also
possible to include predefined checkers from a third party plug-in. This enables
cost-effective reuse of checkers for common tasks, e.g., the checkers for EJB 3.0
are available as such a plug-in. Checking is triggered any time a resource, i.e.
a Java class file or a checker, changes. Immediately after a change the Magel-
lan plug-in synchronizes the database as discussed. Next, all queries found in the
folder structure or provided by a plug-in are evaluated. The results of each query
are passed to a special handler that is responsible for processing the resulting
XML nodes. In this case, the handler maps the nodes back to the corresponding
locations in the source code (e.g., to a class / method / field declaration or to a
246 M. Eichberg, T. Schäfer, and M. Mezini
line number in the source code). Additional information defined along with the
query, such as the severity of the restriction or a problem description, are used
to inform the developer about the broken restriction (see Figure 1).
Figure 1 shows an example of the results from multiple queries. In the lower
half of it the standard problem view of Eclipse is shown with multiple violated
restrictions for class CategoryX. The developer can see the severity, a description
and the location where the violation occurs. ¿From the second last entry in the
problems view it can be seen that it is possible to navigate to the corresponding
location in the source code by selecting an entry.
5 Evaluation
Before we will discuss the performance, we first discuss the effort necessary when
developing new checkers. We made the experience that the biggest effort when
writing queries is to learn to use XQuery. The effort was not to understand
the XML representation generated by BAT2 XML. This is probably due to the
fact that most checkers do not require sophisticated control-flow or data-flow
analysis and that it is sufficient to simply take a look at the XML representation
of a class to write the query. A detailed knowledge of the execution semantics of
bytecode instructions is not necessary. Hence, we expect that developers familiar
with XQuery and Java can immediately start writing queries to check structural
Using Annotations to Check Structural Properties of Classes 247
properties and that those checks can be written in a reasonable amount of time,
that is implementing and testing a query requires less than an hour.
To assess the potential, performance, and memory consumption of our ap-
proach we have developed a full set of queries to check the constraints defined
in the EJB 3.0 draft specification[10]. The queries were evaluated against a demo
248 M. Eichberg, T. Schäfer, and M. Mezini
release of the xPetstore project[20]4 project that was updated by Bill Burke and
Gavin King for EJB 3.0.
The following measurements were taken on an Intel Celeron 2.40 GHz system
with 504 MB RAM running Windows XP and using J2SE 5.0, Saxon 8.1 and
Eclipse 3.1M2 as the underlying platform. The XML database had 2833 class
entries, which represented all public classes and interfaces of all Java APIs5
delivered with Java 5, except for classes in the javax.swing.* and java.awt.*
packages. Additionally, all necessary JARs to compile the xPetstore project were
included. The evaluation for the original xPetstore project which run without
any error being signaled required 1.97 seconds. To make the evaluation more
realistic, we injected some more or less severe problems into the project code. The
evaluation of all 48 queries against the messed project code generated correctly
53 messages and was executed in 3.56 seconds. In both cases, the time required
by Eclipse to recompile the source file and to update the Magellan database
should be added, which amounts to another 1-2 seconds. To keep the Magellan
database in memory approximately 40 MB are required.
Detailed execution times are shown in Table 1; the table lists the times re-
quired to evaluate the query containers (printed bold) as a whole, as well as
the times required for the evaluation of each context defining query, and the
times for the queries to check the constraints along with a short description of
the checked constraint. Queries that took less than 10 milliseconds to evaluate
are omitted for brevity. The descriptions were shortened; the messages shown to
developers are more detailed.
The result of this preliminary analysis shows that the overhead (less than
five seconds and running in a non-blocking background process), generated by
checking all implementation restrictions, is acceptable for a day-to-day usage.
Further, the evaluation shows that the implementation restrictions defined by
EJB 3.0 can be checked by using a declarative, though functionally complete,
query language; it is not necessary to write the checks as imperative meta-
programs in a “standard programming language” such as Java.
6 Related Work
The purpose of FindBugs[21] is to find bugs or potential bugs in existing projects
based on control and data flow analysis. In contrast to our tool, FindBugs does not
enable to write declarative queries. Instead, to detect a bug a visitor[22] has to be
written that visits the in-memory representation of a class’ bytecode and reports er-
rors and warnings. JLint[23] and JiveLint[24] are further tools to detect bugs, which
are similar in scope and functionality to FindBugs. However, while these tools are
concerned with identifying general bugs that are independent of the usage of spe-
cific frameworks our approach is targeted at identifying specific implementation
restrictions that need to be checked if and only if a specific framework is used.
4
xPetstore-EJB3.0: http://cvs.sourceforge.net/viewcvs.py/jboss/xpetstore-ejb3.0/
5
Classes starting with com.* are irrelevant for the checks and were not included.
Using Annotations to Check Structural Properties of Classes 249
IRC [25] is similar to FindBugs in the respect that a checker also analyses
the in memory representation of a class’ bytecode. But in contrast to FindBugs
a sophisticated framework exists to programmatically construct queries to check
the code. So, while evaluation speed is explicitly targeted by IRC writing a query
still involves writing Java code and requires detailed knowledge of the internal
representation of the byte code. Based on a comparison of the development
of checkers using IRC and our new tool XIRC our experience is that writing,
maintaining and evolving declarative queries on top of an XML representation is
easier and can be done in less time. The development of checkers (for EJB 2.1)
for IRC needed approximately double the time than the development for XIRC;
though, the preconditions were comparable: The students who developed the
checkers had no knowledge about the framework or the byte code representation
in case of IRC and no knowledge about XQuery or the XML representation of
byte code in case of this work.
AspectJ[26] can also be used for constraint checking[27]. However, AspectJ
was not primarily designed to do it and, as we have argued in [25], the possibilities
offered by static pointcuts to detect violations of constraints are too limited to
be useful in general.
PMD[28] is similar to our tool in the respect that it also supports to write
declarative queries by using XPath, which is an important part of the XQuery
language. However, PMD operates on the abstract syntax tree of a program and
its primary goal is to check the style of a program and not the semantics. In
particular, the used abstract syntax tree does not contain resolved type infor-
mation, e.g., the types of the formal parameters of a method are not available
from looking at a method call node in the AST. This makes writing queries that
take type information into relation or that need to span multiple classes tedious
and error-prone. Checkstyle[29] is similar to PMD and suffers from the same
problem.
The idea of Splint[30] is to annotate the source code (ANSI C) to make design
decisions or implementation restrictions explicit. E.g., to annotate a parameter
with @notnull to indicate that the parameter should never be null. Splint will
then perform a static analysis of the code using the annotations and report vi-
olations. Splint is designed as a compiler; extensibility by users was not a goal.
However, it would be an interesting exercise to develop a set of similar Java
annotations and checks that can be used by developers to make implementation
restrictions explicit in their code and which are checked.
ESC/Java2[31] also uses annotations of the Java source code to enable an ex-
tended static analysis. Since ESC/Java is based on theorem proving the evalua-
tion times are very high [32]; on-the-fly evaluation is out of scope.
Acknowledgments
The authors would like to thank Cuma Ali Gencdal, who implemented parts of
the support for annotations in BAT2 XML and most of the queries for EJB 3.0.
References
1. Team, X.: XDoclet: Attribute-Oriented Programming. (http://xdoclet.sourceforge.
net/)
2. Foundation, A.S.: Commons attributes. jakarta.apache.org/commons/attributes/
(2004)
3. Inc., J.: JBoss AOP 1.0 beta3. http://www.jboss.org (2004)
4. Beust, C.: SGen. http://www.beust.com/sgen/ (2004)
5. DeMichiel, L.G.: Enterprise JavaBeans Specification, Version 2.1. SUN Microsys-
tems (2003)
6. Russell, C.: Java Data Objects, Version 1.0. SUN Microsystems (2002)
Using Annotations to Check Structural Properties of Classes 251
7. Sun Microsystems: Java management extensions. White paper, Palo Alto, Cali-
fornia, USA (1999)
8. Archer, T.: Inside C#. Microsoft Press (2001)
9. Bloch, J.: A metadata facility for the java programming language. Java Specifica-
tion Request 175, SUN Microsystems (2002)
10. DeMichiel, L.G.: Enterprise javabeans specification, version 3.0. Java Specification
Request 220 (2003)
11. Russell, C.: Java data objects 2.0 - an extension to the jdo specification. Java
Specification Request 243 (2004)
12. Zotter, B.: Web services metadata for the java platform. Java Specification Request
181 (2004)
13. Bruce, J.: Jdbc 4.0 api specification. Java Specification Request 221 (2004)
14. Mordani, R.: Common annotations for the java platform. Java Specification Re-
quest 250 (2004)
15. Eichberg, M., Mezini, M., Ostermann, K., Schäfer, T.: A kernel for cross-artifact
information engineering in software development environments. In: Proceedings of
11th IEEE Working Conference on Reverse Engineering (WCRE), IEEE Computer
Society (2004) to appear.
16. Eichberg, M.: Battoxml. http://www.st.informatik.tu-darmstadt.de/BAT (2004)
17. Boag, S., Chamberlin, D., Fernández, M.F., Florescu, D., Robie, J., Siméon, J.:
Xquery 1.0: an xml query language. Working Draft 23 Juli 2004, (W3C)
18. Clark, J., DeRose, S.: XML Path Language (XPath) Version 1.0.
(http://www.w3.org/TR/1999/REC-xpath-19991116)
19. Cepa, V., Mezini, M.: Declaring and enforcing dependencies between .net custom
attributes. In: Proceedings of the Third International Conference on Generative
Programming and Component Engineering. (2004)
20. Tchepannou, H., McSweeney, B., Cooley, J.: xPetstore. http://xpetstore.sourceforge.
net (2003)
21. Hovemeyer, D., Pugh, W.: Finding bugs is easy. SIGPLAN Notices December
(2004)
22. Gamma, E., Helm, R., Johnson, R., Vlissides, J.: Design Patterns. Professional
Computing Series. Addison-Wesley (1995)
23. Artho, C.: Finding faults in multi-threaded programs. http://artho.com/jlint/
(2001)
24. Sureshot: JiveLint v1.22. (http://www.sureshotsoftware.com/javalint/)
25. Eichberg, M., Mezini, M., Schäfer, T., Beringer, C., Hamel, K.M.: Enforcing
system-wide properties. In: Proceedings of the 15th australian software engineering
conference (ASWEC), IEEE Computer Society (2004)
26. Kiczales, G., Hilsdale, E., Hugunin, J., Kersten, M., Palm, J., Griswold, W.G.: An
overview of aspectj. In: Proceedings of the 15th european conference on object-
oriented programming (ECOOP). Volume 2072 of Lecture Notes in Computer Sci-
ence., Budapest,Hungary, Springer (2001) 327–355
27. Shomrat, M., Yehudai, A.: Obvious or not? regulating architectural decisions us-
ing aspect-oriented programming. In Kiczales, G., ed.: Proceedings of 1st inter-
national conference on aspect-oriented software development (AOSD), Enschede,
The Netherlands”, ACM Press (2002) 3–9
28. PMD. (http://pmd.sourceforge.net)
29. Kühne, L., Studman, M., Burn, O., Sukhodolsky, O., Giles, R.: Checkstyle.
http://checkstyle.sourceforge.net/ (2004)
252 M. Eichberg, T. Schäfer, and M. Mezini
30. Evans, D., Larochelle, D.: Improving security using extensible lightweight static
analysis. IEEE Software January / February (2002)
31. Cok, D., Kiniry, J.: Esc/java2. http://www.cs.kun.nl/sos/research/escjava/ (2004)
32. Rutar, N., Almazan, C.B., Foster, J.S.: A comparison of bug finding tools for
java. In: 15th IEEE International Symposium on Software Reliability Engineering
(ISSRE’04). (2004) to appear.