Atenção: esse artigo tem um vídeo complementar. Clique e assista!
Apresenta uma introdução a linguagem dinâmica Groovy, que possibilita ter uma produtividade de linguagens dinâmicas como Python e Ruby dentro da máquina virtual Java, sem emendas.
Para que serve:
Tornar o desenvolvimento em Java mais rápido e produtivo, além de apresentar novos conceitos, como closures, não disponíveis na linguagem Java, que podem facilitar a vida do desenvolvedor em tarefas corriqueiras.
Em que situação o tema é útil:
Para agilizar o desenvolvimento de aplicações Java, otimizando situações onde a mesma é muito verbosa, como manipulação de XML por exemplo. Groovy possibilita, através de mecanismos como closures, uma sintaxe mais limpa e produtividade em alto nível.
Um pouco de Groovy:
É possível programar para a plataforma Java sem usar a linguagem Java, e ainda por cima ser extremamente produtivo. Groovy é uma linguagem dinâmica, flexível e que se integra com Java sem emendas, além de fornecer recursos como closures e atribute accessors, não disponíveis na linguagem padrão da JVM. Groovy, ao contrario de outras linguagens dinâmicas, possibilita gerar bytecodes Java e possibilita o uso de toda a infra-estrutura já desenvolvida para suas aplicações.
Linguagens dinâmicas estão na moda já há algum tempo. Desde o advento de frameworks de alta produtividade como o Ruby on Rails e o Django, linguagens como Ruby e Python saíram de seus nichos e passaram a fazer parte das rodinhas de conversa de desenvolvedores Java, outrora um tanto quanto seletivos. Esses, então, descobriram um admirável novo mundo, com closures, tipos de dados complexos e facilidades que não existem na sua linguagem preferida. Foi mais ou menos nesse meio que surgiu o embrião do que viria a ser o Groovy.
Como tudo começou
No dia 29 de agosto de 2003 James Strachan publicou em seu blog o primeiro artigo sobre aquilo que viria a ser o Groovy (veja em Links o endereço do post). Ele deixava bem claro as suas intenções na época: “minha idéia inicial é fazer uma pequena linguagem dinâmica, que seja compilada diretamente em classes Java e que tenha toda a produtividade elegante encontrada em Ruby e Python, mas que permita reusar, estender, implementar e testar código Java já existente”.
James procurava uma linguagem dinâmica para desenvolver em plataforma Java, e em seu post ele deixava claro que as opções da época não eram interessantes. Ele não queria apenas uma linguagem dinâmica, mas sim algo que pudesse ser integrado ao que ele já tinha pronto em Java, algo que acelerasse seu desenvolvimento e que não o obrigasse a jogar tudo o que tinha de código Java já pronto e testado (e em produção) no lixo. Enfim, ele queria algo que não existia na época.
Mas como querer é poder, James uniu-se a Bob McWhirter e juntos fundaram o projeto Groovy em 2003. Logo, com um grupo de pessoas que compartilhavam da mesma idéia, iniciaram o desenvolvimento da linguagem. Foi em 2004, com a fundação do GroovyOne e a entrada de outros desenvolvedores (entre eles Guillaume Laforge – hoje o mantenedor do projeto) que a coisa decolou. Foi criada a Groovy Language Specification (GLS) e o kit para testes de compatibilidade (o TCK), além do parser básico da linguagem. O embrião do projeto estava pronto e a partir daí não teria mais como voltar atrás.
Groovy evoluiu desconhecido por algum tempo, e até dezembro de 2007 várias versões foram lançadas sob o número 1.1.x. Em 7 de dezembro de 2007 a versão final da família 1.1 foi lançada, e então nomeada Groovy 1.5 devido às diversas modificações realizadas na mesma. Hoje a linguagem é uma especificação do JCP (JSR 241) e é considerada a segunda linguagem oficial da plataforma.
Ao contrario do que alguns pensam, Groovy não é um concorrente do Java, mas uma ferramenta de apoio, de produtividade, como veremos neste artigo.
O que é e pra que serve o Groovy?
O web site oficial da linguagem possui uma das melhores definições sobre a linguagem, a qual reproduzo a seguir: “Groovy é uma linguagem ágil e dinâmica para a Plataforma Java com recursos que são inspirados em linguagens como Python, Ruby e Smalltalk, tornando-os disponíveis aos programadores Java, usando uma sintaxe mais próxima do Java”. Ou seja, Groovy possui uma sintaxe semelhante ao Java, mas com o poder de linguagens dinamicamente tipadas.
Mas Groovy não é apenas uma linguagem de script. Groovy pode ser compilada, gerando bytecodes Java, ou seja, um arquivo de código fonte Groovy pode virar um arquivo .class (e esse recurso você não encontra por exemplo no JRuby). Isso garante que a única coisa que você precisa para rodar seus códigos Groovy no ambiente de produção é a máquina virtual Java (ou seja, nada mais do que usualmente já precisaria) e o jar com o runtime e API`s do Groovy. É comum dizer que Groovy roda integrado com o Java sem emendas, o que não acontece com seus “concorrentes”, por assim dizer.
Mais do que isso, o Groovy é totalmente integrado ao Java no mais baixo nível. Por exemplo, se você instanciar um objeto do tipo Date em Groovy esse nada mais é do que uma instância de java.util.Date. E tudo funciona de maneira transparente por que, por debaixo dos panos, tudo é bytecode Java.
Aí você me pergunta “ok, então pra que eu preciso disso?”, e a resposta é simples: para facilitar sua vida. Groovy possui uma sintaxe mais simples e enxuta do que o Java, apesar de ainda parecer Java, e possui recursos poderosos que não são encontrados na linguagem Java, como closures. E Groovy possui um grande aliado, o Grails, um framework de produtividade baseado em Spring e Hibernate que permite o desenvolvimento de aplicações Java EE com a mesma agilidade do pessoal do Ruby on Rails (e sem configurar centenas de arquivos XML!).
Outro ponto importante é que ambos, Groovy e Grails, são hoje propriedades da SpringSource, empresa que mantém o framework Spring. A empresa adquiriu a G2One, que cuidava de ambos, em 11 de novembro de 2008 e em seu site (novamente na seção Links) é possível ver uma nota interessante sobre o assunto.
O que preciso para desenvolver em Groovy?
Como qualquer outra linguagem, para desenvolver em Groovy você precisa de um editor de textos, de um interpretador/compilador e outras ferramentas. Felizmente o NetBeans nos fornece tudo o que precisamos (e até mais) num único pacote.
O NetBeans é uma excelente IDE mantida pela Sun e desenvolvida por uma grande comunidade ao redor do mundo. Ela possui suporte nativo a Java, C/C++, PHP, JavaScript, Ruby e Groovy. Para este artigo vou usar a versão 6.5 da IDE rodando no Mac OS X versão 10.5.6. Você pode baixar gratuitamente o NetBeans de seu site (veja o endereço no quadro Links).
Caso deseje usar o Eclipse (que também suporta Groovy via plugins) ou outra IDE para testar os códigos deste artigo, ou mesmo um editor de textos simples como o GEdit do Gnome ou o Notepad do Windows, você deverá configurar o ambiente. Para isso recomendo que acesse a página do projeto na internet. Porém, caso ainda não use o NetBeans, dê uma chance a ele. Essa é a oportunidade de conhecer duas ferramentas novas e de alta qualidade ao mesmo tempo.
Alô mundo
Vamos começar nossa viagem pelo admirável mundo novo do Groovy com um exemplo extremamente simples. Sou fã do tradicional Alô mundo, apesar de ser um exemplo simples para iniciar numa linguagem. No nosso caso ele será suficiente para apresentar muitos recursos, como attribute accessors, como usar Groovy dentro do Java e muito mais.
Abra o NetBeans (ou o ambiente de sua escolha) e crie uma nova aplicação Java. Você verá uma categoria Groovy na janela de Novo Projeto, mas ela tem apenas um template para a criação de um projeto Grails. Como este não é o escopo deste artigo vamos ignorar essa categoria de projetos. Para isso use a categoria Java, como na Figura 1.
Figura 1. Criação de um novo projeto Java.
Clique no botão Próximo e então informe um nome para seu aplicativo (eu usei o singelo nome “AloMundoGroovy”) e selecione onde o deseja salvar. Clique em Finalizar e seu aplicativo será criado. Até agora não colocamos nem um pouco de Groovy no projeto, ele é um tradicional e simples projeto de aplicação Java que você já conhece.
Vamos adicionar então o Groovy ao projeto. Para isso clique com o botão de atalho do mouse sobre o projeto e selecione o menu Propriedades. Na janela que será aberta selecione o item Groovy na lista de categorias e marque a opção Ativar Groovy, como na Figura 2.
Figura 2. Adicionando Groovy ao projeto.
Agora nosso projeto já possui Groovy em sua estrutura. Perceba, na Figura 3, que, no grupo Categorias, no navegador do projeto, foi adicionado o groovy-all.jar, que é quem faz a “mágica” para nós.
Figura 3. Nosso projeto agora tem Groovy.
Por padrão o NetBeans criará um arquivo .java no nosso projeto. Remova-o pois não o usaremos, e então crie um pacote chamado org.groovy.maonamassa para adicionarmos os códigos-fonte de nosso projeto. Dentro desse pacote adicione um novo JFrame e, na janela de design do NetBeans, adicione uma caixa de texto ao JFrame, como na Figura 4.
Figura 4. Um JFrame com uma caixa de texto dentro.
Agora vamos adicionar um arquivo .groovy em nosso projeto. Para isso clique sobre o pacote criado e clique com o botão de atalho do mouse. Selecione então a opção Novo>Outro, e na janela que será aberta, na categoria Groovy, selecione Classe do Groovy. Nomeie-a como considerar mais interessante, sem a necessidade de ser o nome da classe principal, pois Groovy não faz essa diferenciação como o Java.
Vamos adicionar o código à nossa classe Groovy. Para isso, digite o código da Listagem 1.
Listagem 1. Nossa classe Groovy
package org.groovy.maonamassa
class AloMundoGroovy {
def saudacao = "Alô mundo, em Groovy !!!!"
}
Perceba que não usamos ponto-e-vírgula no final de nossa declaração, e que usamos a palavra reservada def na criação de nosso objeto (sim, objeto, da classe Object). O restante deve ser conhecido para programadores Java. Nossa classe Groovy está pronta para uso. Basta editarmos o código de nosso JFrame para colocar tudo em funcionamento. O código do JFrame deverá ficar como apresentado na Listagem 2.
Listagem 2. O código de nosso JFrame
package org.groovy.maonamassa;
public class MostrarJFrame extends javax.swing.JFrame {
AloMundoGroovy meuAloMundo = new AloMundoGroovy();
/** Creates new form MostrarJFrame */
public MostrarJFrame() {
initComponents();
String aloMundo = meuAloMundo.getSaudacao().toString();
jTextField1.setText(aloMundo);
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jTextField1 = new javax.swing.JTextField();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
getContentPane().add(jTextField1, java.awt.BorderLayout.CENTER);
pack();
}// </editor-fold>
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new MostrarJFrame().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JTextField jTextField1;
// End of variables declaration
}
Repare na linha em negrito, é nela que chamamos o método getSaudacao() de nossa classe Groovy. Se você olhou o código da Listagem 1 e não achou esse método não se preocupe, ele é criado através de um recurso comum no Groovy e no Ruby, que é chamado attribute accessor. Esse recurso cria os getters e setters para propriedades de uma maneira simples e eficaz, sem excesso de código. Isso acontecerá sempre que você definir um membro de sua classe sem especificar a visibilidade (protected, public ou private): o Groovy o considera como uma propriedade e define automaticamente os getters e setters.
A mesma classe da Listagem 1, escrita em Java, teria o dobro do tamanho. Veja na Listagem 3.
Listagem 3. Nossa classe AloMundoGroovy em Java – um tanto quanto “prolixo”, não acha?
package org.groovy.maonamassa;
public class AloMundoJava {
String saudacao = new String();
public String getSaudacao() {
return saudacao;
}
public void setSaudacao(String saudacao) {
this.saudacao = saudacao;
}
}
Note que parte de nosso projeto foi feito em Java (para tirar proveito do editor visual do IDE), mas uma parte foi feita em Groovy (e isso deixou as coisas mais simples – uma linha ao invés de sete), e ambos funcionam bem juntos, como é possível ver na Figura 5.
Figura 5. Nosso projeto em execução.
O leitor mais atento deve ter reparado no .toString() junto ao nosso método getSaudacao(), mostrado na Listagem 2, o que mostra que tanto o getter como o setter de saudacao trabalham com um Object. Isso se deve ao fato de que não definimos o tipo de nosso objeto no momento da sua criação com o def. Para corrigir, modifique o código Groovy para ficar como o da Listagem 4 e remova o .toString() da Listagem 2. Verifique que agora ambos os métodos getter e setter trabalham com String e não com Object. É possível ser menos verboso ainda e deixar de utilizar o def, pois ele pode ser omitido quando especificamos o tipo do objeto.
Listagem 4. Nossa classe Groovy modificada
package org.groovy.maonamassa
class AloMundoGroovy {
// aqui você pode omitir o def
def String saudacao = "Alô mundo, em Groovy !!!!"
}
GDK
Assim como o Java possui a JDK, o Groovy possui a GDK. É fácil confundir-se quando pensamos nisso pois todo objeto Java pode ser usado dentro do Groovy, mas o contrario não é verdade. A GDK estende a JDK adicionando métodos que não existem originalmente nos objetos Java.
Um exemplo seria como obter o tamanho de uma determinada instancia de uma classe. Em Java isso é bem confuso pois existem objetos que usam o método length() (como os que são instancias de arrays e Strings), outros usam o método size() (como os que são instancias de Collections e Maps). Temos até um getLength() (para java.lang.reflect.Array) e o método groupCount(), para instancias da classe Matcher.
Groovy, através de um dispositivo chamado MetaClass, possibilita que todos esses objetos utilizem um mesmo método para obter o tamanho de um objeto: o size(). Isso possibilita termos o código da Listagem 5, onde temos tanto um ArrayList quanto uma String usando o mesmo método, o size().
Listagem 5. O poder de fogo do GDK
class TestaSize {
public def imprime() {
String teste = "isso é um teste"
ArrayList meuArray = new ArrayList()
meuArray.add(teste)
println teste.size()
println meuArray.size()
}
}
Outra vantagem do GDK sobre a biblioteca padrão do Java é que Groovy não diferencia entre tipos primitivos e objetos. Em Groovy a expressão valor01 + valor02, considerando valor01 e valor02 do tipo java.lang.Integer, retorna a soma dos dois inteiros. Mas o Groovy vai além, definindo uma equivalência entre operadores e métodos: no caso, a expressão acima será interpretada como valor01.plus(valor02). Se você quiser criar novas classes com suporte a operadores, basta definir nela o método que será chamado para cada operação (para + o método é o plus(), para – o método é o minus(), para ++ é next() e por aí vai – consulte a documentação do Groovy para a lista de métodos e operações correspondentes).
Pense na utilidade prática disso. Quantas vezes você já não teve uma classe em que seria conveniente usar o operador + para somar uma instância com outra e teve que apelar para métodos mirabolantes como somaClasse() ou append()? Em Groovy basta definir o método correto e, ao avaliar a operação, o Groovy procura o método correspondente.
Isso só é possível por que o Groovy usa o conceito de MetaClass apresentado acima. Quando o compilador encontra uma expressão como valor01 + valor02 num código Groovy, ele gera um bytecode diferente do que gera quando encontra essa mesma expressão num arquivo de código Java, pois chamadas de métodos são redirecionadas pelo MetaClass do objeto, o que possibilita ao Groovy interceptar, adicionar, redirecionar e remover código em tempo de execução. É esse truque que possibilita valor01 + valor02 tornar-se valor01.plus(valor02) em tempo de execução.
Claro que todo esse poder tem um preço: um código Groovy é ligeiramente mais lento do que um código Java durante a execução, mas nada que torne proibitivo seu uso. Fazendo uma analogia, num comparativo com o desenvolvimento para sistemas operacionais, a JVM seria nosso sistema operacional, e ao desenvolver optaríamos por Java quando precisamos de velocidade, e por Groovy quando precisamos de facilidades e performance não é um dos requisitos principais. Pode parecer, com todo esse parágrafo, que Groovy é um elefante pesado e lento, mas Groovy é apenas um pouco mais lento que Java.
Na Listagem 6 é possível encontrar um exemplo de como sobrescrever o operador + através do uso do método plus(). Criei uma classe chamada SomaODobro que, quando tem duas instâncias somadas, realiza a adição e depois a multiplicação para retornar o resultado. Veja o código.
Listagem 6. Usando o plus para aumentar o poder do +
package org.groovy.maonamassa
class SomaODobro {
def Integer valorInicial
public def plus(SomaODobro outro) {
return (valorInicial + outro.valorInicial) * 2
}
}
class AloMundoGroovy {
public def testa() {
SomaODobro valor01 = new SomaODobro()
SomaODobro valor02 = new SomaODobro()
valor01.valorInicial = 10
valor02.valorInicial = 20
println valor01 + valor02
}
}
É importante ressaltar que sim, é possível, em Groovy, ter mais de uma classe dentro de um arquivo de código fonte como visto acima. As classes podem, inclusive, ser públicas, ao contrário do Java, onde podemos ter apenas uma classe pública por arquivo. Veja nas Listagens 7 e 8 um exemplo simples.
Listagem 7. Um arquivo Groovy com duas classes públicas
package groovytest
public class Carro {
public def imprime() {
println "Sou um carro"
}
}
public class Moto {
public def imprime() {
println "Sou uma moto"
}
}
Listagem 8. Instanciando as classes Groovy
package groovytest;
public class Main {
public static void main(String[] args) {
Carro meuCarro = new Carro();
Moto minhaMoto = new Moto();
meuCarro.imprime();
minhaMoto.imprime();
}
}
Closures
Um dos recursos mais úteis e apaixonantes de linguagens dinâmicas são os closures, ou fechamentos, ou blocos, que dão um poder de fogo enorme no desenvolvimento. Closures nada mais são do que pedaços de código tratados como objetos, e como tal podem receber parâmetros e retornar valores. E como a JVM não sabe se o código que está rodando é Groovy ou Java, é perfeitamente possível dizer que um closure é apenas mais objeto para a JVM, tal qual uma String ou um Integer.
Uma aplicação robusta e poderosa de closure é na classe File da GDK. O Groovy estende o objeto File padrão do Java e adiciona um método eachLine(), que recebe como parâmetro um closure:
new File(“arquivo.txt”).eachLine { println it }
O closure nada mais é do que o bloco { println linha }, que será executado para cada iteração de eachLine(), ou seja, essa única linha abrirá um arquivo de texto chamado arquivo.txt, lerá linha por linha até o final e passará cada linha ao closure, que imprimirá o que recebeu na saída padrão usando o println() (o it representa a linha recebida). Tudo isso em apenas uma linha de código.
Outro exemplo bem interessante é apresentado a seguir, onde temos um tipo de dado do Groovy (o Range, que é um intervalo representado com dois números separados por dois pontos simples, como em 1..100, que inclui os números de 1 a 100); e o método each(), que varre cada membro do Range, e depois executa a closure que o imprime.
(1..10).each { println it }
Ok, mas o que é esse tal de it no meu código? Ele é uma variável conhecida como “Magic variable”, ou “ variável mágica”, algo que não precisa ser declarado pra existir. it pode ser visto como um membro da classe que define os closures do Groovy, é ele quem recebe o parâmetro padrão quando esse não é declarado. Veja como fica a opção de uso de uma variável explícita no lugar da variável mágica.
(1..10).each { valorAtual -> println valorAtual }
É o sinal de -> que separa a declaração de variáveis do corpo do closure. Mas closures não são úteis apenas para imprimir um valor na saída padrão, eles podem ser usados para operações complexas, sua imaginação é o limite.
O poder dos closures
Vamos criar um exemplo pra demonstrar um pouco do poder e da elegância do uso de closures. Crie um novo projeto Java e adicione Groovy a ele como visto anteriormente. Adicione uma nova classe Groovy chamada Aluno e então insira o código da Listagem 9.
Listagem 9. A classe Aluno.groovy
package groovy2
class Aluno {
// definimos as propriedades
String nomeAluno
Integer matriculaAluno
// variavel para a matriculo
static int matricula = 0
// Construtor
Aluno(String nome) {
matricula = matricula + 1
this.setNomeAluno(nome)
this.setMatriculaAluno(matricula)
}
public String toString() {
return "Matricula: " + this.getMatriculaAluno().toString() +
" Nome: " + this.getNomeAluno()
}
}
Nessa classe temos duas propriedades, o nome do aluno e o número de sua matrícula. O nome deverá ser informado no momento da criação do objeto, através de nosso construtor e o número da matrícula é sugerido através do uso de um membro estático que é incrementado a cada nova instancia criada (perceba que esse recurso não deve ser usado em situações reais, mas encaixa como uma luva nesse exemplo).
Redefinimos também o método toString(), para possibilitar uma impressão simplificada de nossos valores, quando necessário. Perceba que faço uso dos getters e setters sem os declarar pois, como foi visto antes, eles são criados automaticamente quando definimos membros de classe sem especificar sua visibilidade.
Na Listagem 10 instanciamos, em um arquivo main.java três objetos de nossa classe e imprimimos seus dados, usando o toString().
Listagem 10. A classe Main.java, instanciando três objetos aluno
package groovy2;
public class Main {
public static void main(String[] args) {
Aluno aluno01 = new Aluno("Marcelo");
Aluno aluno02 = new Aluno("Giuliana");
Aluno aluno03 = new Aluno("Ana Beatriz");
System.out.println(aluno01.toString());
System.out.println(aluno02.toString());
System.out.println(aluno03.toString());
}
}
O resultado será algo como:
Matricula: 1 Nome: Marcelo
Matricula: 2 Nome: Giuliana
Matricula: 3 Nome: Ana Beatriz
Vamos agora criar, na Listagem 11, uma nova classe Groovy chamada Aula. Vamos utilizá-la para agrupar nossos alunos em aulas.
Listagem 11. A classe Aula.groovy
package groovy2
class Aula {
ArrayList alunos = new ArrayList()
def adicionaAluno(Aluno nomeAluno) {
alunos.add(nomeAluno)
}
def removeAluno(Aluno nomeAluno) {
alunos.remove(nomeAluno)
}
def imprimeListaAlunos() {
alunos.each() { alunoAtual -> println alunoAtual.toString() }
}
}
Modifique o arquivo Main.java para que fique como na Listagem 12.
Listagem 12. A classe Main.java, modificada
package groovy2;
public class Main {
public static void main(String[] args) {
Aluno aluno01 = new Aluno("Marcelo");
Aluno aluno02 = new Aluno("Giuliana");
Aluno aluno03 = new Aluno("Ana Beatriz");
Aula historia = new Aula();
historia.adicionaAluno(aluno01);
historia.adicionaAluno(aluno02);
historia.adicionaAluno(aluno03);
historia.imprimeListaAlunos();
}
}
Ao chamarmos o método imprimeListaAlunos() faremos uso de um closure para percorrer todos os membros do ArrayList da classe Aula (através do each()). Agora faça um teste e escreva as classes Aluno e Aula em Java e veja quantas linha a mais de código seriam necessárias para o mesmo resultado.
A maior parte das linguagens e recursos que se propõe a enxugar o código o faz às custas de clareza. Isso não acontece em Groovy: o código continua perfeitamente legível, mesmo com linhas a menos. Em alguns casos, como no exemplo acima, é até mais fácil ler um código Groovy do que um código Java.
Para onde ir agora?
Groovy é extremamente poderosa e pode lhe ajudar muito em seus projetos Java. Ela é particularmente útil para processamento de texto graças a um poderoso suporte a expressões regulares, para processamento de listas e de arquivos graças ao uso de closures e principalmente para o processamento de XML, onde o Java é deveras confuso e prolixo.
Além disso Groovy é a base do Grails, framework de produtividade para o desenvolvimento de aplicações web que une a poderosa infra-estrutura do Spring e Hibernate à simplicidade das idéias do Ruby on Rails. Grails possibilita o desenvolvimento de aplicações complexas de maneira rápida e indolor, gerando uma aplicação web totalmente compatível com Java EE em um arquivo .war.
Para aprender mais sobre Groovy dê uma olhada na página do projeto na web. Existem dúzias de exemplos e informação relevante para que você torne-se produtivo rapidamente. Além disso, é interessante dar uma olhada no livro Groovy em ação, escrito por Dierk König junto a Andrew Glover, Paul King, Guillaume Laforge (o mantenedor do projeto) e Jon Skeet, publicado pela editora AltaBooks. (O original, Groovy in action, é publicado pela Manning, caso inglês não seja um problema). Groovy é simples e poderoso e merece sua atenção. O tempo que irá ganhar quando começar a usá-lo compensará e muito seu aprendizado.
Post de James Strachan, onde surgiu a ideia sobre o Groovy
http://radio.weblogs.com/0112098/2003/08/29.html
Página da SpringSource comentando a compra da G2One
http://www.springsource.com/node/836
Site do NetBeans, a única IDE que você precisa
http://www.netbeans.org
http://grails.codehaus.org
Site do Groovy
http://groovy.codehaus.org