AOP and reuse. Now that our AOP implementation is stabilizing, and we're writing TONS of code that uses it, I am seeing one particular area why this rocks so much compared with the "usual" way of doing things: reuse.
The most striking example is as follows. All tree-based object graphs are created by simply attaching two generic extensions to them: NodeChild and NodeContainer, which together form a parent/child relation. All code that operates on trees then only have to understand these two interfaces. This means that we can have object graphs that have mixed object types, which is great, but it also means that I can write UI code that uses only these interfaces. For example, we have a drag&drop enabled JTree thingy which has a customized TreeModel that works directly on these two interfaces. I.e. if I want to edit object graphs that implements these interfaces I just create such a JTree and then "it just works". This, then, enables an enourmous amount of code reuse, not only on the server-side and in the object model, but also in the client code which uses it. This allows us to churn out new features with an amazing speed, and the more code we write (all of which is reusable), the faster it goes to make new features since we can reuse so much of the code.
See? This level of reuse is almost impossible to achieve with "normal J2EE programming", or any other kind of programming. AOP achieves this because of its inherently reuse-friendly nature.
And THAT's really really nice. [Random thoughts]
Sounds terrific. Will this AOP framework be made available to the rest of us at some point? 
9:01:02 AM