Tag: Groovy
Groovy and Closures
by RJ Salicco on Jan.10, 2010, under Development
Happy New Year! So it is 2010 and you still haven’t looked at Groovy or had fun developing with Closures? It is time to give it a try. Download Groovy (currently 1.7), setup a GROOVY_HOME variable, and add GROOVY_HOME/bin to your system path. Now open up a text editor, I like Textmate on my Mac and Notepad ++ when I am on a Windows machine, and create a new file, something like ClosureFun.groovy. Now let’s get some coding done. First, let’s add a class:
class Person {
def firstName
def lastName
def emailAddress
}
This is really not too difficult to understand, right? We have a class, Person, with three attributes; firstName, lastName and emailAddress. Now let’s create some instances of Person:
bob = new Person(firstName:"Bob", lastName:"Jones", emailAddress:"bob.jones@yahoo.com") rob = new Person(firstName:"Rob", lastName:"Fake", emailAddress:"rob.fake@gmail.com") ray = new Person(firstName:"Ray", lastName:"Real", emailAddress:"ray.real@gmail.com") tom = new Person(firstName:"Tom", lastName:"Real", emailAddress:"tom.real@yahoo.com") mike = new Person(firstName:"Mike", lastName:"Test", emailAddress:"mike.test@msn.com") drew = new Person(firstName:"Drew", lastName:"Wilkins", emailAddress:"dwilkins@aol.com")
We now have six instances of Person; bob, rob, ray, tom, mike and drew. Groovy supports these Map-like constructors and they are given to us just like Java gives us a no arg constructor by default if we do not create a constructor for our Java class. We also get new Person(firstName:”value”), new Person(lastName:”value”), new Person(emailAddress:”value”), new Person(firstName:”value”, emailAddress:”value”)… and the other permutations. This feature is quite nice. Now let’s create a list of Persons:
def list = [bob, rob, ray, tom, mike, drew]
Maybe the Groovy syntax is a little different than Java, but it is pretty easy to see how, in the code above, to create a list of Persons. Now, we have this instance of list, as in java.util.ArrayList, that now contains our instances of Person. We have created a class Person, we have our six instances of Person and they all exist in a list. What now?
Well, I want to be able to print out the values of firstName and lastName of particular instances of Person that are in the list. I want to print out the Person instances in our list where the firstName value begins with “R”. Then I want to be able to print out the Person instances in our list where the emailAddress contains “yahoo”. Someone else wants to print out the Person instances where the last letter in lastName is “e” and their friend wants the Person instances where the last letter in lastName is “s”. Should I write a method for each scenario that will take a list as a parameter and loop through each value and check for our desired condition then print the firstName and lastName? Sure, why not?
def printPersonsWithFirstNameBeginingWithR(list) {
list.each {
if(it.firstName.startsWith("R")) {
println "$it.firstName $it.lastName"
}
}
}
Our first method is done. If you are not familiar with Groovy, ‘list.each’ is like a ‘for’ loop in Java and ‘it’ is an implicit placeholder for each item in the list. In our case, ‘it’ represents a Person class. More information on syntax of Groovy can be found on the Groovy Web site.
def printPersonsWithEmailAddressContainingYahoo(list) {
list.each {
if(it.emailAddress.contains("yahoo")) {
println "$it.firstName $it.lastName"
}
}
}
def printPersonsWithLastNameEndingWithE(list) {
list.each {
if(it.lastName.getAt(-1) == "e") {
println "$it.firstName $it.lastName"
}
}
}
def printPersonsWithLastNameEndingWithS(list) {
list.each {
if(it.lastName.getAt(-1) == "s") {
println "$it.firstName $it.lastName"
}
}
}
That would work, right? Yeah, we could then write some code to call each method passing in our list and we would get what we want. Cool, we’re done. Wait, we need to support another condition. We need to support a request to print out all Person instances in our list where the emailAddress contains “gmail”. Well, I guess we should write another method? Why not?
def printPersonsWithEmailAddressContainingGmail(list) {
list.each {
if(it.emailAddress.contains("gmail")) {
println "$it.firstName $it.lastName"
}
}
}
In our case, we see a pattern emerging. The only thing that changes in each of the above methods is the name of the method and the conditional statement in the if block. Well, when we take advantage of Closures in Groovy we can ignore the 5 methods we wrote above and just write 1 method like the one below (yeah, 5 methods into 1):
def printPersons(list, clos) {
list.each() {
if(clos(it)) {
println "$it.firstName $it.lastName"
}
}
}
The above method looks just like our other 5 methods but we have changed our input parameters. Now we are expecting a list and a Closure as arguments and we evaluate the Closure parameter in the if block as our conditional statement (Closures can do more than return true or false). So how do we call our re-factored, re-written method? We now call the method passing is our list as a parameter and because the Closure is the last argument in the printPersons method, we can create our conditional Closure within brackets as you can see here:
// firstName starts with 'R'
printPersons(list) { it.firstName.startsWith("R") }
// emailAddress contains 'yahoo'
printPersons(list) { it.emailAddress.contains("yahoo") }
// last letter of lastName is 'e'
printPersons(list) { it.lastName.getAt(-1) == "e" }
// last letter of lastName is 's'
printPersons(list) { it.lastName.getAt(-1) == "s" }
Without getting into all the syntax and semantics of Groovy, we use ‘it’ again because it is a special implicit variable in Groovy used quite often with Closures and other Groovy code structures. In our case, ‘it’ will represent each Person instance in the loop, ‘list.each’. Now when we need to add that last minute request, well, it is already supported! Just pass the new condition.
// emailAddress contains 'gmail'
printPersons(list) { it.emailAddress.contains("gmail") }
Very cool stuff. Now, we can combine everything in one file, like ClosureFun.groovy and run the script. There are plenty of articles and blog posts all over the Internet about Groovy and Closures. I have learned quite a bit by attending presentations by people like Venkat Subramaniam, Scott Davis, Guillaume LaForge, Graeme Rocher, Jeff Brown and a few others. At the end of the day, it is all about getting your hands on Groovy, so get out there and write some code!
Hazelcast Groovyness
by RJ Salicco on Dec.10, 2009, under Development
Data distribution is a pretty cool topic. Recently, I have been working with Hazelcast, which is an open source clustering and data distribution platform for Java. Well, I really like what I have seen so far and I figured why not have some fun with Hazelcast and Groovy.
I started by adding the Hazelcast 1.7.1 jar to $GROOVY_HOME/lib. Hazelcast, at an introductory level, provides distributed implementations of java.util { Queue, List, Set, Map }. I can run a Groovy script on multiple JVM’s and I can share a Map of customers on each instance. For example:
def customersMap = Hazelcast.getMap("customers")
Now, I have an instance of Map and I can add values using Hazelcast’s distributed id generator:
def idGen = Hazelcast.getIdGenerator("customer-ids")
def id = idGen.newId()
customersMap.put(id, "Customer $id")
So, that was pretty simple, right? Here is the entire Groovy script HazelcastGroovynessAdd.groovy:
import com.hazelcast.core.Hazelcast
import com.hazelcast.core.IdGenerator
def customersMap = Hazelcast.getMap("customers")
def idGen = Hazelcast.getIdGenerator("customer-ids")
def id = idGen.newId()
customersMap.put(id, "Customer $id")
I can open up a few different command prompts and enter:
> groovy HazelcastGroovynessAdd.groovy
Now, the customers Map has a few customers in it and our Groovy scripts are still running. Let’s add an com.hazelcast.core.EntryListener to the customers Map so we can detect a com.hazelcast.core.EntryEvent. Here is HazelcastGroovyness.groovy:
import com.hazelcast.core.Hazelcast
import com.hazelcast.core.EntryListener
import com.hazelcast.core.EntryEvent
def listener = [
entryAdded: { EntryEvent ev ->
println "key $ev.key was added with value $ev.value to $ev.name"
Hazelcast.getMap("customers").values().each {
println it
}
},
entryUpdated: { EntryEvent ev -> },
entryRemoved: { EntryEvent ev -> },
entryEvicted: { EntryEvent ev -> }
] as EntryListener
def customersMap = Hazelcast.getMap("customers")
customersMap.addEntryListener(listener, true)
In the above code, we define listener which implements com.hazelcast.core.EntryListener. I now start up HazelcastGroovyness.groovy at a new command prompt(s):
> groovy HazelcastGroovyness.groovy
We can go back to our original HazelcastGroovynessAdd.groovy script and open (re-open) a few more command prompts and run the script that adds customers to the Map. Now in each running instance of HazelcastGroovyness.groovy we see something like:
key 2000001 was added with value Customer 2000001 to c:customers Customer 2000001 Customer 1000001 Customer 1
Hazelcast is very cool, easy to use technology that provides distributed data with a few lines of code, especially with Groovy. More information can be found at Hazelcast’s website and at the project site at Google Code.
SpringOne 2GX 2009 Day Four
by RJ Salicco on Oct.23, 2009, under Commentary
Unfortunately, all good things must come to end and that means it is time to pack my things, check-out of my hotel room in NOLA and catch a flight back to Tampa. The good thing is that the excitement of SpringOne / 2GX doesn’t have to end. I am little late to press with completing this post (MacBook battery, sleep, travel, work), but anyone who works with me or who lives with me can tell you that I am still amped about what I saw and experienced at SpringOne / 2GX.
At the beginning of day four, I checked out Hamlet D’Arcy’s presentation on Groovy and OSGI. I have seen a presentation at the Tampa JUG on OSGI, courtesy of my colleague, Vladimir Vivien and Hamlet’s presentation really helped me get a hold of the technology again. He is a wealth of knowledge and a talented software developer / presenter.
One of my favorite presenters, Venkat Subramaniam, discussed design patterns in Java and Groovy. It was a very useful presentation. Venkat is an incredible presenter and the content of his presentations are right on point. He knows what he is doing!
After lunch, I checked out Jeff Brown’s (SpringSource / Grails) presentation on using Grails without a browser. I really enjoyed Jeff’s presentations all week. It is awesome to hear about a technology that I feel passionate about from the source. As Jeff said, Grails is a Web framework but Grails really offers more that just rapid Web development, it is also a platform. He proved that in his presentation.
SpringOne / 2GX 2009 was a great event. My Rod Johnson bobble-head is already on my desk solving enterprise Java problems. The No Fluff Just Stuff crew and SpringSource hosted a great event, at a great venue, in a beautiful city. Looking forward to the 2010 event.
SpringOne 2GX 2009 Day Three
by RJ Salicco on Oct.22, 2009, under Commentary
Day three was an exciting day. I attended an awesome presentation about DSL’s in Groovy presented by Guillaume LaForge. I got to speak with him a bit, he is a great guy. I attended Christophe Coneraets and Jeremey Grelle’s presentation on the technical pieces of Flex and Spring. Flex is great (already knew that), but being able to make remote calls to Spring is where it’s at. Spring’s BlazeDS support is very Spring-like and that means you an leverage your spring knowledge to work with Flex remoting. I checked out Keith Donald’s presentation, “Working with Spring Web Flow”. I really like Web Flow. I like Web Flow with JSF because it makes sense when you have to use JSF and I also like the Web Flow hooks inside of Grails. Hamlet D’Arcy’s presentation, “Legacy Code, Groovy and You”, really spoke to me. Some of us work in environments that need to pay attention to some of his key points on re-factoring/re-writing and TESTING. At the end of the day, I attended “Groovy AST Transformations” with Venkat Subramaniam. First, he is a great speaker/presenter and I look forward to attending most of his presentations because he knows what he is doing. Second, AST transformations look really cool, but I need to let it digest a bit before I dig in. It is a great feature of Groovy, like MOP, but it can also be dangerous, like MOP, if you don’t know what you are doing. I am looking forward to attending “OSGI and Groovy Jump Start”, “Design Patterns in Java and Groovy” and “Grails Without a Browser” on the final day of the event.
