Tuesday, February 9, 2010

Calling Groovy closure from Java

After spending some time with Groovy alone i thought to mix Groovy code with Java. As closures seems the most weird in Groovy i tried to access a closure method from the Java class.

// Groovy code
class ClosureTest{
String firstName
String lastName

def proc(Closure closure){
closure.call(firstName, lastName)
}
}

// Groovy client
def ct = new ClosureTest()
ct.firstName = "dhaval"
ct.lastName = "nagar"
ct.proc{fn, ln -> println "$fn, $ln"}

// Java client

import groovy.lang.Closure;

class JavaClosureClient{
public static void main(String[] args){
ClosureTest ct = new ClosureTest();
ct.setFirstName("dhaval");
ct.setLastName("nagar");

ct.proc(new Closure(ct){
public Object call(Object[] argument){
System.out.println(argument[0] + ", " + argument[1]);
return null;
}
});
}
}

Well the difference shows the verbosity of the Java client compared to the Groovy one.

At my workplace we are not in a position to use Groovy extensively but with such silent integration between the two i am sure we can leverage some of the Groovy features.

Dynamic Typing in Groovy

Groovy like many other features works different from Java when it comes to method binding. Java uses the static binding at compile time to bind the method with the caller based on the parameter types. On the other hand Groovy does method binding at runtime based on the value type of the variable.

Java method binding

public class BindingTest{
public static void main(String[] args){
Object obj1 = 1;
Object obj2 = "hello";

proc(obj1);
proc(obj2);
}

public static void proc(Object obj){
System.out.println("object");
}

public static void proc(String str){
System.out.println("string");
}
}

At execution, the above Java program will print "object" for both the method calls. The reason is Java does "proc()" method binding based on the variable type defined in the call and ignores the actual values.

On the other hand the same Groovy code will print the output based on the variable values at the runtime.

Groovy method binding

def proc(Object obj){
println "object"
}

def proc(String str){
println "string"
}

proc 1
proc "hello"

The above Groovy program will print "object" followed by "string" output upon execution. This capability makes the code clear and concise. Developer can avoid unnecessary type casting in case of method overriding.

One such boilerplate code a Java programmer has to write while overriding the equals() method, which can be avoided with this approach.

// Java way
public boolean equals(Object obj){
if(!(obj instanceof MyType)){
return false;
}

MyType mt = (MyType) obj;
// do equality check
return result;
}

// Groovy way
public boolean equals(MyType mt){
// do equality check;
return result;
}

The Groovy code is quite simple as no type checking or type casting is involved. Besides if the caller will pass any other type of object; the super class version of equals() will be called and as the base equals() checks identity (==, reference equality), it will return false without any additional line of code.

So such small but effective techniques makes Groovy more popular in Java world.

Java Programmer's first look on Groovy

Like many Java programmers i started learning Groovy for some fascinated stuffs like Dynamic Typing, Closures, functional programming, etc. Overall the first experience with the Groovy was mind blowing. It has many new things to learn. To start with i am using Groovy in Action, its an excellent book for Groovy beginners.

My first encounter with Groovy started with the conventional "Hello World" program. The Hello World example finished and as such i didn't learn anything.

println "Hello, World"

But meanwhile i found that there are various ways to execute the above groovy code snippet:

1. From command prompt

>groovy -e "println 'Hello, World'"

2. From .groovy file

// HelloWorld.groovy

println "Hello, World"

// on prompt
// .groovy extension is optional
>groovy HelloWorld.groovy

3. From Groovy Interactive Console

// on prompt
>groovyConsole

A GUI application will open where in the upper half part developer can write the Groovy script and on lower half can see the script result.

4. From Groovy Shell

Though i haven't explored the Shell much but i could execute one line at a time and "Hello World" needs one line only. Following is the command to open the Groovy Shell:

// on prompt
>groovysh

Seemingly it would look quite simple to a new learner, but the real magic starts when the above code is either executed by Java interpreter or used by a Java program.

Convert Groovy files to .class files

// on prompt
// .groovy extension is NOT OPTIONAL this time
>groovyc HelloWorld.groovy

And the above command will create a .class file which can be executed with:

// on prompt
>java -classpath .;{groovy home}\embeddable\groovy-all-1.6.7.all.jar HelloWorld

And it works correctly. The same way this class file can be access by any Java program, it can create an instance or call the main() method directly.

So overall my first experience with Groovy was really good and i am quite sure to spend some time with this emerging language.

References

1. Groovy Home
3. Lots of links at Groovy DZone

Monday, February 8, 2010

Getting Started with Grails, Second Edition

The second edition of Getting started with Grails has just released. As the name says the book gives the step-by-step knowledge for the Grails framework and its fundamentals. The book is very well written and a must read for Grails beginners.

Scott Davis and Jason Rudolph both are very well known in Groovy and Grails world. The book will surely help you understand the power of Grails.

The book is available in the infoq.com bookshelf http://www.infoq.com/minibooks/grails-getting-started.

If you are a Groovy/Grails beginners like me, read Mastering Grails article series by Scott Davis at http://www.ibm.com/developerworks/views/java/libraryview.jsp?search_by=mastering+grails

Sunday, August 2, 2009

Google Wave Free Account Access

I received my Google Wave just a day before. But i found not all got this invitation and many are frustrated because they didn't got it and someone from their group has got it.

I am making my wave account open to those who doesn't have, so that they can use the application. This step to not to gain any kind of publicity but to help those who truly want to use.

username: dhaval.b.nagar
password: for password mail me at dhaval.b.nagar@gmail.com

I am a java developer and google fan and hopping everyone going to use this account having the same purpose as i have, to make this much better.