Jim Driscoll's Blog

Notes on Technology and the Web

Archive for March 2012

Executing Groovy Programs in-memory

leave a comment »

Now that we’ve gone over some Groovy basics, it’s time to switch back to writing in the Java language, and talk about how to run Groovy programs inside your Java programs.  Like most general purpose programming languages, there’s more than one way to do things in Groovy, and that’s never more true when it comes to executing Scripts – I once counted 7 ways to use the String “System.exit(0)” to shut down the VM, and I’m quite sure that I missed a few.  For this example, we’ll use the method I consider to be the best and most extensible, which uses the class GroovyShell.

Before we get started, be sure to include the Groovy libraries in your Java class path, so that you can use the same classes as Groovy.  In the current distro, it’s the file named groovy-all.jar.    Once that’s there, you should be able to execute the following code:

 

import groovy.lang.GroovyShell;
import groovy.lang.Script;

public class Test {

    public static void main(String[] args) {
        GroovyShell shell = new GroovyShell();
        shell.evaluate("println 'hello world'");
 
    }
}

 

I won’t bother including the surrounding cruft in the future, but wanted to illustrate that this is just a (very) simple Java program.  We create a GroovyShell object, and call the evaluate method on it, passing a String.  That String, in turn, is evaluated by the Groovy parser, a class is (invisibly) created, and the class is run – the end result is that “hello world” is printed to std out.

There’s a problem with this code though – it’s kinda slow.  About 10ms on my machine (for a warm run, where all the required classes are already loaded and initialized – the initialization is actually 300ms, but that’s a one time hit).  Now, that might be perfectly acceptable for your application – but if you’re going to be executing this thing multiple times, that could really add up in a multiuser environment.  One of the things that’s happening here is a full compile of the generated script code.  And while compiler technology has certainly gotten faster in the last few years, it’d be nice to skip that step on occasion.  The GroovyShell API offers a way to separate out the compilation and execution steps.

 

GroovyShell shell = new GroovyShell();
Script script = shell.parse("println 'hello world'");
script.run();

 

Here, we’ve separated out the compile phase from the run phase.  The compile phase still takes 10ms, but the run phase only takes whatever the Java class run time is.  In this case, it’s a sub 1ms run time.  This separation also opens things up for us to use other APIs as well, and we’re going to use this technique going forward.

Under the hood, here’s what’s happening:  Groovy is taking your input String, and converting it into a class, of type Script.  Script contains a method, run.  The contents of that run method are populated with the parsed contents of the String you pass in as an argument.  So, when we call script.run(), the println method is called, which prints out the message.  One last important note is that the run method actually returns Object – so we can also use these scripts to compute values.  And if you don’t specify a return, the final statement executed in the script will be automatically returned as the value.  Thus, if the final line in your script is “x < y”, the run method will return a Boolean equal to whatever the result of the comparison is.  You can also define inline methods (as we did in the intro post I did), and those methods will be placed on the generated Script – you can even access those methods via reflection.

Next up, using the Groovy Binding class.

Written by Jim Driscoll

March 17, 2012 at 9:06 AM

Posted in DSL, Groovy

A quick introduction to the Groovy language (part 2)

leave a comment »

In my previous post, I started with a simple Java program (which also worked in Groovy), and slowly stripped out the cruft until I was left with the following Groovy script:

def sayHello(name) {
    println("Hello $name!")
}
def name = 'world'
sayHello(name)

 

Now, let’s add a little change to use an array.  Since Groovy is a rough superset of Java, you might be tempted to do something like:

def sayHello(name) {
        println("Hello $name!")
}

String[] names = {"SintSi", "Kaitlyn", "Keira"}

for (String name : names) {
    sayHello(name)
}

 

But this won’t work.  This is one place where Java syntax differs from Groovy’s. To create a static array, you’d instead do:

def sayHello(name) {
        println("Hello $name!")
}

String[] names = ["SintSi", "Kaitlyn", "Keira"]

for (String name : names) {
    sayHello(name)
}

 

As before, we can eliminate the type declarations:

def sayHello(name) {
        println("Hello $name!")
}

def names = ["SintSi", "Kaitlyn", "Keira"]

for (def name : names) {
    sayHello(name)
}

 

But a more Groovy way of doing the same thing would be to use the “in” keyword:

def sayHello(name) {
        println("Hello $name!")
}

def names = ["SintSi", "Kaitlyn", "Keira"]

for (name in names) {
    sayHello(name)
}

 

Note that under the hood, this code is no longer creating an array – rather, Groovy is (invisibly) creating an ArrayList.  This gives us a number of new options – for instance, sorting:

def sayHello(name) {
        println("Hello $name!")
}

def names = ["SintSi", "Kaitlyn", "Keira"]

names.sort()

for (name in names) {
    sayHello(name)
}

 

You can also add and remove entries to the list, like so:

def sayHello(name) {
        println("Hello $name!")
}

def names = ["SintSi", "Kaitlyn", "Keira"]

names += 'Jim'
names -= 'SintSi'
names.sort()

for (name in names) {
    sayHello(name)
}

 

But this still isn’t the way that many Groovy coders would do it. They’d probably use the built in method each, which takes a closure as an argument.  If you aren’t already familiar with closures (I knew them already from JavaScript), they’re similar in many ways to method pointers.  And you might as well start learning about them, they’re coming to Java (finally).  To use a closure, you define it using enclosing curly braces, and you can call it with the call method, like so:

def sayHello(name) {
        println("Hello $name!")
}

def clos = {name -> sayHello(name)}
clos.call('world')

 

This will print “Hello world!”.  Note that if you’re trying this in groovyConsole, you’ll see an additional value at the end – this is because Groovy scripts always return the last value as the return value, and groovyConsole is showing you the value of the names ArrayList.  In this example, the “name ->” preamble defines a single parameter that the closure takes.  Now let’s use the closure with the each method:

def sayHello(name) {
        println("Hello $name!")
}

def names = ["SintSi", "Kaitlyn", "Keira"]

names += 'Jim'
names -= 'SintSi'
names.sort()

def clos = {name -> sayHello(name)}
names.each(clos)

 

Under the covers, names.each is iterating through the collection, and passing each value to the closure as the first parameter, just as in our previous example.  We can simplify this by creating the closure in place.  And since in Groovy, method parenthesis are optional when the method takes one or more parameters, we can say:

def sayHello(name) {
        println("Hello $name!")
}

def names = ["SintSi", "Kaitlyn", "Keira"]

names += 'Jim'
names -= 'SintSi'
names.sort()

names.each {name -> sayHello(name)}

 

Which is pretty darn readable.  One more thing:  by default, the first parameter of a closure is named “it”.  So, you could instead say:

def sayHello(name) {
        println("Hello $name!")
}

def names = ["SintSi", "Kaitlyn", "Keira"]

names += 'Jim'
names -= 'SintSi'
names.sort()

names.each {sayHello(it)}

 

That’s it for now. If you’ve followed along so far, you’ve gotten more than enough Groovy under your belt to deal with anything you might see in my coming posts, as well as being able to say “Sure, more or less”, when someone says “Do you know any Groovy?”

 

Written by Jim Driscoll

March 17, 2012 at 7:50 AM

Posted in Groovy

A quick introduction to the Groovy language (part 1)

leave a comment »

Before I start talking about using Groovy’s capabilities to create a DSL (mostly in Java), let’s take a few minutes to go over what Groovy is.

Groovy is a general purpose scripting language which runs on the JVM, and can largely be viewed as a superset of Java.  Take the following program:

public class Hello {
    String name;
    
    public void sayHello() {
        System.out.println("Hello "+getName()+"!");
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public String getName() {
        return name;
    }
    
    public static void main(String[] args) {
    
        Hello hello = new Hello();
        hello.setName("world");
        hello.sayHello();
    }
}

Is this a Groovy program or a Java program?  Yes, it is – it will compile and run in both.  This basic program is a bit wordy, and we can certainly do things more simply in Java, but this contains a number of patterns that you’d commonly see, including the use of the bean pattern, as well as the use of the main method to make the class executable via the java command line program.    When we run it, it simply prints out “Hello world!”, as is customary in these sorts of things.

To try this out in Java, you can use your favorite IDE.  You can also use an IDE to try this in Groovy, but you may just want to use the groovyConsole program, which is available as part of the GDK.  Download it now, and play along via cut and paste…

Now, as I said, Groovy is a rough superset of Java – one difference is that things are public by default.  That means we could just as easily say the following:

class Hello {

    String name;
    
    void sayHello() {
        System.out.println("Hello "+getName()+"!");
    }
    
    void setName(String name) {
        this.name = name;
    }
    
    String getName() {
        return name;
    }
    
    static void main(String[] args) {
    
        Hello hello = new Hello();
        hello.setName("world");
        hello.sayHello();
    }
}

 

Accessors and mutators are automatically created for your class variables, so we can also shorten it by taking those out:

class Hello {

    String name;
    
    void sayHello() {
        System.out.println("Hello "+getName()+"!");
    }
    
    static void main(String[] args) {
    
        Hello hello = new Hello();
        hello.setName("world");
        hello.sayHello();
    }
}

 

Now we’re getting somewhere.  In Groovy, System.out.println can be shortened to just “println” as a convenience, so you can also say:

class Hello {

    String name;
    
    void sayHello() {
        println("Hello "+getName()+"!");
    }
    
    static void main(String[] args) {
    
        Hello hello = new Hello();
        hello.setName("world");
        hello.sayHello();
    }
}

 

There’s also a difference in how Groovy deals with String objects – double quote strings allow for variable substitution.  There’s also single quote strings, which do not:

class Hello {

    String name;
    
    void sayHello() {
        println("Hello $name!");
    }
    
    static void main(String[] args) {
    
        Hello hello = new Hello();
        hello.setName('world');
        hello.sayHello();
    }
}

 

Groovy also allows dot notation to get and set fields of classes, just like Java.  Unlike Java, this will actually go through the getter/setter methods (which, you’ll recall, are automatically generated in our current example):

class Hello {

    String name;
    
    void sayHello() {
        println("Hello $name!");
    }
    
    static void main(String[] args) {
    
        Hello hello = new Hello();
        hello.name = 'world';
        hello.sayHello();
    }
}

 

Typing information is also optional – instead of specifying a type, you can just use the keyword def.  Use of def is mandatory for methods, but optional for parameters on those methods.  You should also use def for class and method variables.  While we’re at it, let’s take out those semicolons:  They’re optional in Groovy.

class Hello {

    def sayHello(name) {
        println("Hello $name!")
    }
    
    static def main(args) {
        Hello hello = new Hello()
        def name = 'world'
        hello.sayHello(name)
    }
}

 

OK, that’s nice, but we can get this even shorter. Because Groovy is a scripting language, there’s automatically a wrapping class (called Script, which will become very important to us later). This wrapping class means that we can get rid of our own wrapping class, as well as the main method, like so:

def sayHello(name) {
    println("Hello $name!")
}
def name = 'world'
sayHello(name)

 

That’s all for now, I’ll do a second part to this later.  But for now, if someone asks you if you know Groovy, you can now say “Sure, a bit”.

Credit for the idea behind this post goes to Guillaume Laforge – I saw him give a variation of this as an intro to his talk at JavaOne, and loved it.

Written by Jim Driscoll

March 16, 2012 at 11:16 AM

Posted in Groovy

What is a DSL, anyway? Why should you care?

leave a comment »

As part of my job at Oracle, working on the ADFm portion of ADF,  I work on DSL features in Groovy.  (ADFm uses Groovy as its extensibility layer, in much the way that HTML pages use JavaScript.)  I’m interested in blogging about the (fairly neat) stuff I’ve learned, but now that I think of it, it’s quite possible that many people reading this won’t really know what a DSL is…  So let’s talk about that for  a minute.

DSL stands for Domain Specific Language, and it essentially means a purpose built language designed for a specific task:  HTML, Unix scripting, and SQL are three you’re almost certainly familiar with.  Contrast this with a a general purpose language, like Java, or for that matter, Groovy, where the language is open ended, and intended to deal with almost any task.  So far, simple enough, and this is all dealt with very adequately in the Wikipedia article on the topic.

But here’s the thing:  When you’re creating a DSL with Groovy (or, for that matter, with many metaprogramming languages), you’re not generally creating a limited language – you’re creating a domain aware extension to the existing general purpose language you’re using as a base – unless, of course, you do a great deal of additional work to disable the existing language features.

So, what to call such a beast?  What to call a domain aware general purpose language?  I’ve noticed that most people just call it a DSL, so that’s the convention I’ll follow in the following posts.  Computer science purists, please forgive me.

Why should you care about DSLs?  Why learn how to create one?  Well, I can only answer for me, but I can tell you that when I was a still a wee little programmer, the people who created the languages I used were people I really looked up to, and the idea of creating one of my own, or even just knowing how, is something that’s really exciting to me.  On a more practical side, if you have this in your toolbox, ways to use it present themselves all the time.  Want to create a really usable, readable testing framework around your Selenium tests?  A DSL may fit the bill.  Need to present a text heavy interface to your users for open-ended data entry?  A simple object definition language DSL seems appropriate.  And so on.  Like all techniques, it can be overused (factories, anyone?), but DSLs have their place.   Plus, it’s just so darn cool.

In the following series of posts, I’ll go over the basics of creating a DSL.  No Groovy knowledge will be required or assumed – just Java.  Follow along – I think you’ll like it.

Written by Jim Driscoll

March 12, 2012 at 7:22 PM

Posted in DSL

DSLs with Groovy JavaOne talk

leave a comment »

I’ve been neglecting my blog, but just a quick note to mention that my latest talk at JavaOne, DSLs with Groovy, is posted up on Slideshare.

The talk’s designed for someone with no significant Groovy experience (unlike most Groovy DSL talks), so if it’s interesting to you, check it out.

I’m hoping (but not promising) to turn the talk into a series of Blog entries in the coming weeks.  So if you want, just wait, and I’ll send you explanations in more digestible bits and pieces in the coming weeks.

 

Written by Jim Driscoll

March 10, 2012 at 1:28 PM

Posted in DSL, Groovy

Follow

Get every new post delivered to your Inbox.

Join 412 other followers