Kiss My App

Tuesday, November 30, 2004

Practice What You Preach

This post is actually part II of my Annotation Inheritance blog. Based on some of recent rants, I'm finally fleshing out my own framework with some of the new features in J2SE 5.


The framework is another MVC framework, but don't leave yet... it's goal is to be completely configureless-- no XML files to manage along side your code. My hope is that when it's finished, I can look at rolling back some of the features into a future addon to JavaServerFaces. Some of the goals I have:


Lightweight constructor-injection factory-- and I don't mean container. The factory has the same goals as Picocontainer, but doesn't manage lifecycles at all at creation. Instead, it uses what's called "wormholing" to provide state and additional developer features like named bindings at higher layers. The way this works is that a company can create their own Container object and provide it an instance of my factory implementation. When a certain type is requested, the container is passed as a parameter, and then used in the construction of the instance. This is the wormhole, where top level objects are passed to the lower level objects in order to allow things such as lifecycle managment or proxying to occur.


The view and navigation should be maintained by the view if possible-- allowing not only form data to be submitted in the post, but also your "action forwards".


Annotation driven configuration. This means that contextual data such as converters or validators are declared right with the property on the object. This allows configuration data to be strongly typed and does not require "runtime" type checking of configuration data. Granted I'm anti-AOP, but I believe this solution runs more in line with straight-talking OOP principals. I can have a User object with all of its properties, then simply create a UserForm that extends User with all of the annotations you want to use for the web framework-- or simply apply them to User itself. The reason why declaring annotations like this is safer than AspectJ, is that the annotations aren't going to affect anyone unless they are specifically looking for them-- a reversal of roles you could say.


An example would be taking something like a "first name" property on a bean and declaring (on the setter) annotations like "@ValidateNotNull" and "@ValidateLength(16)". My hope is to have the validation processors abstract enough that they can be easily used outside of the MVC realm.


The reason why I'm finally posting some of my ideas is that they are now actually working. The generics and annotations in J2SE make everything seem so clean and exact in what you are doing-- no guessing games anymore in trying to make flexible frameworks. After I got home from work, I was able to put together a working example of a validator annotation with pseudo inheritance. Also, I was able to stack various validators on a single method or class in order to work like Common's Validator, but in probably a tiny fraction of the code and without the configuration files.
Here's an example of what a developer would have to add to their POJO "backing" bean for a web form (no implements or extends required).



public class NewUserAction {

protected String firstName;
protected int age;
protected UserDao dao;

public NewUserAction(UserDao dao) {
this.dao = dao;
}

public String commit() {
dao.add(new User(firstName, age));
return "pass";
}

public String getFirstName() {
return firstName;
}

@ValidateNotNull
@ValidateLength(16)
public void setFirstName(String firstName) {
this.firstName = firstName;
}

public int getAge() {
return age;
}

@ValidateIntegerRange(min=1,max=100)
public void setAge(int age) {
this.age = age;
}
}

Hopefully I will have the framework ready by the end of the year. I was going to post the working validator source code with annotation processing, but I would like to wait and publish an actual framework or article, not just bits and pieces.


Annotation Inheritance Part 1

With the new metadata JSR, the group decided no to allow any extensibility or inhertance with Annotations themselves (the spec only describes inheritance of annotated properties on objects themselves). I started to think about how a system could check for user defined annotations (since things like instanceof will not work). e.g. Being able to label a property with a Validator annotation, but then allow user defined Validators that have properties like smallest and largest value, or even a money Validator. Here's kind of what I'm thinking (whiteboard quality)--



@Retention(RetentionPolicy.RUNTIME);
public @interface Validator {
Class value();
}

@Validator(IntegerRangeValidatorInstance.class);
public @interface IntegerRangeValidator {
int start() default 0;
int end() default Integer.MAX_VALUE;
}

public class IntegerRangeValidatorInstance
implements ValidatorInstance {

protected int start;
protected int end;

public void setStart(int start) {
this.start = start;
}
public void setEnd(int end) {
this.end = end;
}

public ValidationError validate(Object value) {
try {
int ivalue = Integer.parseInt(
value.toString());
if (ivalue > end || ivalue < start) {
return new ValidationError(
"Value must be between "
+start+" and "+end+".");
}
} catch (Exception e) {
return new ValidationError("not an integer");
}
return null;
}
}

Now, how this ends up getting validated is by doing depth first searches on the properties and classes you are modifying for type Validator.class. It's not hard to concieve a recursive method that walks through an annotation from a method or class, get it's type, and then ask it for it's annotations until there are no more to get, or we've found a Validator annotation type.


In theory, once we've found a Validator type, instantiate class value, and if the Validator was a parent of the another annotation, use it's annoationType to reflect out the properties defined, and assign them to the instantiated class via setter injection. Now that we have a complete instance of the actual Validator object, then we can call some method on it to validate the input. Since Annotations are static, we can do lots for caching created validator for even higher performance.

I will probably try to hack something up tonight and post it on this blog as soon as I can.

Sunday, November 28, 2004

Ego Tripping at the Gates of Hell

In my initial rant about AOP, I hoped to spawn some serious debate from the Java community over what and how AOP should be used, if it at all. Two very lengthy threads insued at TheServerSide.com and Sun's Java Forums. I was offered some good examples of AOP usage, some poor examples of AOP usage, and an abundance of hubris comments. To all I say, "Thanks!"

I spent some time reflecting on my original post and the examples/debates offered up on the forums. Not to spoil the ending for all of you, but I feel even more strongly against using AOP with OOP than before.

Both OOP and AOP work to solve the same thing-- encapsulation and inheritance. The difference is that OOP provides a vertical object model through inheritance and delegation and AOP provides a horizontal attribute model through pointcuts. When a developer writes code, he or she operates within a set of 'rules' as specified by the language to provide scope to the logic they convey in their code. By providing scope, code becomes easier to read and maintain-- you can logically focus your attention on a single scope of variables and state through the concept of objects. AOP advocates are correct in stating that aspects can provide the same kind of scope and encapsulation, but one is better than the other.

Point #1, who has the right to provide the behavior for an object-- the subject or the observer? An example is moving and displaying a collection of shapes. When a caller (the observer) calls methods to modify the state of the shape, does it have the right to notify the display that the shape has actually moved? Shouldn't the shape (the subject) be able to retain the knowledge of if and how it moved? What if shape's behavior changes, will the observer's behavior now have to change? The OOP solution for updating the display would be to let the shape notify any listeners that it has in fact moved. The AOP solution is to update the display any time I call a method on shape where I think it will cause it move. Compile-time weaving or not, we've just broken the shape object's encapsulation and added code to our system that has to be maintained seperate from shape itself.

Point #2, AOP can make OO code act in unnatural ways. JBoss AOP provides an 'asynchronous' annotation to methods. The idea of taking a method and by simply adding an annotation, have it be asynchronous for everyone that uses it (the callers). First off, the method probably wasn't meant for asynchronous operation and the caller doesn't necessarily have the right to now declare it as such. Secondly, the JBoss asynchronous aspect introduces code changes to the way all callers now interact with the method. If the goal of AOP is to encapsulate behavior, this aspect is a complete 180. Referencing my first point, through AOP we've just changed the behavior of the subject through observation. An OOP solution would be to delegate the call while providing a literal asynchronous method signature, encapsulate asynchronous implementations in your delegator. If I want to use the method as written, unmodified, I can still call it directly. If I want the method to be called asynchronously, then I can be the special case and use a delegator.

Point #3, AOP with OOP now creates a bidirectional inheritance model. What does that mean? Your code can now be a pain to maintain. That is probably the biggest issue AOP proponents had with my original rant. Developers now not only have to trace the vertical object model, but also the horizontal attribute model as provided by aspect pointcutting. Developers everywhere are asking themselves, "Where's the beef? Where's that behavior coming from? Where's that variable being set? I don't know!" It might just be an IDE issue to some, but to me it's a logical issue. I can logically follow a single java class on a piece of paper, I can't say the same for all of the aspects that might be weaved at compile or runtime.

In summary, where do I see any benefit to AOP? In decorating my code, not my application. This means that AOP can be used for things like logging/tracing the code I write, but never to dictate application behavior or state. It really has no business in my application. If you find AOP as a wonderful solution to issues during implementation, then you are going about OOP the wrong way. The only thing AOP does is provide encapsulation for procedural programming.

Tuesday, November 23, 2004

The Annotated Dream

IMHO, the most prominent feature in J2SE5 is not generics, enums, or new for loops; it's annotations.

Annotations are better than Aspects since they are explicitly declared on your methods/fields/classes and checked by the default compiler. You may argue that Aspects and annotations aren't the same thing, but I believe Aspects are there to provide additional behavior within a specific context or protocol-- where now that context/protocol can simply leverage annotations declared on your objects. An example is a persistence protocol. Either you write Aspects and pointcut all of your objects to provide additional behavior/properties for persistence, or simply have your persistence mechanism "read" the behavior/properties off of the object you pass it.

I would like to see JavaServerFaces annotated just like EJB 3.0. The annotations wouldn't be a substitution to in-page declarations, but as a secondary solution for those who want a cleaner seperation of validation/conversion rules from the view. Imagine declaring a POJO bean with some JSF validation annotations and some EJB annotations. How easy would it be to modify and persist objects from a web page?

Wednesday, November 17, 2004

I have an AOP Framework for You

Today I came upon a new AOP framework that performs 5 times faster than the next implementation. It allows type safe mixin's, decorating interceptors, and can be easily run in any debugger. It's called 'Java'.

I've been writing code for my company long enough that I'm now running into those, "now why the hell is it doing that?" situations. What gets me through the learning curve is my trusty IDE with it's wonderful 'goto Definition' features, and not to forget the 'find References' gem. It's the only weapon I have in refactoring.

Now developers are all over AOP. Here's a great idea, we are going to make all of our classes dependent on a framework which will sprinkle your objects with behaviors that you will only get at runtime. Many articles talk about how to add things like debugging to your method calls using some AOP framework. If you didn't depend on running your code in an AOP framework in the first place, you could just debug what you did in any IDEs' interactive debugger.

AOP also talks about Mixin's, a way of weaving additional static behavior into your objects. Hey, I just made your car object a boat and the rest of your code doesn't even know it yet! How cool is that?! Java has Mixin's too, it's done through the composite pattern and interfacing your objects. I know first hand, that developers scoff at the need to interface all of your business objects, but even AOP implementations like Cglib of DynaOp use interfaces to represent mixin's. Yay, we have type saftey... kinda.

In addition to Mixin's, there are interceptors. I'm going to back pedal a bit in my rant and say that I can see the benefits of interceptors, but only within a framework context. Servlet Containers use Filters along with SOAP frameworks, but those are there to provide you with behavior that is contextual to the protocol. Some developers use AOP to handle transaction, I say use ThreadLocal or use the Transaction/Command/ServiceLocator pattern to define a flow of events for a transaction.

I can see how AOP can help us programmers be more lazy, lazy programmers are the best programmers hands down. Really, who wants to write the same code over and over? They will do it right the first time so they won't have to do it again or change it. But let's be good lazy programmers and follow Agile principals. Things like Single Responsibility, Composite Pattern, Delegate Pattern, etc should easily prevent you from coding yourself into a corner on your next project. e.g. I mentioned Mixin's using the Composite pattern, why not plug your Composite objects into an IoC container? There's your AOP framework, and you should be able to new your composite object in a main method too in order to test.

Once you start thinking in AOP, then your implementation and design will degrade since you know you can shortcut your way out of anything into an un-traceable mess. Go ahead and use AOP on your next project, then come back a couple years later and try to debug it. Let me see where the heck that value is being set...

Wednesday, November 10, 2004

Containers

Today, theserverside.com had a couple articles of interest, one was an open discussion on controller features and another was a web cast on the future of J2EE. Much of the controller discussion was people wanting everything under the sky rolled into their controllers-- tons of complexity and inevitably more XML configuration files. The J2EE web cast was quite reassuring in that top developers on the panel complained that J2EE was way to complex and that 99.9% of the people aren't even using any of the features in J2EE.

In summary, J2EE has tons of cool features but has high hurdles of entry (EJB, WS, JMS), as I like to put it. I look at the new Struts 2.0 (Shale) proposal and see Struts only becoming more complex. Don't get me wrong, business processes are terribly difficult to model, especially when your applications use legacy systems and the features that Shale is proposing would be put to good use, but what about the 80/20 case-- that 99.9% that I mentioned earlier. Is Struts setting itself up for being another, early EJB spec?

I've been developing with Sun's JavaServerFaces team (yes it's hard to believe that I'm actually working on a team for once), and it's because I feel very strongly about JSF and what it provides. Too many times have I repeated to JSF nay-sayers on the forums that JSF is extremely complex, but only if you want it to. I could write one plain Java object and plug it into JSF and have that be my complete application; or I could model a whole controller layer in 50 Java objects that talk to a business layer, etc. You are what you eat, as if it could ever be applied to pragmatic programmers, and I'm comfortable saying that I would use JSF on my next enterprise application (and we are talking about billions of dollars in transactions per year).

I want to take a step back for a moment and talk about those hurdles of entry with Java and the specs people are putting out there. These hurdles of entry can easily be tackled in 3 ways-- learn the spec, use a graphical tool to manage your code, or use a simplified API for that spec.

Learning the spec isn't a half bad idea, but I hate being concerned if I'm correctly connecting to a JMS with a Topic Connection, and it's an every continuing process that the developer himself must be concerned with.

The second option was using a graphical tool. BEA is leading the way with their workshop products that are all drag and drop development. Some may say that takes too much code controll out of your hands if you can't generate the same code in VI or Emacs. The other problem with the second option is that it might commit your whole enterprise application to a single vendor because all your code needs their tool's to deploy.

The third option IMHO is the best option with finding a simpler API to work with. This is something the EJB 3.0 spec is founded on with extrinsic definitions. Other IoC containers provide similar behavior, usually in an external configuration file of behavioral definitions. Spring is leading the way at simplifying development with the hurdles of entry for J2EE by providing simplified Beans that your code can interact with instead of 10 Objects (example is managing connections/transactions to a database with a single Hibernate DAO).

In summary, more work needs to be done to simplify specs or no one will use them. Developers have seen the light and basically regressed to container/extrinsic development. It's declarative, testable, and developers have ownership of the final product. I've been fleshing out a container called 'Strux' which uses annotation listeners and factories to wire components together.