Jan 14

Groovy Closures

Groovy, Tech No Comments »

Mike has put together another well researched article on Groovy Closures.

He discusses what they are, how they work now, and some ideas on how he would fix them.

In Mikes world you would end up going from:

[1, 2, 3, 4].each { | param | println param }

to (params, clos keyword, no more |, no optional ;):

[1, 2, 3, 4].each (clos(param) { println param });

NOTE: Although Mike shows the form: { foo | … } Groovy supports { | foo | … } and has even talked about enforcing that.

I understand his points, and from a Java perspective it makes even more sense. However I think Charles Miller had a really good point… showing the power of perspective :)

Other things you complain about are very Ruby-like, but it helps to phrase them differently. For example, Ruby hackers wouldn’t say that a return statement was optional, they’d say that all methods return the value of the last statement in the method, but this behaviour can be overridden by an explicit return. (It’s a subtle difference of point-of-view).

Similarly, in Ruby, you wouldn’t say that semi-colons are optional. You’d say that the newline was the default statement separator, but you can force an end-of-statement with a semi-colon.

It is funny how actual work changes things. The more code I write in languages which don’t require a ‘;’ every 30 keystrokes, the more it bugs me when I have to go back to typing them, and more importantly seeing them on every line or so. What a load of clutter! :)

Jan 14

Why Groovy should have corporate backing: Fund development!

Groovy, Tech 1 Comment »

There has been another up-turn in critiques for Groovy. The like of Mike Spille, Hani, Cedric, and others, have ripped into the project.

People have asked me how I feel about it all, and I think they are a little surprised that I am not upset or something.

I am not upset as:

  • The opinions are not just rants. They are educated responses about how they feel about Groovy
  • Everyone is entitled to their opinion
  • They seem to actually care (else why spend the time)

The last point is so important. A lot of people, in and out of the Groovy community are giving honest feedback because they care.

Noone is saying: “Groovy is a piece of merde, so scrap it already!”.

If anything, the general vibe is:

“Groovy has so much potential. I seem some problems, and someone needs to get in and fix things before it is too late”.

I am a strong believer in the potential of Groovy. Even if the language ‘groovy’ fails, I think it has been part of a more important factor… having Sun, and Java some developers, realise that the power of Java is in the platform. Java shouldn’t be the One True Language. It is one way of expressing yourself, and is very good for many problems. But it is pretty balsy to say “This one way of expressing yourself is definitely the only way, and the best, for all”. Come on. A language like Groovy (and many others) has many advantages. One, is the way it can grow and ‘try’ ideas. Can you imagine how hard it is to get a feature into the Java language (cheap shot: unless you persuade Sun that Microsoft is doing it :)).

So, I am sold on the potential of Groovy. I enjoy many languages and platforms, and I am really excited about having a language as fun to work with and productive as Groovy on the JVM platform (so I also have access to Spring, Hibernate/JDO/…, AspectWerkz/AspectJ, etc etc).

So, to the subject of this post!

I think Groovy would be helped in LEAPS and BOUNDS if a company (or two :) got behind it. If Sun wants to make a play for other languages, why don’t they hire some people to work on Groovy? SURELY it is worth having people around to work on that compared to some of the other ‘research’ projects they are playing with? Sun already allows John Rose to work on Groovy, and I think they part for some of his time working on it. Make that fulltime. Hire James, or Guillame, or someone else.

Groovy needs a full time LEADER. James is just too busy at the moment to take it all on. Noone should EXPECT him too. How can we? Groovy needs the loose strings ironed out, and it needs some grunt work done such as:

  • Making it stable
  • Refactoring for the new ANTLR parse
  • Getting error reporting spot on, so you aren’t in debug hell
  • Solid, top notch, IDE Support (Eclipse/IntelliJ plugins)
  • Documentation

And it goes on and on. Sometimes you need to be working on a project full time, and having it be your focus, to get onto these tasks. This is where a company can come in.

BEA would be another great potential contributor. Maybe they could have even kept Sam Pullara if they just let him work on Groovy? ;)

A vendor can jump in and become a real leader in the dynamic language space. They could integrate with Groovy all over the shop, and I would certainly love them for it :)

The User Base Is There

From the talks that I give on Groovy, feedback I get, and the number of people jumping onto areas like Ruby, I have no doubt that people want functionality that Groovy can give them. Will anyone step up to the plate, take the potential energy, and run with it?

Jan 14

Why Groovy should have corporate backing: Fund development!

Groovy, Tech 1 Comment »

There has been another up-turn in critiques for Groovy. The like of Mike Spille, Hani, Cedric, and others, have ripped into the project.

People have asked me how I feel about it all, and I think they are a little surprised that I am not upset or something.

I am not upset as:

  • The opinions are not just rants. They are educated responses about how they feel about Groovy
  • Everyone is entitled to their opinion
  • They seem to actually care (else why spend the time)

The last point is so important. A lot of people, in and out of the Groovy community are giving honest feedback because they care.

Noone is saying: “Groovy is a piece of merde, so scrap it already!”.

If anything, the general vibe is:

“Groovy has so much potential. I seem some problems, and someone needs to get in and fix things before it is too late”.

I am a strong believer in the potential of Groovy. Even if the language ‘groovy’ fails, I think it has been part of a more important factor… having Sun, and Java some developers, realise that the power of Java is in the platform. Java shouldn’t be the One True Language. It is one way of expressing yourself, and is very good for many problems. But it is pretty balsy to say “This one way of expressing yourself is definitely the only way, and the best, for all”. Come on. A language like Groovy (and many others) has many advantages. One, is the way it can grow and ‘try’ ideas. Can you imagine how hard it is to get a feature into the Java language (cheap shot: unless you persuade Sun that Microsoft is doing it :)).

So, I am sold on the potential of Groovy. I enjoy many languages and platforms, and I am really excited about having a language as fun to work with and productive as Groovy on the JVM platform (so I also have access to Spring, Hibernate/JDO/…, AspectWerkz/AspectJ, etc etc).

So, to the subject of this post!

I think Groovy would be helped in LEAPS and BOUNDS if a company (or two :) got behind it. If Sun wants to make a play for other languages, why don’t they hire some people to work on Groovy? SURELY it is worth having people around to work on that compared to some of the other ‘research’ projects they are playing with? Sun already allows John Rose to work on Groovy, and I think they part for some of his time working on it. Make that fulltime. Hire James, or Guillame, or someone else.

Groovy needs a full time LEADER. James is just too busy at the moment to take it all on. Noone should EXPECT him too. How can we? Groovy needs the loose strings ironed out, and it needs some grunt work done such as:

  • Making it stable
  • Refactoring for the new ANTLR parse
  • Getting error reporting spot on, so you aren’t in debug hell
  • Solid, top notch, IDE Support (Eclipse/IntelliJ plugins)
  • Documentation

And it goes on and on. Sometimes you need to be working on a project full time, and having it be your focus, to get onto these tasks. This is where a company can come in.

BEA would be another great potential contributor. Maybe they could have even kept Sam Pullara if they just let him work on Groovy? ;)

A vendor can jump in and become a real leader in the dynamic language space. They could integrate with Groovy all over the shop, and I would certainly love them for it :)

The User Base Is There

From the talks that I give on Groovy, feedback I get, and the number of people jumping onto areas like Ruby, I have no doubt that people want functionality that Groovy can give them. Will anyone step up to the plate, take the potential energy, and run with it?

Jan 05

Scripting COM with Groovy

Groovy, Tech No Comments »

I saw a link to COM Scripting via James’ blog.

Scriptom is an optional Groovy module developed by Guillaume Laforge leveraging the Jacob library (JAva COm Bridge). Once installed in your Groovy installation, you can use a wrapper to script any ActiveX or COM component from within your Groovy scripts. Of course, this module can be used on Windows only.

Scriptom is especially interesting if you are developing Groovy shell scripts under Windows. You can combine both Groovy code and any Java library with the platform-specific features available to Windows Scripting Host or OLE COM automation from Office.

Nice work Guillaume. Dynamic languages offer a cool alternative for working with IE, Word, Excel, and any other component!

Jan 05

Syncing up your IntelliJ IML files with Maven and Groovy

Builds, Groovy, Tech No Comments »

I often use the Maven IntelliJ plugin to create project files (.ipr/.iml/.iws).

A quick:

% maven idea

does the job nicely.

However, when dependencies change, I don’t want to re-run the idea task, as it wacks a lot of project settings that I may have had. What I really want to do is take the current .iml file, and tweak the classpath which has entries such as:

<orderEntry type="module-library">
<library name="asm">
<CLASSES>
<root url="jar://C:/Documents and Settings/Dion/.maven/repository/asm/jars/asm-1.4.3.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>

So, I put together a quick groovy script which does just this.

#!/bin/env groovy
# -----------------------------------------------------------------------------
# ideaSync.g: Take a given project.xml and an IntelliJ IDEA .iml file,
#             and sync up the dependencies
# -----------------------------------------------------------------------------

import groovy.util.XmlParser
import java.io.File
import java.io.OutputStream
import java.util.*

import org.dom4j.Document
import org.dom4j.io.XMLWriter
import org.dom4j.io.OutputFormat

# -- Enforce the project.xml and dir
if (args.length < 3) {
println """
Usage: ideaSync.g project.xml
.iml /path/to/maven/repo

e.g. ideaSync.g /foo/project.xml /foo/project.iml /www/adigio/maven
"""
System.exit(1)
}

# -- Variables
projectxml   = args[0]
intellijxml  = args[1]
mavenRepoDir = args[2]
indent       = 0

# -- Open up the IntelliJ
.iml file
intellij = new XmlParser().parse(intellijxml)

# -- Open up the project.xml file and get the dependencies, and create an updated XML node
project = new XmlParser().parse(projectxml)

# -- Build the order entries
orderEntries = []

project.dependencies.dependency.each {
groupId    = it.groupId[0].text()
artifactId = it.artifactId[0].text()
version    = it.version[0].text()

orderEntry = buildOrderEntry(groupId, "jar://${mavenRepoDir}/${groupId}/jars/${artifactId}-${version}.jar!/")

orderEntries += orderEntry
}

# -- Grab Order Entries
intellij.module.component.each { | c |
if (c['@name'] == 'NewModuleRootManager') {
oldOrderEntries = c.findAll { !it.orderEntry }
c = orderEntries
}
}

# -- Print the Header
println ''

outputDOM(intellij)

# -----------------------------------------------------------------------------
#  From the given group ID and URL, return an Order Entry node
# -----------------------------------------------------------------------------
def buildOrderEntry(groupId, url) {
# -- Builder
builder = new groovy.util.NodeBuilder()

return builder.orderEntry(type: 'module-library') {
library(name: groupId) {
CLASSES() {
root(url: "jar://${mavenRepoDir}/${groupId}/jars/${artifactId}-${version}.jar!/")
}
JAVADOC()
SOURCES()
}
}
}

# -----------------------------------------------------------------------------
#  Recursive function which outputs a node, and then child nodes
# -----------------------------------------------------------------------------
def outputDOM(node) {
String tagName = node.name()
Object tagValue = node.value()
boolean hasChildren = false;
String attributes = ""

printIndent()

print "<${tagName}"

# -- Print out any attributes
node.attributes().each { |entry|
attributes = " ${entry.key}=\"${entry.value}\"" + attributes
}
print attributes

if (tagValue instanceof String) {
println "${tagValue}"
hasChildren = true;
}

List children = node.children()

if (children != null && !children.isEmpty()) {
hasChildren = true
}

println( (hasChildren) ? ">" : " />" )

for (child in children) {
indent++
outputDOM(child)
indent--
}

if (hasChildren) {
printIndent()
println ""
}
}

# -----------------------------------------------------------------------------
#  Print out the correct indent
# -----------------------------------------------------------------------------
def printIndent() {
print "  " * indent
}

I was hoping that I could use the NodePrinter that is already in Groovy, but it prints out the nodes like foo() { bar(); …. not in XML.

I think it would be good to have an XMLNodePrinter, or just have a toXML() method in the NodePrinter to do that work, as I think this script follows a common pattern:

  • Suck in an XML document into nodes
  • Munge the nodes in some way
  • Print out the new XML document

I would also really like to add this functionality to the maven plugin itself, so I could:

% maven idea:resynciml

or something like that. I think I will wait for m2 though, and see if I can use something other than Jelly for it? ;)

Jan 05

Syncing up your IntelliJ IML files with Maven and Groovy

Builds, Groovy, Tech No Comments »

I often use the Maven IntelliJ plugin to create project files (.ipr/.iml/.iws).

A quick:

% maven idea

does the job nicely.

However, when dependencies change, I don’t want to re-run the idea task, as it wacks a lot of project settings that I may have had. What I really want to do is take the current .iml file, and tweak the classpath which has entries such as:

<orderEntry type="module-library">
<library name="asm">
<CLASSES>
<root url="jar://C:/Documents and Settings/Dion/.maven/repository/asm/jars/asm-1.4.3.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>

So, I put together a quick groovy script which does just this.

#!/bin/env groovy
# -----------------------------------------------------------------------------
# ideaSync.g: Take a given project.xml and an IntelliJ IDEA .iml file,
#             and sync up the dependencies
# -----------------------------------------------------------------------------

import groovy.util.XmlParser
import java.io.File
import java.io.OutputStream
import java.util.*

import org.dom4j.Document
import org.dom4j.io.XMLWriter
import org.dom4j.io.OutputFormat

# -- Enforce the project.xml and dir
if (args.length < 3) {
println """
Usage: ideaSync.g project.xml
.iml /path/to/maven/repo

e.g. ideaSync.g /foo/project.xml /foo/project.iml /www/adigio/maven
"""
System.exit(1)
}

# -- Variables
projectxml   = args[0]
intellijxml  = args[1]
mavenRepoDir = args[2]
indent       = 0

# -- Open up the IntelliJ
.iml file
intellij = new XmlParser().parse(intellijxml)

# -- Open up the project.xml file and get the dependencies, and create an updated XML node
project = new XmlParser().parse(projectxml)

# -- Build the order entries
orderEntries = []

project.dependencies.dependency.each {
groupId    = it.groupId[0].text()
artifactId = it.artifactId[0].text()
version    = it.version[0].text()

orderEntry = buildOrderEntry(groupId, "jar://${mavenRepoDir}/${groupId}/jars/${artifactId}-${version}.jar!/")

orderEntries += orderEntry
}

# -- Grab Order Entries
intellij.module.component.each { | c |
if (c['@name'] == 'NewModuleRootManager') {
oldOrderEntries = c.findAll { !it.orderEntry }
c = orderEntries
}
}

# -- Print the Header
println ''

outputDOM(intellij)

# -----------------------------------------------------------------------------
#  From the given group ID and URL, return an Order Entry node
# -----------------------------------------------------------------------------
def buildOrderEntry(groupId, url) {
# -- Builder
builder = new groovy.util.NodeBuilder()

return builder.orderEntry(type: 'module-library') {
library(name: groupId) {
CLASSES() {
root(url: "jar://${mavenRepoDir}/${groupId}/jars/${artifactId}-${version}.jar!/")
}
JAVADOC()
SOURCES()
}
}
}

# -----------------------------------------------------------------------------
#  Recursive function which outputs a node, and then child nodes
# -----------------------------------------------------------------------------
def outputDOM(node) {
String tagName = node.name()
Object tagValue = node.value()
boolean hasChildren = false;
String attributes = ""

printIndent()

print "<${tagName}"

# -- Print out any attributes
node.attributes().each { |entry|
attributes = " ${entry.key}=\"${entry.value}\"" + attributes
}
print attributes

if (tagValue instanceof String) {
println "${tagValue}"
hasChildren = true;
}

List children = node.children()

if (children != null && !children.isEmpty()) {
hasChildren = true
}

println( (hasChildren) ? ">" : " />" )

for (child in children) {
indent++
outputDOM(child)
indent--
}

if (hasChildren) {
printIndent()
println ""
}
}

# -----------------------------------------------------------------------------
#  Print out the correct indent
# -----------------------------------------------------------------------------
def printIndent() {
print "  " * indent
}

I was hoping that I could use the NodePrinter that is already in Groovy, but it prints out the nodes like foo() { bar(); …. not in XML.

I think it would be good to have an XMLNodePrinter, or just have a toXML() method in the NodePrinter to do that work, as I think this script follows a common pattern:

  • Suck in an XML document into nodes
  • Munge the nodes in some way
  • Print out the new XML document

I would also really like to add this functionality to the maven plugin itself, so I could:

% maven idea:resynciml

or something like that. I think I will wait for m2 though, and see if I can use something other than Jelly for it? ;)

Dec 09

Good news for the Java platform: Sun holds Dynamic Languages Summit

Groovy, Java, Tech 11 Comments »

A lot of people in the community have been bugging Sun that they need to shake off the “Java == the language” view, and think more about the platform.

Tim Bray definitely saw this, and he pulled together a summit between top dynamic languages folk, and the main Sun Java players.

As soon as I heard about the summit I was really excited. When smart people get together good things happen. And it sounds like they did. Hey, there was even talk of adding an opcode here and there if it really made sense!

On Tuesday a summit was held at Sun, “with a few of our internal Java leaders, and on the dynamic-languages side, Larry Wall and Dan Sugalski (Perl and Parrot), Guido van Rossum, Samuele Pedroni and Sean McGrath (Python), and James Strachan (Groovy)”.

There were a couple of action items to report back on this or that, but the take-aways were pretty clear. For my money, the important thing about the meeting was bridge-building; the dynamic-language guys now know who to shout at in Javaland, and the Java guys know who in dynamic-language land to pester about what works and what doesn

Dec 01

Groovy mavenisms again: Building a lib dir from dependencies

Builds, Groovy, Tech 1 Comment »

To follow on in the same vein as my last post, I also have had the need now and then to take my maven world, and build a lib directory snapshot of my projects dependencies to pass on to others.

This was used with people not using maven, and for awhile for my IDE to point too (although now I can % maven idea). The only annoying part of maven idea is that it whipes your config each time, and you can’t share the project as the files are all absolute to your own personal maven repo.

Maven Jar Builder

#!/bin/env groovy
# -----------------------------------------------------------------------------
# maven2jar.g: Take a given project.xml and build a directory with jar files
# -----------------------------------------------------------------------------

import groovy.util.XmlParser
import java.io.*
import java.nio.channels.*

# -- Enforce the project.xml and dir
if (args.length < 1) {
println """
Usage: maven2jar.g project.xml [newdir]

e.g. maven2jar.g /foo/project.xml tempdir (defaults to .)
"""
System.exit(1)
}

# -- Variables
projectxml   = args[0]
todir        = (args.length > 1) ? args[1] : ".";
badFiles     = []
mavenLocalRepository = System.getProperty("user.home") + "/.maven/repository"

# -- Open up the file and do the work
project = new XmlParser().parse(projectxml)

project.dependencies.dependency.each {
groupId    = it.groupId[0].text()
artifactId = it.artifactId[0].text()
version    = it.version[0].text()

fromFileName = "${mavenLocalRepository}/${groupId}/jars/${artifactId}-${version}.jar"
toFileName   = "${todir}/${artifactId}-${version}.jar"

println "-----------------------------------------------------------------------"
println " Copying From: ${fromFileName}"
println " Copying To  : ${toFileName}"

try {
copyFile(new File(fromFileName), new File(toFileName))
} catch (Exception e) {
println "Error: Could not copy: ${e}"
}
}

# -- Define the function to copy the files
def copyFile(inFile, outFile) {
FileChannel sourceChannel = new FileInputStream(inFile).getChannel()
FileChannel destinationChannel = new FileOutputStream(outFile).getChannel()
sourceChannel.transferTo(0, sourceChannel.size(), destinationChannel)
sourceChannel.close()
destinationChannel.close()
}
Nov 30

Checking my maven repository with Groovy

Builds, Groovy, Tech 8 Comments »

I am finding myself grabbing Groovy rather than Perl for some of those small scripting tasks that you run into.

One I ran into recently revolved around my maven repository.

We setup our own Maven repo (we don’t want to keep hitting the poor ibiblio site!), and whenever we add dependencies, we grab the files from ibiblio and put them in our own repo.

However, it is easy to forget, so I whipped up a script that will check the dependencies in our project.xml and make sure those files exist in the repo, else it will shout at me to do the move.

It would also be cool to have it automatically do the copy itself!

I really like how you can whip through XML

Groovy Maven Script

#!/bin/env groovy
# -----------------------------------------------------------------------------
# mavenTestRepository.g: Take a given project.xml and a Maven repo, shout out
#                        which files are there, and which are not
# -----------------------------------------------------------------------------

import groovy.util.XmlParser
import java.io.File

# -- Enforce the project.xml and dir
if (args.length < 2) {
println """
Usage: mavenTestRepository.g project.xml mavenRepoDir

e.g. mavenTestRepository.g /foo/project.xml /www/adigio/maven
"""
System.exit(1)
}

# -- Variables
projectxml   = args[0]
mavenRepoDir = args[1]
badFiles     = []

# -- Open up the file and do the work
project = new XmlParser().parse(projectxml)

project.dependencies.dependency.each {
groupId    = it.groupId[0].text()
artifactId = it.artifactId[0].text()
version    = it.version[0].text()

println "-----------------------------------------------------------------------"
println " Group ID    : ${groupId}"
println "  Artifact ID: ${artifactId}"
println "  Version    : ${version}"

boolean fileExists = true
try {
new File("${mavenRepoDir}/${groupId}/jars/${artifactId}-${version}.jar").eachLine { }
} catch (Exception e) {
fileExists = false
}

if (fileExists) {
println "Good: File exists in repo"
} else {
badFiles += ["${groupId}: ${artifactId}-${version}"]
println "Bad: File DOES NOT exist in repo"
}
}

# -- Print out the bad ones
if (badFiles.size() > 0) {
println "\n-----------------------------------------------------------------------"
println "Dependencies not in the repository:\n"
badFiles.each { println it }
}
Nov 29

How closures and the like make me think differently

Groovy, Tech 118 Comments »

Each language and environment that you program in tends to have a feel. When you are deep into one community, you take on its “slang”.

This can be good, as you can learn a lot, and it can be a good way to communicate. However, it is good to visit other countries and learn other cultures.

Here is one small example of how I may write different code in Java, now that I also live in other communities such as Groovy, LISP, etc.

I was looking at a project, which had a lot of conversion code, to pretty-print contents of arrays, collections, and the like.

The way the team handled it was to have a bunch of methods on the model objects which would iterate through their collections/arrays and would built a nice String.

I would think of this problem differently:

  • What is consistent? The formatting of the elements is always the same
  • What varies? The actual data that you want to display

Now, you could of course, grab a Jakarta Commons library to spew the info out for you, but if you want to control it yourself I would do the following:

Put the common code in one place

PrettyPrinter.java has methods such as:

String convertCollectionToString(Collection theCollection, StringConversionFormatter formatter);

String convertArrayToString(Collection theCollection, StringConversionFormatter formatter);

Put the varied code in via a closure

The StringConversionFormatter interface encapsulates the variety. So, to do a conversion of a Role domain object I would have something like:

String result = PrettyPrinter.convertCollectionToString(roles, new StringConversionFormatter() {
public String format(Object o) {
return ((Role)o).getName();
}
});

Man I wish we could have PrettyPrinter.convertCollectionToString(roles, { return o.name })

;)