Saturday, April 28, 2007

Groovy running fine on .NET

It's just a crazy idea to test Groovy on .NET, after I read this post on IKVM weblog that the author test IKVM using JRuby. If JRuby runs fine, probably Groovy does so.

Simple steps here,

1. Download .NET 2.0 Runtime.
2. Download SharpDevelop IDE 2.1, just in case that you're lazy enough to code.
3. Download IKVM for .NET 0.34 rc2 binary
4. compile your Groovy jar with the following command:

ikvmc -target:library groovy-all-1.1-SNAPSHOT.jar

Some errors will appear, just ignore them.
You'll get groovy-all-1.1-SNAPSHOT.dll.

5. Open SharpDevelop, create a new .NET console application.
6. Add references, all IKVM DLLs and your groovy DLL.
7. Open your main class, type the following code (in C# for example)
using System;
using System.Collections.Generic;

namespace GroovyDotNet {
class MainClass {
public static void Main(string[] args) {
groovy.ui.InteractiveShell.main(args);
}
}
}

8. Run the program, and you'll also have an executable file as well.

Alright, if you don't want to get your hand dirty, do step 1 and wait for the binary. I'll upload it soon.

Update:
Here's the screen shot.


and here's the binary.

Tuesday, April 24, 2007

Patterns for selecting metaclass will allow better support AOP in Groovy

I'm still being with quantification thoughts for dynamic AOP.

There're some diffirences between dynamic and static weaving implementation. I'm saying about what AspectJ does, and what I'm going to do with Groovy AOP.

In AspectJ, it's focusing on static weaving for better performance. The idea behind is that every dynamic joinpoint has the corresponding static shadow, which is projected on source or bytecode of the target program. All quantifying will be done by AspectJ compiler to match every defined pointcuts, of course, at compile-time or load-time. Easy kinds of quantifiable joinpint are, for example, constructors and methods.

But nothing like this exists when we're talking about dynamic AOP. Dynamic AOP has nothing to do about 'static' shadows. This kind of weaving allows re-definition of aspect at run-time. Dynamic joinpoint in Groovy is powerful and a bit more complex to implement because of its MOP mechanism. Every class in Groovy has its own Metaclass to control the behaviour. ACtually, from AOP perspective, the metaclass can be though of as a basic per-target aspect. But when we're saying about AOP weaving, it allows multiple aspects to weave into a single target class. Comparing with MOP in Groovy, it's clear that AOP is somehow more powerful. In case of my AOP implementation, I have the AOP-metaclass to help dispatching advices.

So what's more ?

To fully support AOP quantification in Groovy, I came up with pattern matching idea to assign a metaclass for the target class. I'm feeling strange with this. I'm thinking of it as a good way to support pointcut-advice AOP model for Groovy. But there's something interesting about it that's beyond my head.

I hope I can figure it out soon.

Sunday, April 22, 2007

Ubuntu 7.04

Ubuntu Linux 7.04 came out, I did upgrade and everything goes fine.
Many guys in Java community get excited that JDK 1.6 is already in it's repository. My OpenOffice got updated to 2.2 as well, and that's great.

I've also tried it in VMWare player and, of course, there's no correct driver for 7.04 at the moment. The problem I have is just about the mouse. But it's not a big deal, I tweaked XOrg.conf and set the driver back to the original one ("mouse" instead of "vmmouse").

My new Ubuntu experience has just started !

Saturday, April 21, 2007

AOP for Groovy is here !! Code moved to be Grails-AOP

AOP for Groovy is here !

I've just refactored and uploaded my AOP subsystem into the Grails-Plugins repo. Anyway, it cannot say that this AOP implementation is Grails-Plugins. It's likely to be a drop-in module because it contains ObjectMetaClass that will hook into system-wide metaclass instantiation process.

This is an AspectJ-like, the pointcut-advice model implementation of AOP for Groovy. Both 2 important properties of AOP, Quantification and Obliviousness, has been implemented by design.

Browse the repo: http://svn.codehaus.org/grails-plugins/grails-aop/

Thursday, April 19, 2007

The ways to express pointcuts, the choice is yours

From the non-AOP programmers' perspective, the pointcut mini-language in AspectJ seems to be a bit difficult to learn. Before they can start writing some aspects, they need to know background concepts about join points, the way how to quantify them with a combination of pointcut designators, and the way how to express advice codes.

I cannot argue this because making pointcut languages simple yet powerful is quite an active research in the AOP area.

Some workaround to solve this problem could be having different kind of way to express pointcuts in one framework. So this means we're going to have several mini-languages inside the host language for describing aspects. They are what I'm going to implement for my AOP subsystem for Groovy.

For example, call() PCD is a quite common one you often use, so having:

Test.around['test*'] = {} instead of around(): call(Test.test*(..)) { }


can reduce the learning curve.

But when, the power of the basic pointcut language is not enough, you can use the full version of pointcut language, like this:

static aspect = {
def p = pointcut{
pcall('public *':'set*') & pcall( ... ) &
within(MyClass:'some*')
}
around(p) { context ->
proceed(context.args)
}
}


The choice of expressing pointcuts is just yours.

Monday, April 16, 2007

Aspect Groovy: Per class and Per instance

From last post, I'm going to the next step by re-implementing my AOPSupportMetaClass again in Java to have some precise controls. Now the AOP metaclass got updated and support weaving both per class and per instance. However, the pointcut expression style is still based on John McClean's implementation.

This is for per instance weaving


def t = new TestObject()
t.around['save'] = { inv ->
inv.args[0] = inv.args[0] + '.'
inv.proceed(inv.args)
}
t.save('test')



And you can guess, this is per class weaving


TestObject.around['save'] = { inv ->
inv.args[0] = inv.args[0] + '.'
inv.proceed(inv.args)
}
def t = new TestObject()
t.save('test')



Last test code can be obtained from here.

Sunday, April 15, 2007

Groovy and AOP Metaclass

I've recently found John McClean's last year article about AspectJ-like AOP model implemented in Groovy. In its comments, his readers posted that he should have a custom MetaClass to support his approach. I'm sure he probably did it because he's going to talk about AOP in Groovy at Grails Exchange conference this May. However based on his implementation, I've done the similar MetaClass as well, as I need some kind of AOP facility to support my research.

Probably after the Grails Exchange event, I can see his AOP code somewhere.

Here's my implementation:

package org.plaop;

import groovy.lang.DelegatingMetaClass

public class AOPSupportMetaClass extends DelegatingMetaClass {

def after = [:]
def before = [:]
def around = [:]

public AOPSupportMetaClass(MetaClass delegate) {
super(delegate);
initialize();
}

public Object getProperty(Object object, String prop) {
if(prop == 'around') return this.around else
if(prop == 'before') return this.before else
if(prop == 'after') return this.after else
return super.getProperty(object, prop)
}

public Object invokeMethod(Object arg0, String name, Object[] args) {
if(before[name]!=null) {
before[name](inv)
}

def inv = new InvocationContext(methodName: name, args: args, called: arg0)
inv.proceed = { arglist ->
super.invokeMethod(arg0, name, arglist)
}

def result = null
if(around[name]!=null) {
result = around[name](inv)
} else {
result = super.invokeMethod(arg0, name, args)
}

inv.proceed = null

if(after[name]!=null) {
after[name](inv)
}
return result
}
}



This is how to use it:

void testBasicAround() {
def mcr = InvokerHelper.getInstance().metaRegistry
AOPSupportMetaClass amc = new AOPSupportMetaClass(
mcr.getMetaClass(TestObject.class))
mcr.setMetaClass(TestObject.class, amc)

def t = new TestObject()
t.around['save'] = { inv ->
inv.args[0] = inv.args[0] + '.'
inv.proceed(inv.args)
}
t.save('test')
}


The big bug here is that this MetaClass hasn't yet supported per class weaving model. But it's not that hard to implement. John's article really realised me the power of Groovy MOP from AOP perspective.

Sunday, April 08, 2007

Invariant Dynamic Calls

Basically, dynamically typed languages, Groovy in this context, dispatch calls by firstly choosing appropriate methods, then invoking them. The choosing process is obviously expensive. Several techniques, such as method caching, are currently implemented in Groovy to speed things up. However, choosing methods through reflection won't allow JIT to optimise method bodies for callers. With caching, the shortest steps for Groovy are still:

calling an invokeX method -> looking up cache -> calling the cached chosen method,

and you can not further optimise the invocation beyond this point.

The only way to do this is to simply replace that call by the chosen method call.
It's basic and everyone on the groovy-dev list knows about this (I supposed). Anyway, there're a lot arguments in the list that we should preserve the "dynamicity" of Groovy. I agree with those arguments, so we should leave Groovy core as it is, but we can really do somethings at the application level, in production phase.

During unit testing, developers may find sets of "invariant dynamic calls" of their applications. I roughly define an invariant dynamic call as a call that has only one chosen method. Trivial examples for this kind of call in Grails framework are Domain class' .save() and .delete(). If we assume that our test suites cover the application enough, so we can basically conclude that each dynamic call identified by the test suites is an invariant dynamic call, if there is only one chosen method for it. Then, we just simply replace these calls with static signatures, in class files or even by on-the-fly transformation, to gain performance back.

My current technique to analyse calls at bytecode-level is, firstly scanning for ScriptBytecodeAdapter.invoke*, then reverse looking for LDC "methodName" and other arguments that will be stored onto the stack.

Beyond Java 6
I dont exactly know when INVOKEDYNAMIC will arrive, but with this instruction replacing invariant dynamic calls will be much easier by
1. changing INVOKEDYNAMIC to appropriate kind of invoke, say INVOKEVIRTUAL, INVOKESPACIAL, INVOKESTATIC or INVOKEINTERFACE.
2. changing type descriptors to the correct classes.

I haven't followed the spec of INVOKEDYNAMIC at the moment, it's time to have a quick read again.