Should JSR-305 annotations has classfile or runtime retention?

97 views
Skip to first unread message

Bill Pugh

unread,
Mar 1, 2007, 7:04:26 PM3/1/07
to jsr...@googlegroups.com
Should the annotations developed by JSR-305 have classfile or runtime
retention?

I think we clearly don't want sourcefile retention.

Runtime retention might be useful for some dynamic tools. But a lot
of the dynamic tools
would probably use bytecode writing, and thus still have access to
the annotations.

What do people think?

Bill

Tom Ball

unread,
Mar 2, 2007, 12:05:04 AM3/2/07
to jsr...@googlegroups.com
I strongly lean toward classfile retention -- even if they are not
doing actual bytecode writing, it's still easy to write a classloader
if these annotations are needed. My assumption is that these will be
of most use to tools that are inspecting, but not executing the
classes. Besides, disk space is still a lot cheaper than memory!

Tom

Peter

unread,
Mar 2, 2007, 5:39:57 AM3/2/07
to JSR-305: Annotations for Software Defect Detection
Vote +1 for classfile retention (also this means waste of heap memory)

-Peter

Maxim Shafirov

unread,
Mar 2, 2007, 4:37:03 PM3/2/07
to JSR-305: Annotations for Software Defect Detection
+1 for class file retention.

Jim Hazen

unread,
Apr 1, 2007, 4:55:56 PM4/1/07
to JSR-305: Annotations for Software Defect Detection
+1 for runtime retention.

Feel free to talk me out of this. My gut feeling is that once JSR 305
hits the streets, not only will developers want warnings based on
static code analysis, but that someone somewhere will want to extend
these annotations and provide runtime features. There are times where
it isn't possible to apply many recommended checks, and even if it
were, the only thing to do is raise an exception anyway.

We have Apache Commons lang.Validate (http://jakarta.apache.org/
commons/lang/api-release/org/apache/commons/lang/Validate.html) that
allows developers to manually perform certain error checks. I would
personally like to use JSR-305 to notify others of certain parameter
requirements (param must not be null). However if I get a null value
anyway, I'd like a separate AOP module to apply the null checking
cross-cutting concern, rather than having to sprinkle Validate calls
everywhere.

Sure I could write my own annotations, however how many @NotNull
annotations do we need floating around? One for JPA, one for JSR-305,
one for Apache Commons lang.Validate? I'd vote for more consolidation
of commonly used annotations with domain specific cross-cutting logic
provided by the specific provider. I.e., have a single standard
@NotNull (actual name TBD) annotation, JPA uses it to generate schema
definitions, JSR-305 for static analysis, JavaDoc for improved output,
and someone else for runtime error checking and enforcement.

However, in order to do this, it would mean that the common annotation
would need to have runtime retention, correct?

Maxim Shafirov

unread,
Apr 3, 2007, 10:58:18 AM4/3/07
to JSR-305: Annotations for Software Defect Detection

> However, in order to do this, it would mean that the common annotation
> would need to have runtime retention, correct?

Not quite. This kind of assertion will most probably added by either
bytecode postprocessing (additional compilation phase) or VM agent,
which have classfile annotations available.

Jim Hazen

unread,
Apr 3, 2007, 12:28:42 PM4/3/07
to jsr...@googlegroups.com
Really?  I don't see most users or framework developers pre-compiling or writing an agent.  Rather I see them using the annotations in a similar way to JSR 220, which all have runtime retention.  However I come from a web background so this may just be the hammer I'm used to.  I do like the ability to simply package a framework jar and have everything just work.  Agents need to be configured on the command line don't they?  Can agents be bootstrapped at runtime?  What are the pros/cons of agents vs reflection.  If Agents don't use reflection, how do they work?  I just don't know enough at this point to understand all the potential gotchas.  I do think that the runtime benefits of overloading these annotations should be thought about and the initial reaction on the list seems contrary to mine.

Put another way, why do JSR 220 annotations have runtime retention?

Tom Ball

unread,
Apr 3, 2007, 4:40:10 PM4/3/07
to jsr...@googlegroups.com
Please read the JSR description at
http://www.jcp.org/en/jsr/detail?id=305, and JSR 220 if you haven't
already. The purpose of this JSR is to define standard annotations
for software defection tools, so that developers can add additional
information to make finding defects more accurate. For example,
should a method always, never, or sometimes accept null parameters as
valid? A tool can only infer the intent, while the API providers
(should) know.

Tom

Jonathan Aldrich

unread,
Apr 3, 2007, 10:49:53 PM4/3/07
to JSR-305: Annotations for Software Defect Detection
+1 for runtime retention.

I think classfile retention would be a major mistake; the annotations
should be available at run time. The memory cost for this has got to
be negligible, as it's a per-class cost that's likely a small
percentage of the code size anyway, not a per-object cost--plus an
optimizing JIT could load it into memory on demand if desired.
Premature optimization (e.g. by us, not the JIT) is the root of all
evil!

On the other hand, the benefits of runtime annotations to dynamic
tools would be considerable. Yes, rewriting or class loaders could be
used to get the same information. But by far the simplest solution is
to use the Java reflection libraries to access the annotations, and it
seems foolish to give up the ability to do this and then go through a
lot of work to reconstruct the information at run time.

As an example of the utility of runtime retention, one of my graduate
students developed a simple typestate specification system using Java
annotations, and implemented a checker for it that reads annotations
at run time [1]. The checker could have been implemented as a
bytecode rewriter--and admittedly the checking could have been
optimized more in that case--but the implementation would have been
*much* more difficult. So having this information at runtime will
clearly facilitate research, but also prototyping or lightweight
dynamic analysis tools written in an industrial setting. In general,
I don't think we can anticipate all the uses people will think of for
these annotations, but it's a good bet many will be dynamic and we
should allow for that, especially since the run time cost is
negligible.

Jonathan Aldrich
jonathan...@cs.cmu.edu
http://www.cs.cmu.edu/~aldrich/

[1] Kevin Bierhoff and Jonathan Aldrich. Lightweight Object
Specification with Typestates. FSE 2005. http://www.cs.cmu.edu/~aldrich/papers/fse05.pdf

Tom Ball

unread,
Apr 4, 2007, 11:05:37 AM4/4/07
to jsr...@googlegroups.com
Our goal, as I understand it, is to design a simple, easy to
understand and apply set of annotations which specify design
information to assist error detection tools. Some of these
annotations may be frequently used by diligent engineers, and a
"negligible" cost per annotation can add up in large projects. For
many such diligent engineers, *any* runtime cost is a barrier to their
adoption of technology like this.

As a side note, annotation processing is not a golden hammer to be
applied to all engineering problems (it is perhaps the hammer of the
year). The tool you described sounds like it could have been more
simply designed using aspects; a tool like AspectJ would have handled
all bytecode rewriting transparently.

Tom

Jim Hazen

unread,
Apr 4, 2007, 11:19:31 AM4/4/07
to jsr...@googlegroups.com
For many such diligent engineers, *any* runtime cost is a barrier to their
adoption of technology like this.

Could these engineers not use a bytecode engineering tool themselves to remove any problem annotations from the class files?  If so, why not allow others to innovate in this area?  Standard annotations which specify design information have value beyond just error detection tools.

Dan Kogan

unread,
Apr 4, 2007, 11:57:30 AM4/4/07
to jsr...@googlegroups.com
Tom, very good point.

Besides, a lot of tools do use static analysis to analyze class files.

Dan

Jonathan Aldrich

unread,
Apr 4, 2007, 3:43:57 PM4/4/07
to JSR-305: Annotations for Software Defect Detection

On Apr 4, 11:05 am, "Tom Ball" <tball...@gmail.com> wrote:
> .... Some of these


> annotations may be frequently used by diligent engineers, and a
> "negligible" cost per annotation can add up in large projects.

I think Jim's point is an excellent one here. If anyone really cares
about the runtime costs, it's easy to write a tool that strips
annotations from classfiles. That one tool can be used by anyone who
needs it. However, if we specify that annotations don't persist at run
time, then *everyone* who wants to use those annotations has to write
their own classfile-based tool, instead of using runtime reflection.

> For many such diligent engineers, *any* runtime cost is a barrier to
> their adoption of technology like this.

I don't think we have to cater to irrationality; no true engineer
objects to "any" runtime cost, as the definition of engineering is
making tradeoffs between the costs and benefits of a technology.
Anyone who is using annotations "frequently" clearly sees a major
benefit, and is not going to object to a vanishingly small (or even
zero) cost. Has anyone even measured what this cost is? If there are
objections due to cost, they should be based on data.

But there's no reason why run time retention need have any runtime
cost, for people who do not use the annotations at run time. If the
run-time cost of annotations *ever* gets high enough to get on the
radar of any significant user, it's easy as pie to optimize this in
the JIT. Just don't load the annotations into memory until the user
requests them. Then the cost is zero. Again, we'd be making a big
mistake to prematurely optimize here; the lesson of Java is that it's
worth paying a bit of efficiency to get major software engineering
benefits, and we've seen that JITs can do amazing optimizations when
given the chance.

> As a side note, annotation processing is not a golden hammer to be
> applied to all engineering problems (it is perhaps the hammer of the
> year). The tool you described sounds like it could have been more
> simply designed using aspects; a tool like AspectJ would have handled
> all bytecode rewriting transparently.

The tool I referenced is an error detection tool based on design
intent, but dynamic rather than static. There are good reasons to
support both kinds of checking with this JSR, as they are
complimentary, and there's a number of each kind of tool under
commercial development. We did in fact use aspects to implement our
tool. AspectJ was used to insert generic checks, but the checking code
we inserted used run-time annotation loading to get the (string) data
stored in the annotations to compare it with runtime information.
This made the checker far easier to implement; without runtime
retention we would have had to somehow get the string data from the
annotations statically, and AspectJ doesn't provide a good way to do
this. In our situation dynamic retention for design intent
annotations was a clear win; of course this may vary in other
situations.

There are a ton of other good use cases for dynamic annotations. Think
about loading a module dynamically: you might want a checker that
verifies that the JSR-305 annotations on the interface conform to your
code's expectations. Yes, one could do this in the classloader, but it
would be much easier to introspect the loaded code before running it.

Jonathan

Tom Ball

unread,
Apr 4, 2007, 3:51:27 PM4/4/07
to jsr...@googlegroups.com
I was talking about *users* of these annotations, using them for
projects unrelated to designing defect analysis tools. There are a
lot more potential users of these annotations than authors of tools
that reference them, so our focus should be on minimizing the impact
on the great majority. As a tool developer, I'd rather take the
complexity hit myself than pass it on to my customers.

As for extended value, the name of this JSR is "Annotations for
Software Defect Detection", so that is our focus. While there are a
lot of possible annotations which can improve program specification,
we need to focus in order to deliver something useful before the JDK
gates close again.

Tom

Bill Pugh

unread,
Apr 4, 2007, 4:53:06 PM4/4/07
to jsr...@googlegroups.com
The question I'm not sure about is what is the actual overhead of
making an annotation
be runtime.

I'm sure that that many people have heard of the calculation that the
cost of inlining all the jsrs
was less than the cost of changing the name of the language from oak
to java.

Now, if we don't have any kind of default annotation (as some people
seem to prefer),
we'd probably have a cost of at least one annotation per method.

We default annotations, it would probably be a tenth of that.

What would the cost actually be? Clearly, it should be a per-class
cost, not a per-instance
cost.

What would the cost of one runtime annotation per method be on a
large application?

Anyone want to do a back of the envelope calculation?

Bill

Abe

unread,
Apr 5, 2007, 5:43:23 PM4/5/07
to JSR-305: Annotations for Software Defect Detection
A better question, do we anticipate annotating our annotations with
@Documented? This allows the annotations to appear in JavaDocs. If so,
then we must have a retention policy of Runtime for our annotations.

Dave Griffith

unread,
Apr 6, 2007, 8:13:12 AM4/6/07
to JSR-305: Annotations for Software Defect Detection
How does that follow? There's nothing in the contract of @Documented
that implies anything about retention? All that @Documented does is
put the annotation conceptualy in the public API. It doesn't say
anything about the annotation being accessible by reflection.

Jim Hazen

unread,
Apr 6, 2007, 11:10:43 AM4/6/07
to jsr...@googlegroups.com
It doesn't say anything about the annotation being accessible by reflection.

Aaa.  But it does.  According to the JLS, if an annotation has a meta-annotation with RetentionPolicy.RUNTIME the compiler will make the enclosed annotation available at runtime as well.  @Documented has runtime retention.

JLS (http://java.sun.com/docs/books/jls/third_edition/html/interfaces.html#9.6.1.2):

9.6.1.2 Retention

Annotations may be present only in the source code, or they may be present in the binary form of a class or interface. An annotation that is present in the binary may or may not be available at run-time via the reflective libraries of the Java platform.

The annotation type annotation.Retention is used to choose among the above possibilities. If an annotation a corresponds to a type T, and T has a (meta-)annotation m that corresponds to annotation.Retention, then:

  • If m has an element whose value is annotation.RetentionPolicy.SOURCE, then a Java compiler must ensure that a is not present in the binary representation of the class or interface in which a appears.
  • If m has an element whose value is annotation.RetentionPolicy.CLASS, or annotation.RetentionPolicy.RUNTIME a Java compiler must ensure that a is represented in the binary representation of the class or interface in which a appears, unless m annotates a local variable declaration. An annotation on a local variable declaration is never retained in the binary representation.
If T does not have a (meta-)annotation m that corresponds to annotation.Retention, then a Java compiler must treat T as if it does have such a meta-annotation m with an element whose value is annotation.RetentionPolicy.CLASS.


Discussion

If m has an element whose value is annotation.RetentionPolicy.RUNTIME, the reflective libraries of the Java platform will make a available at run-time as well.

Ciera Christopher

unread,
Apr 6, 2007, 11:26:38 AM4/6/07
to jsr...@googlegroups.com
That's not what it says. It's worded poorly is all.

"If an annotation a corresponds to a type T, and T has a
(meta-)annotation m that corresponds to annotation.Retention"

m is not any meta-annotation. m can only be @Retention. This goes on
to state that if there is no @Retention meta-annotation, the default
is class retention.

~Ciera


--
Ciera Nicole Christopher
Institute for Software Research
Carnegie Mellon University
www.cs.cmu.edu/~cchristo

Jim Hazen

unread,
Apr 6, 2007, 12:16:45 PM4/6/07
to jsr...@googlegroups.com
I may have misread.  Even if annotations don't inherit RetentionPolicy from meta-annotations, @Documented still requires a runtime policy to work.  At least according to this article.  http://www-128.ibm.com/developerworks/library/j-annotate2.html  Someone should just try this out and put the debate to rest.  I'm off to a meeting, perhaps later in the day.

On 4/6/07, Ciera Christopher <ciera.ch...@gmail.com> wrote:

That's not what it says. It's worded poorly is all.

"If an annotation a corresponds to a type T, and T has a
(meta-)annotation m that corresponds to annotation.Retention"

m is not any meta-annotation. m can only be @Retention. This goes on
to state that if there is no @Retention meta-annotation, the default
is class retention.

~Ciera


On 4/6/07, Jim Hazen <jimhaz...@gmail.com> wrote:
> > It doesn't say anything about the annotation being accessible by
> reflection.
>
> Aaa.  But it does.  According to the JLS, if an annotation has a
> meta-annotation with RetentionPolicy.RUNTIME the compiler will make the
> enclosed annotation available at runtime as well.  @Documented has runtime
> retention.
>
> JLS

Nils Kilden-Pedersen

unread,
Apr 6, 2007, 12:32:24 PM4/6/07
to jsr...@googlegroups.com
Of course it doesn't. Javadocs are generated from source files, and if a target (class, method, field, parameter) has @Documented, it'll appear in the javadocs.

Jim Hazen

unread,
Apr 6, 2007, 12:38:53 PM4/6/07
to jsr...@googlegroups.com
Well one of these two is very wrong.  Anyone have a test case?

"The one "gotcha" with Documented is in the retention policy. Notice that Listing 13 specifies the annotation's retention as RUNTIME. This is a required aspect of using the Documented annotation type. Javadoc loads its information from class files (not source files), using a virtual machine. The only way to ensure that this VM gets the information for producing Javadoc from these class files is to specify the retention of RetentionPolicy.RUNTIME. As a result, the annotation is kept in the compiled class file and is loaded by the VM; Javadoc then picks it up and adds it to the class's HTML documentation. "

Dave Griffith

unread,
Apr 6, 2007, 1:49:22 PM4/6/07
to JSR-305: Annotations for Software Defect Detection

I've seen the JetBrains @NotNull annotation in javadoc quite literally
hundreds of times. It is @Documented, and has @Retention of CLASS.
It is not available reflectively in the Sun JVM (I just ran a small
test case). The article linked is mistaken.

On Apr 6, 12:16 pm, "Jim Hazen" <jimhazen2...@gmail.com> wrote:
> I may have misread. Even if annotations don't inherit RetentionPolicy from
> meta-annotations, @Documented still requires a runtime policy to work. At

> least according to this article.http://www-128.ibm.com/developerworks/library/j-annotate2.html Someone

mfursov

unread,
Apr 16, 2007, 10:51:25 AM4/16/07
to JSR-305: Annotations for Software Defect Detection
Jonathan,
What additional optimizations JIT will be able to do if JSR-305
annotations have runtime retention?
Do you think that if parameter have @NotNull annotation JIT can safely
skip null checking in generated code?
Do you have any other examples for JIT?


On Apr 5, 2:43 am, "Jonathan Aldrich" <aldrich.jonat...@gmail.com>
wrote:

Ciera Christopher

unread,
Apr 16, 2007, 11:46:58 AM4/16/07
to jsr...@googlegroups.com
> What would the cost actually be? Clearly, it should be a per-class
> cost, not a per-instance
> cost.
>
> What would the cost of one runtime annotation per method be on a
> large application?
>
> Anyone want to do a back of the envelope calculation?

I'm not sure of the actual cost of each runtime annotation. However,
here's some project numbers for anyone who can calculate it.

Size: 110 KLOC
Number of classes: 2100
Number of methods: 11000

This project makes heavy use of object-oriented design; I have heard
many people claim it to be over-designed. I don't think there are many
projects that would be more worse case than this. I think if we can
show it to be a reasonable cost tradeoff for a project with this many
classes (given the relatively small codesize), it's worthwhile.

~Ciera

Maxim Shafirov

unread,
Apr 16, 2007, 12:04:55 PM4/16/07
to JSR-305: Annotations for Software Defect Detection
Please note the decision we'll make applies to *every* java project
out there, not the most common ones. So I beleive "if runtime
penalties are OK for mid-size project we'd accept it" logic is
severely broken.
IntelliJ IDEA project now has 30000 classes + classes from JDK +
classes from various libraries resulting in a few 16.000 classes
loaded in the most common usage scenario and 99m default permanent
generation limit. I beleive our end users won't appreciate doubling
this and I also beleive our codebase is far not the largest one.

So, no matter how small runtime penalties are they don't scale, and we
must have very serious reasons to insist those will be paid off.

On Apr 16, 7:46 pm, "Ciera Christopher" <ciera.christop...@gmail.com>
wrote:

Tom Ball

unread,
Apr 16, 2007, 1:35:40 PM4/16/07
to jsr...@googlegroups.com
I spoke with Joe Darcy, who has been the lead engineer for all JDK
annotation work, and his understanding of how HotSpot optimizes for
runtime annotations is that their structures stored but not
initialized until the first annotation in a class, method, or variable
is referenced, at which point they are all loaded and the appropriate
reflection instances created. The reason I said HotSpot is because
this optimization behavior is not specified and may vary with
different JVMs.

So (for HotSpot) if you have a project which doesn't normally have its
annotations referenced at runtime, then the cost is basically the
classfile size difference plus memory boundary padding. The project
delta is difficult to calculate, however, because constant
declarations are shared within a classfile; one classfile which
specifies the same parameter string to lots of annotations will have a
smaller delta than one with different strings, for example. There is
also a hit for the first annotation use due to its class name entry in
the constant pool and a smaller hit for the first annotation use on a
class or class member for the attribute overhead, compared to
subsequent annotations. It's therefore difficult to calculate
accurately.

Does anyone know of an existing open-source mid-sized project which
already extensively uses the annotations FindBugs or IntelliJ/IDEA
define? AFAIK, their current annotations do not use runtime
retention, so first compiling a project and noting the total size of
its classes, then changing those annotations' retention to runtime and
recompiling should give a much more accurate estimate of the memory
cost. Yes, there are additional costs when the annotations are
accessed at runtime, but those instances are probably short-lived and
so shouldn't be burdensome.

Tom

Mikhail Fursov

unread,
Apr 16, 2007, 1:44:11 PM4/16/07
to jsr...@googlegroups.com
Tom,
Before discussing overhead of JSR305-like annotations with runtime retention do we have the answer why do we need them in runtime? How they will help to a JIT or some testing tool?
Sorry if I missed something and it was already told before.
--
Mikhail Fursov

Jim Hazen

unread,
Apr 16, 2007, 2:20:29 PM4/16/07
to jsr...@googlegroups.com
Those asking for runtime-retention would like to apply the "one kind of stuff" principle to JSR 305 annotations, and use them to provide the underpinnings of runtime frameworks and tools.  We admit that the purpose of the original JSR restricts the scope of JSR 305 annotations to "a standard set of annotations that can assist defect detection tools".  However, we'd like to see that the original goals of JSR 305 are met without restricting the JSR 305 annotations to only assist defect detection tools.

Tom Ball

unread,
Apr 16, 2007, 4:46:39 PM4/16/07
to jsr...@googlegroups.com
Bill asked if anyone could come up with a "back-of-the-envelope"
estimate of the impact of runtime retention, I asked Joe Darcy if he
knew, and the answer proved more complicated than I anticipated.
FWIW, I strongly support class retention and believe runtime retention
to be an unnecessary waste of memory. But regardless, I think Bill's
request for actual data to more useful to our deliberations than all
of us rehashing our opinions (including me :-).

Tom

On 4/16/07, Mikhail Fursov <mike....@gmail.com> wrote:

Mikhail Fursov

unread,
Apr 17, 2007, 1:45:09 AM4/17/07
to jsr...@googlegroups.com
On 4/17/07, Tom Ball <tbal...@gmail.com> wrote:

Bill asked if anyone could come up with a "back-of-the-envelope"
estimate of the impact of runtime retention, I asked Joe Darcy if he
knew, and the answer proved more complicated than I anticipated.

I also asked Alexey Varlamov today (he is the implementer of annotations support in Harmony JDK) and he told me that memory footprint for an annotation in Harmony is about 4-5 pointers in the worst case. So it's about 20bytes on 32bit and 40bytes on 64bit platforms.


FWIW, I strongly support class retention and believe runtime retention
to be an unnecessary waste of memory.  

+1 here, but my concern is not about memory but about design and usecases.



--
Mikhail Fursov
Reply all
Reply to author
Forward
0 new messages