Writing Your pom Files in Groovy - a Sneek Preview of Maven 3's Polyglot Features
Join the DZone community and get the full member experience.
Join For FreeMaven 3 is promising to be the most significant upgrade since the release of Maven 2. While maintaining backward compatibility with existing Maven 2 projects, it introduces a number of powerful and compelling new features, such as a complete rewrite of the internal architecture, OSGi support and multi-language pom files. In this article, I will be giving a preview of this last feature.
One exciting new feature in Maven 3 is it's ability to work with pom files written in non-XML notations. The Maven core now provides an underlying DSL to access the Maven internals, and write POM files in the language of your choice. This currently includes scripting languages like Groovy, Ruby, and others. In short, you will be able to write a DSL for virtually any scripting language you like that can hook into the Maven internals and pilot the Maven build process.
This article focuses on the Groovy support - writing your POM files in Groovy.
With Maven 3, you can use a Groovy DSL that maps directly to the XML pom format. So, instead of:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.5</version>
<scope>test</scope>
</dependency>
you could write:
dependencies {
dependency { groupId 'junit'; artifactId 'junit'; version '4.7'; scope 'test' }
}
Let's take a closer look. A handy way to start is to use the translator tool, which lets you translate an existing pom.xml file into:
$ translator pom.xml pom.groovy
This generates a Groovy transcription of your pom file, which looks and feels just like a traditional pom file, except in Groovy. Here is a simple one:
project {If you're familiar with the XML pom files, this will read pretty easily - it's essentially an XML pom file without the noise generated by the XML tags. Although it's an obvious improvement, some of the transcribed Groovy DSL code might still seem a bit wordy to some. For example, a set of project dependencies might look like this:
modelVersion '4.0.0'
parent {
artifactId 'babble'
groupId 'com.sonatype.training'
version '1.0.6-SNAPSHOT'
}
artifactId 'babble-core'
version '1.0.6-SNAPSHOT'
name 'babble-core'
url 'http://maven.apache.org'
build {
testResources {
testResource {
filtering 'true'
directory 'src/test/resources'
}
}
}
dependencies {
dependency {
groupId 'junit'
artifactId 'junit'
version '4.7'
scope 'test'
}
}
profiles {
profile {
id 'development'
properties {
'log4j.level' 'DEBUG'
}
}
profile {
id 'production'
properties {
'log4j.level' 'WARN'
}
}
}
properties {
'log4j.level' 'info'
}
}
dependencies {
dependency {
groupId 'junit'
artifactId 'junit'
version '4.7'
scope 'test'
}
dependency {
groupId 'org.hamcrest'
artifactId 'hamcrest-all'
version '1.1'
}
dependency {
groupId 'log4j'
artifactId 'log4j'
version '1.2.12'
}
}
However, you can make this more concise simply by using semi-colons to separate the dependency elements:
dependencies {
dependency { groupId 'junit'; artifactId 'junit'; version '4.7'; scope 'test' }
dependency { groupId 'org.hamcrest'; artifactId 'hamcrest-all'; version '1.1' }
dependency { groupId 'log4j'; artifactId 'log4j'; version '1.2.12' }
}
This is certainly more concise and more readable, and goes with the general tendancy of moving away from XML as a build scripting language in favour of more lightweight notations. But the real power of this is that it is effectively an interface to the Maven 3 core, that gives you full access to all of the Maven features. The Maven 3 core is rock solid, and you can leverage all the existing features and plugins from the Maven 2 ecosphere.
Maven 3 is supposed to be fully backward-compatible with your existing Maven 2 projects, with the exception, I believe, of a few fairly rare corner cases. I tested Maven 3 against a few large real-world projects (including a couple of gnarly ones), and indeed everything seemed to work just fine. I've also converted the pom.xml files into Groovy equivalents and run the builds successfully. Performance is good - I didn't notice any real difference between using an XML pom file and a Groovy one.
I've just scratched the surface of Maven 3 Groovy support, but hopefully this will give you some idea of what it's all about. In the coming weeks, I'll write about some of the other new features in Maven 3.
Opinions expressed by DZone contributors are their own.
Comments