|
|
||
Eitan Suez's BlogJ2SE ArchivesStill Thinking About Annotations..Posted by eitan on November 24, 2005 at 07:20 AM | Permalink | Comments (2)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");
}
@CommandAt(
mnemonic='g',
caption="Greet Customer",
parameterCaptions={"Enter Name: ", "Specify Greeting: "}
)
public String greet(String name, String greeting)
{
String msg = _name + " says: " +
"Hello " + name + ": " + greeting;
System.out.println(msg);
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:
static
{
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). etc.. 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. Structure of J2SE: ModularityPosted by eitan on July 06, 2004 at 12:19 PM | Permalink | Comments (6)With 2604 classes in J2SE v1.4.2_05, one could say that J2SE is a large API. I mean, compared to other APIs, such as dom4j (153 classes) and hibernate (466 classes), J2SE is large. Of course, you'll argue: "this is not a fair comparison: J2SE is an aglomeration of multiple APIs, packaged together as one large bundle." One should instead compare dom4j and hibernate with APIs such as jdbc, swing, awt, jndi, jta, rmi, security, util, xml, etc.. My point exactly! I'm glad you brought this up. [AFAIK] Java was the first language to introduce an official, structured, and coherent namespace mechanism to separate my code from yours, code that does X from code that does Y: packages. And packages are terrific! Over the years, and with the growth of the Java platform, I've come to believe that yet another level is missing: some kind of uber-package. Maybe we should simply call it an API. We need something to bridge the gap from "package" to J2SE. This idea reminds me very much of what the folks at W3C do with their specs: with time, new revisions of specifications grow to a point where spec authors decide to modularize them. For example the CSS3 spec is comprised of a few dozen modules (fonts, lists, borders, text, print, media, etc..). The latest DOM and HTML specs are also modularized. Back to Java, I'd like to see J2SE more formally modularized. I mean, I know that all packages that begin with javax.swing a part of the Swing API. I'd still argue for a more formal modularization mechanism. As I browse J2SE javadocs, I'd like to see a first-level hierarchy of APIs, not packages. I see this as a natural "cleavage point" (so to speak). And in fact, somewhere under the java.sun.com web site, you'll actually find home pages for each of these J2SE "sub-APIs." I'd like to go as far as select what J2SE APIs to include in my javadocs to begin with (perhaps because I may not need to use them all on a specific project I'm on). This reminds me of something else (here I go on yet another tangent): there's this informal rule that average humans have difficulty remembering lists longer than seven (7) items. J2SE contains 114 packages. That's definitely more than 7. If we were to introduce this extra level, we could nominally bring things back, closer to that rule of seven: J2SE could be comprised of maybe a dozen sub-APIs, each containing maybe 8-10 packages. That'd work for me! As far software packaging/download purposes are concerned, I'm actually happy as a clam with the current state of affairs. | ||
|
|