Skip to main content

Still Thinking About Annotations..

Posted by eitan on November 24, 2005 at 7:20 AM PST

It has taken me a while to get into java 5 annotations.
The reason partly was how late java 5 distributions
arrived to the macosx platform (and it's still not the
default version). About six months ago this stopped
being an issue for me as i am now developing on ubuntu.
I can't say enough wonderful things about ubuntu
but we'll save that discussion for another blog entry.

I tried out writing my own annotation. The scenario in
question was the idea of modeling a method as an action.
So metadata about a method might include the caption for
the action, the mnemonic character to bind to that action
and more such metadata. Essentially, the idea is to invoke
the method when the action is performed from the UI.
Here's a simple example of how an annotation might be bound
to some methods in a ficticious class, Waiter:

public class Waiter
   private String _name;
   public Waiter(String name) { _name = name; }

   public void aplainmethod()
      System.out.println("this is a plain method");

         caption="Greet Customer",
         parameterCaptions={"Enter Name: ", "Specify Greeting: "}
   public String greet(String name, String greeting)
      String msg = _name + " says: " +
            "Hello " + name + ": " + greeting;
      return msg;

   public String toString() { return _name; }

There's no denying the elegance of the solution. I
particularly like the ability to place information about
the method right next to it, though this may prove unwieldy.
Aspects for example place code about methods somewhere else
and use selectors to bind the code dynamically to methods
based on some criteria. That's much more powerful.

The reason I'm inclined to prefer aspects is simply that
the the meta-stuff is a block of code, whereas annotations
are declarative in nature. This is just a feeling at
the moment but I think the reason I prefer the former case
is that in order to arrive at a solution we're not employing
any new concepts: the concept of a block of code existed in
Java. Things are more self-similar, more minimalistic. Also,
one might wonder how far one can describe meta-work declaratively.
I think that's essentially the difference between annotations and
aspects: aspects are meta-code whereas annotations are meta-data.

I recently went through the short exercise of developing a basic
issue manager (similar to bugzilla or scarab). The most fascinating
aspect of the exercise was discovering a piece of metadata about
methods: its owner. That is, the person who is assigned a bug
is the bug owner and only him/her should be allowed to invoke the
'accept()' method to signal that they've taken ownership of the bug.
Similarly, only the person who opened the bug should be allowed to
verify and close the bug, not the developer responsible for fixing
it. So I decided to model accept() and close() as methods on the
same object (Issue) but to specify the owner of the method to relate
who (what logged-in user) is allowed to invoke them (from the ui
of course).

For better or for worse, this is what I came up with:

      ComplexType type = ComplexType.forClass(Issue.class);
      type.command("Accept", AssignedState.class).setOwner(type.field("assignedTo"));
      type.command("Fix", AcceptedState.class).setOwner(type.field("assignedTo"));
      type.command("RejectFix", FixedState.class).setOwner(type.field("openedBy"));
      type.command("Close", FixedState.class).setOwner(type.field("openedBy"));

So the way you should read/interpret the code is:

For Issues:

for the command "Accept" in AssignedState, set the owner to the value
of the assigneTo property (that is call getAssignedTo() when you need
to know).


Sure enough, that did the trick. Now when I assign a bug to a user, only
that user can accept it (what I'm not showing you is the framework that
produces the ui from the model objects).

My main question at the moment, is: would it be possible to define such
meta data using annotations? I don't have the answer yet. This bit of
code is declarative in nature so we should be ok. The only complication
might arise from the limitation that annotation property values can only
be of type: primitive, String, Class, enum, annotation, or an array thereof.
In the above case, the owner is of type Field (not java.lang.reflect.Field,
but another Field). There are other issues to consider as well, and they're
not necessarily insurmountable.

I don't yet have extensive experience with annotations to say for
sure, but I have a feeling that it would be nice to be able to traverse
from an annotation to its associated programming element; in this case:
to go from the CommandAt annotation to its associated method. Looking
at the javadocs for java.lang.annotation.Annotation, this relationship
does not appear to be defined.

I find it would be very interesting to also discuss this whole issue of
metastuff from the point of view of aspects. Maybe it's just me but
having to weave in aspects into bytecode seems to be a hurdle high enough
to block mass adoption of this powerful technology. My feeling on this point at
the moment is that aspects have not yet reached their peak; that
we will have to wait for a manifestation of aspects implemented for a
scripting/non-compiled environment before that can happen. Indeed there
already appears to exist a working prototype implementation of aspects for ruby.

Related Topics >>