Thursday, December 29, 2005
Microsoft goes AOP?
While AOP has reached a decent maturity level in the Java platform, thanks to several iniatives from different players with different priorities and goals (IBM, BEA, JBoss, Spring, and individuals like Bob Lee to name a few), Microsoft seems to be willing to move beyond that.
Last year at AOSD they were hosting a session on Phoenix, an interesting building block in the .Net CLR labs to help enable AOP frameworks. The community in .Net around AOP is fairly active as well, and Microsoft did awarded some of the projects, like Alan Cyment' SetPoint hosted on CodeHaus, the home of AspectWerkz.
Recently (Nov. 2005) Microsoft has set up a research event to emulate discussions around the best way to have good AOP solutions in the .Net platform. Several key .Net AOP project leads and folks from the AOP research academia were invited for a full day event at Redmond.
As far as I know Sun never set up such an event to try to understand AOP from its roots, and most of the discussion on the field has been driven by individual to individual networking and the AOSD annual conference.
I am eager to see where .Net ends up in that field in 2 years from now. There are certainly interesting architectures and concepts that we have implemented in Java based AOP that could be ported rightaway to .Net, though .Net luminaries have certainly several new ideas that 'd be worth exploring from Java luminaries point of view - and possibly standardizing on - obviously outside the JCP - unless Sun suddenly cares more about AOP.
Friday, December 23, 2005
Spring 2.x - innovation or maturity?
Last week I had the pleasure to discuss some more with the Spring team at JavaPolis, and I was thus given a quick informal update on what they are heading at in Spring 2.x, especially on the AOP side, discussing with Rod and Rob.
Spring AOP in Spring 1.x has been easy to use - though missing a good pointcut language. This simplicity is well described in a recent article on dev2dev by Eugene, and I had debated this issue and tried to solve it with Spring pointcuts on steroids with AspectWerkz.
In Spring 2.x, with the help of newly appointed excellent Adrian Coyler as chief scientist, my AspectJ lead peer, Spring AOP will unleash AspectJ and @AspectJ that I spent quite some time on this year as per our engagement to merge best of breed AspectWerkz with AspectJ.
But going beyond, Spring 2.x also introduces a way to define aspects in your spring bean xml files directly f.e.:
This is actually a really nice feature that I started playing with 2 years ago when implementing AspectWerkz with Jonas. So there is not much innovation there.
There might actually be some issues and hard work going forward. By having aspects defined this way, the AspectJ runtime that is used when your are using the excellent AJDT Eclipse Plugin for AspectJ will not take those into account (whilst regular @AspectJ ones are fully supported).
This means there 'll be definitely a need to open-up some more AJDT and have some extension point in it so that the Spring IDE can leverage it and have the AJDT crosscutting view display the Spring xml defined aspect.
Wups - xml defined aspect I have said - just like this June 2003' Jonas article introduces, back in AspectWerkz 0.6.3
Maturity - finally!
Thursday, October 20, 2005
JRockit powered AOP prototype available
It's there !
I am very pleased to announce the prototype version of JRockit that includes our AOP API is available. It will drive you far far away from current bytecode instrumentation techniques to a world of plain Java API, complete runtime control for hot deployment and undeployment, agnostic from the programming model you like for your aspects.
If you are involved in the AOP field, bytecode instrumentation field, APM field, and did not heard from us recently, please drop me an email and I 'll consider your participation in evaluating this technology to help us drive it to reality.
You can read the official announcement and some background information in our BEA dev2dev dedicated forum.
Monday, October 10, 2005
Synchronized block join points (v2)
Back in July Jonas suggested some semantics for a synchronized block join point. The discussion was interesting but I am wondering if we actually came up with the right question.
What if we simply think in terms of "is this type listening to locking events ?" instead of trying to come up with a pointcut expression that defines the semantics of a synchronized block - as done in Jonas discusion?
Lets draft some code:
Consider the program:
class Bar {
synchronized void foo() {
..
}
static synchronized void statfoo() {
..
}
void stuff() {
..
synchronized(bar) {
..
}
}
}
So the deal is to listen to lock events - mainly:
- waiting the lock
- just acquired the lock
- just released the lock (or perhaps about to release it - but this does not matter much for this discussion)
I argue that instead of defining semantics, the issue should be narrowed to a type pattern ie something as simple as Bar (or more fancy variations based on type hierarchy or annotation - you bet it).
Given that we can define this interface:
interface Lockable {
void waiting();
void acquired();
void released();
}
As a user you can then implement this interface on your own types, use some sort of AOP or proxy to have it introduced where you want, etc.
So what should happen to make that work?
First based on the type pattern, we simply introduce Lockable to Bar. This can be done manually, by the mean of AOP if f.e. I was writing @Distributed class Bar { .. } and so on - depends on the use case.
Second the interface must then be implemented by Bar.
The user can provide one if implemented manually, or the system (AOP f.e.) can provide an empty one ie something like (depends on the AOP system but you get the idea)
@Introduce("Bar")
class LockableNOOP implements Lockable {
void waiting() {}
void acquired() {}
void released() {}
}
Last we need to transform the program so that the synchronized block or the Bar' synchronized method are triggering event to that.
This is not that hard since we just need to look at the type hierarchy for non static synchronized method and given that an instance synchronized method can be rewritten (by the system) as a synchronized(this) block we end up to something like that:
Replace all synchronized blocks like that:
Given
synchronized(stuff) {
..
}
to
if (stuff instanceof Lockable) {
Lockable lockable = (Lockable)stuff;
lockable.waiting();
synchronized(stuff) {
lockable.acquired();
..// unchanged body
}
lockable.released();
} else {
synchronized(stuff) {
..// unchanged body
}
}
Fairly easy.
So far, nothing will happen, as we have a LockableNOOP implementation, unless the user (you) explicitly provided some implementation.
Last part: configure the system so that it advises Lockable' methods, so that you can add your behavior there (f.e. distribute lock, or trace them for some application performance system). There, usual AOP stuff can be used.
You can now access the enclosing static join point information if you need - which gives you if you really need it, the rich semantics Jonas was looking for:
call(Lockable.waiting()) && withincode(....) && target(t) && cflow(...) .....
// t is the locked object
There are two interesting things to solve now:
- What if I want to kick out the synchronized() block ?(f.e. for distributed lock). I think a small variation of Lockable can solve that - f.e. boolean shouldUseJavaLocks(), and a tiny change for the transformed program.
- What about the static synchronized statfoo() {..} in Bar? For that one, the transformation would have to be a bit more compex so that we f.e. lock on an introduced static field. That said, the Lockable interface is not handy anymore. Any suggestion for that one? Should we define three methods like static void lockable_waiting() that ones would implement or introduce to adress this use case?
On a more high level perspective, this send us back to a recurrent set of problems in the AOP / bytecode transformation space:
- to achieve API transparency, we have a very intrusive transformation engine (though the one described here can be quite fast)
- by changing the bytecode we break the visibility another system may require to work properly (as f.e. we add if blocks, change synchronized method into synchronized blocks etc).
There is thus a set of open questions:
- So should that belongs to the JVM directly, and in which form?
(as f.e. JVMTI already provides monitor entry / exit events, that should be fairly easy). - Should those 3 Lockable' methods (or 6 if we include the static versions) belong to java.lang.Object direclty?
- Would an hybrid system that changes the synchronize blocks using bytecode transformation but then relies on JVM level support for AOP such as we do in JRockit be enough to listen for lock events?
- Is the cost of the introduced instanceof acceptable?
Happy thinking!
Wednesday, September 28, 2005
How will nextgen AOP looks like?
This last days I have been thinking some about how next gen AOP implementations may look like in say 4 years from now in the Java landscape.
As you may known, 5 years ago AspectJ was not based on bytecode manipulation but was based on source code transformation.
As of today, full blown AOP like AspectJ and JBoss AOP are usually build on top of really heavy bytecode manipulation, while more lightweight approach like Spring AOP are build on top of proxy (which under the hood can use bytecode generation technology ie JDK or CGlib proxy).
In the next few days we will start spreading the prototype implementation of AOP support in JRockit JVM which allows to implement all of the AOP interceptions features without even touching the bytecode but with a more abstracted subscription based API. If you missed the dev2dev series you can read more about it there.
This technology is definitely a breakthrough in the field, but does not address the introduction/mixin features ie capability to add method / field / annotation / change the object hierarchy of the object model in a crosscutting manner.
This means that f.e. to implement AspectJ as it is on top of the new JVM based technology we need to wether
- remove the feature from AspectJ - this is dumb as introduction are an important part of AOP
- do that in the VM - well, perhaps but unlikely from my perspective as it would mean changing the Java language itself else ones would not be able to call the introduced members from regular code
- use an hybrid bytecode / VM based AOP approach - why not but it looks a lot like going back to the old bytecode based implementation complexity
- do it in another way!
My thoughts on that is that we will likely do it in another way - and perhaps going back to source code transformation. This year Sun' folks presented the Jackpot project at JavaOne - which is sort of a rule driven source transformation engine. If that ones goes mainstream somewhere with Java 7, ones will have a fairly great technology set to rethink the way we implement AOP in Java, mixing nextgen APT (that will expose the full AST), Jackpot and JVM weaving.