About Me

My photo
Author of Groovy modules: GBench, GProf, Co-author of a Java book パーフェクトJava, Game Developer at GREE

Tuesday, January 25, 2011

Inside GDK

Groovy has Groovy Development Kit (GDK) that extends Java Development Kit (JDK). Thanks to GDK, We can use many convenient methods with JDK classes. So where are those methods defined? How are those methods added to the JDK classes?


The answer of the first question is "In classes under org.codehaus.groovy.runtime package". I'll introduce some of the classes. 


 - DefaultGroovyMethods: Defines generic methods. But also defines some non-generic methods. In the early version, most of the GDK methods are defined here and Groovy team haven't completely finished moving them yet.
 - DateGroovyMethods: Defines date/time related methods.
 - ProcessGroovyMethods: Defines process-management related methods.
 - SwingGroovyMethods: Defines Swing related methods.


Those methods are all with public static modifier. For example, DefaultGroovyMethods defines dump() method as the following (I introduced dump() method in my previous post, "Generic toString() in Groovy"):
----
public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
    ...
    public static String dump(Object self) {
        ...
    }
    ...
}
----

The answer of the second question is a little complicated. Because to be exact, they aren't added. So how are they called? I'll explain with an example. Let me assume that you call dump() method for an object of java.net.URL class like the following:
----
def url = new URL('http://groovy.codehaus.org/')
url.dump()
----

In this case, Groovy calls dump() method by the following two steps:


1. Generate an object of org.codehaus.groovy.runtime.callsite.MetaMethodSite class that holds the meatadata (groovy.lang.MetaMethod) of DefaultGroovyMethods.dump().
2. Call the MetaMethod object's invoke() method with the URL object argument via the MetaMethodSite object.


So, in a nutshell, this means that Grooovy replaces url.dump() to DefaultGroovyMethods.dump(url) at byte-code generation time. 


You can't use the MetaMethodSite class directly because it's only for Groovy runtime. But don't be disappointed. You can do same thing by using Categories:
----
class MyMethods {
    public static String myDump(Object self) {
        ...
    }
}


use (MyMethods) {
    def url = new URL('http://groovy.codehaus.org/')
    url.myDump()
}
----

   

2 comments:

  1. I always wondered how are they being called..
    Nice explanation.

    ReplyDelete