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
-Peter
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?
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.
Tom
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
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
For many such diligent engineers, *any* runtime cost is a barrier to their
adoption of technology like this.
Besides, a lot of tools do use static analysis to analyze class files.
Dan
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
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
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
It doesn't say anything about the annotation being accessible by reflection.
RetentionPolicy.RUNTIME the compiler will make the enclosed annotation available at runtime as well. @Documented has runtime retention.
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:
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.
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.
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.
"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
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
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. "
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
On Apr 5, 2:43 am, "Jonathan Aldrich" <aldrich.jonat...@gmail.com>
wrote:
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
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:
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
Tom
On 4/16/07, Mikhail Fursov <mike....@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.
FWIW, I strongly support class retention and believe runtime retention
to be an unnecessary waste of memory.