Friday, February 27, 2009

Hybrid call site model based on Groovy

I'm trying to model a class structure that support the following features:
  • callsite; separating call and execution semantics to
    • support before/after advice of AspectJ's pointcut-advice model (possible support around advice)
    • further support my typing concerns.
  • support statically resolved callsite (resolving is done at compile-time, but also changeable at runtime)
  • support dynamically resolved callsite (as done in Groovy, JRuby, etc.)
  • must be compatible with Java. i.e., Generated classes can be used as normal Java classes.
My below POC is based on Alex T. implementation. But instead of showing all kind of callsite, I show you here only statically resolved callsite. This callsite is surely fast (I hope it's gonna be at the same level of Java) because it's compile-time thing. The interesting point is that, I have a special class loader for these callsites, namely StaticCallSiteClassLoader. What does it do?  This class loader allows re-definition of these callsites.

What I have observed so far is that All of my callsite classes (_0_println, _1_ctor, _2_render and _3_index) have not been loaded when there is no "direct" reference to them. So they can be fully lazy loading using the StaticCallSiteClassLoader. (I've checked this with java --verbose)

How could these callsites are changed at runtime?
You may see the acallsite, an CallSite array that hold all callsites in the example class. It's intended to be public and can be accessed by, for example, a virtual meta-class.
So what's a virtual meta-class? It's kind of meta-class, but in this case, it's not for controlling behaviour of the class (because all dispatch are static). It's for changing behaviour of callsite by reassigning new callsites object to the callsite array.

Notic that I use WeakReference to hold a callsite class loader. This will be making the class loader GC-able. That's it, after deferenceing all old callsites out of the callsite array, the class loader can be unloaded. Therefore, all callsite class definition are gone as well. Then, we can create a new set of callsites for the current class. This technique would be flexible enough for:
  • changing a static call to be a dynamic call
  • changing a dynamic call back to a static call
  • installing a woven callsite with before, after advice (it features dynamic AOP)
  • inserting type advice, which can lead to bytecode inlining
  • design a hybrid type system to support both static and dynamic typing in the same system.
import java.lang.ref.WeakReference;

import runtime.CallSite;
import classloader.StaticCallSiteClassLoader;
import dm.Render;

public class TestController {

    /* synthetic */
    private static WeakReference<StaticCallSiteClassLoader> cl;

    /* synthetic normal callsite */
    public static class _0_println extends CallSite {...}

    /* synthetic constructor */
    public static class _1_ctor extends CallSite {...}

    /* synthetic inter-type declaration callsite. statically resolved */
    public static class _2_render extends CallSite {...}

    /* synthetic property callsite */
    public static class _3_index extends CallSite {...}

    /* synthetic */
    public static CallSite[] acallsite;

    static {
        cl = new WeakReference<StaticCallSiteClassLoader>(
                    new StaticCallSiteClassLoader(TestController.class)
        );
        acallsite = new CallSite[4];
        acallsite[0] = cl.get().get("_0_println");
        acallsite[1] = cl.get().get("_1_ctor");
        acallsite[2] = cl.get().get("_2_render");
        acallsite[3] = cl.get().get("_3_index");
    }

    public TestController(){
        super();
    }

    public int getIndex() {
        return 10;
    }

    public static void main(String[] args) {
        acallsite[0].callStatic("hello world");
        TestController t = (TestController)(acallsite[1].callConstructor());
        acallsite[2].call(t, "hello world");
        acallsite[0].callStatic(acallsite[3].callGetProperty(t, "index"));
    }

}


Wednesday, February 25, 2009

Using AspectJ to find a Grails' bug

It's because I've got a constraint resource (also time). I've found a Grails bug (4060) that is really hard to spot. There is no exception was thrown and I have no idea how to trace this bug because my knowledge about Spring is really limited. I also do not have any good IDE to help debug Grails well. (calling grails-debug and attaching it remotely to Eclipse won't help much in this situation).

After I enabled Grails log to understand some behaviour of Grails' spring package, I saw some point in the log that it's likely a bug, but the log message is inside Spring, not Grails. (Yep, I need a stack trace).

I then got an idea of using AspectJ to help inserting a conditional code to "dump" stack from that point. What I've used is an execution PCD and a call to Thread.dumpStack();

Here's steps:
  • Enable trace log in grails-app/Config.groovy
  • Find a message
  • Grep to locate the point that emits the message. I found it in Spring code, not Grails.
  • Instead of rebuild Spring, I wrote this AspectJ code:
    pointcut pc():
        execution(
           public Object DefaultSingletonBeanRegistry
               .getSingleton(String,ObjectFactory)
        );
       
    before(String name): pc() && args(name,..) {
        if(name.equals("localeResolver")) {
            Thread.dumpStack();
        }
    }

Note that my target Spring bean is localeResolver, so I put a condition here to dump the current stack to find which part of Grails code is doing with this bean at that time.
  • I then wove the above aspect into spring.jar
$ ajc -cp .:aspectjrt.jar:spring.jar
   -inpath spring.jar\ // I was going to weave spring.jar
   -outjar spring-2.5.6.jar\ // output would be spring-2.5.6.jar
   -showWeaveInfo\ // I wanted to see some weaving info
   -Xlint:ignore\ // ignore error when resolving some missing classes
   Dump.aj // the above aspect


And gotcha, I could really see the context around when this Spring bean is loaded, and reported to Grails JIRA (And Graeme, you did fix it really quickly - you're super cool!).

Thus, using AspectJ code + Thread.dumpStack() is kind of a conditional break point that can help you debugging Grails without an IDE.

Friday, February 20, 2009

Simulate Object with Groovy's Closures and Map

After reading Chapter 18 of Types and Programming Languages by Benjamin C. Pierce, I've got an idea to simulate how OOP is working with closures and map in Groovy. Just for fun anyway :)

def func_01 = { self, props ->
  self.name = props["name"]
}

def func_02 = { self ->
  println "${self.name} is running"
}

def a = [init: func_01, run: func_02]
a.self = a

a.init(a.self, [name:"mr. a"])
a.run(a.self)


Tuesday, February 17, 2009

Explaining Typesheet

I've been designing a language for typesheet, a technique to speeding up Groovy by enforcing type for specific calls.

Current I can enforce type of a call by writing:

method(my.package.MyClass#main(String[])) {
  call(println(*)) && args(s) {
    s ~> String;
  }
}


This typesheet reads: With in the main method of class MyClass, match every call to meta-method "println" (regardless input args). For matched calls,
  1. let MOP select real methods by assuming the type of input argument to be "String", and
  2. convert values of those arguments to be "String" before passing them to the calls.
You may notice that I emphasis 2 places. There are 2 different phases of the above code to be working. Firstly, in dynamically typed languages, like Groovy, method binding is performed at runtime. So matched call messages are not the real methods. Calls to "println" there may be anything depending on the MOP engine to select.

Secondly, declaration in { s ~> String; } (I call it a type intervention block) enforces MOP to select the method according to the type of "s", which is bound to the only argument of the method. ("s" has been binding using an args predicate).

So, what's happening next? You might be guessing correctly :)
MOP will be fully by-passed for those matched calls (because related types are enforced). Therefore, speed will be increased to the level of normal Java calls.

Monday, February 09, 2009

Playing around XUL, JavaScript and jQuery

<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<x:window
    xmlns:x="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
    xmlns="http://www.w3.org/1999/xhtml"
>
    <x:script type="application/x-javascript"
        src="file:///c:/xul/jquery-1.2.6.js"
    />
 
<x:script type="application/x-javascript; e4x=1">
<![CDATA[
  function test(){
    $('#b').attr("label", "3");
    var frag =
        <listitem value="4"
            label="new item"
            xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
        />;
    $('#l').get(0)
        .appendChild(
            (new DOMParser()).parseFromString(
                frag.toXMLString(), 'text/xml'
            ).documentElement
        );
  }
]]></x:script>
     
    <x:button label="click me" oncommand="test();"/>
    <x:button id="b" label="2"/>
    <x:listbox id="l">
        <x:listitem value="1" label="item label"/>
        <x:listitem value="2" label="item label"/>
        <x:listitem value="3" label="item label"/>
    </x:listbox>
 
</x:window>



The above code is to dynamically adding a new <listitem/> into listbox #l. It will be working fine when we get some XUL fragment remotely from the server-side as well. This is Gecko 1.9.0.5.

What I've learned:
  • $("#id").get(0) returns a single element, while .get() returns a list.
  • e4x=1 tells the JavaScript parser to use the newer language spec.
  • jQuery works fine with XUL, but XML namespace is needed to avoid some gotcha because it's been designed to work with HTML, not actually XUL.
  • DOMParser works as expected
  • Gecko 1.9 solved a lot of bugs I was encountering in 1.8.
  • With Grails as a back-end, we can now create a dynamically half-Web/half-desktop app.

Monday, February 02, 2009

What if Groovy has got Structural Typing

Here's a quick mock class after I've been reading this entry.

class G7Greeter {

  def greet(String who, {def setOutput(String text)} model) {
    println "Hello from G7 ${who}"
    model.output = "Hello from G7 ${who}"
  }

}


It would be great if Groovy has Scala's structural typing feature. Structural typing is good for statically "duck typing"-like behaviour. But it seems we need a fork as Groovy dynamic typing allows multi-dispatch already.