| Writing your pom files in Groovy - a sneek preview of Maven 3's polyglot features |
|
|
|
| Tuesday, 20 October 2009 13:59 |
|
Maven 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:
you could write:
Let's take a closer look. A handy way to start is to use the
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:
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:
However, you can make this more concise simply by using semi-colons to separate the dependency elements:
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. Trackback(0)
Comments (19)
![]() written by doug tangren, October 21, 2009
smells a bit like sbt's dependency management written in groovy. sbt is of course in scala though http://code.google.com/p/simpl...Management
written by Sakuraba, October 21, 2009
I cannot stress enough how much I hate this useless DSL-hype-crap. There is absolutely NO productivity gain when one could write this...
dependencies { dependency { groupId 'junit'; artifactId 'junit'; version '4.7'; scope 'test' } } ... in favor of this... There is no gain! It is an illusion and what makes it even worse is, you completely lose all code-completion provided by TextEditors/IDEs for XML editing. This reduces the editing to a copy/paste-try-out development style since you need to remember the "syntax" of such a DSL, something a tool could provide for you. A question like "what attributes are allowed for this element?" cannot be answered by a tool. How anyone thinks that this actually improves anything is beyond me. But I guess people need to make their own experiences. Just look at the success of "Gant", which is pretty much irrelevant. It took the Groovy-DSL-approach to Ant and it didnt work for the masses since people need to abstract from all the xml-way of doing things to a DSL they dont know. written by Felipe Cypriano, October 21, 2009
Sakuraba, IntelliJ IDEA can auto complete groovy code with no problems, just like it does for xml. So the "problem" is with especific products not all as you may suggest.
written by Jacek, October 21, 2009
I would much prefer to simply do it in YAML:
project: - model.version: 4 - dependencies: - dependency: {groupId: "org.apache",artifactId: "commons-lang", version: '1.0'} etc. YAML would be the best format for this...don't understand why you would need an actual language (Groovy) in this case written by Mark Derricutt, October 21, 2009
Hey John, how is the groovy DSL actually parsed by maven? Do we drop in a maven-groovy.jar or something in the maven lib dir? Would love to see how to do this for clojure.
If you're coming along to the hack fest this weekend would love to see how this fits together... written by doug tangren, October 21, 2009
yaml xml or any other markup language lack one benefit.
They are markup. Writing your config in your programming language (rake -> ruby, sbt -> scala, this -> groovy) gives you a much more flexible and expressive way of managing dependencies and the like. I hate seeing in an ant build.xml file. That alone should suffice as the explanation of why dsl in your given programming language is so nice. If you are writing a programming language build to on top of xml, you should ask yourself: Why not just use your applications programming language? Markup languages alone are inflexible. They are static. Although, when using a programming lang is not possible for configuration, yaml is a much simpler, compact, and easier to read format
written by Cees de Groot, October 21, 2009
(and I don't even know groovy ;-)).
What I've been wondering about - in, say, Buildr you have the full power of the language available. So what you typically see people doing is stuff akin to theseDeps = dep1, dep2, dep3, ... thoseDeps = dep2, dep4, dep5, ... ... someModule { dependencies { theseDeps } } because if that's possible, it's not just syntactic sugar, it's a huge step up from the static and limited Maven2 pom (imvho) written by Killian EBEL, October 21, 2009
You should have a look to http://www.gradle.org/, which is a powerful build system, using Maven (and other) repositories. Build scripts in Gradle are written in Groovy, and could be written in Ruby or Python in the future.
Dependencies in Gradle can be declared like this : dependencies { compile 'org.aspectj:aspectjrt:1.6.4' compile 'org.springframework:spring:2.5.6' testCompile 'junit:junit:4.7' } written by John, October 22, 2009
How can I get/build the translator tool? Checked and built maven 3 trunk, but can't find it anywhere.
written by GRO, October 22, 2009
It's good to have an alternative to XML in Maven.
By using Groovy (or other script language) we have simplicity and flexibility. That's the reason I prefer Gradle to Maven, it's simpler and if I need something more complex, I can write my own Groovy script. written by Elwyn Malethan, October 22, 2009
@doug tangren
By using a language (and not markup) to describe the builds, it will inevitably result in subverting the "standard" way in which Maven describes builds. This will potentially reduce portability and coherency. I used the word 'describe' there twice, advisedly. Maven is not for scripting builds but for describing them - something mark-up is designed for. Anything beyond that description should be in MOJOs (written in any language you like), and not in the POM. I welcome the ability to express the Maven configuration in something less verbose than XML. But it should be mark-up, not a programming language. written by Foo, October 23, 2009
Hello,
just like Sakuraba above I just do not get the point of replacing a mature operational-proven thing as XML which has a lot of well working tools, knowledge and business acceptance with some trendy underdeveloped and unproven as YAML, some whatever-DSL Groovy,Ruby,Blafarghl or any other untyped, unverfiyable and tool-less silver bullet. I'ld rather see even more quality in the present things Maven Reality, even better Integration. More nice features and a growing ecosystem while keeping Mavens strong point of declarativeness. What I expect when full programming languages for build descriptions are used is that people will go back do magic-parameter one-off conventionless quickhacks which will result in everything Ant was deprecated for plus all the problems of autotools and other c-Style full-language Tools. In effect: Loss of quality and knowledge conservation we have reached so far. written by GRO, October 23, 2009
I don't think the XML version should be replaced (that's not the idea).
I just want to have better options. Most of the pom files that I had converted to Gradle became smaller and easier to read. I'm a Java developer, it's just more natural to read a pom file written in groovy than in XML. The same apply to other languages: ask Rails guys if they are unhappy with their "unproven" scripts ? Some people will prefer to use legacy XML pom files, but I prefer more convention and readability. If people didn't come with new ideas like this, we'd be using stuff like the crap Struts 1 framework until now and writing 3X more code for a simple web app (just because it's mature). Innovation, please! written by Sakuraba, October 27, 2009
"What I expect when full programming languages for build descriptions are used is that people will go back do magic-parameter one-off conventionless quickhacks which will result in everything Ant was deprecated for plus all the problems of autotools and other c-Style full-language Tools. In effect: Loss of quality and knowledge conservation we have reached so far."
Ditto! What I hate the most about Grails development is the fact that they have a Log4j DSL. Any tutorial/guide/snippet on the web is useless because I need to abstract from a simple properties file to a whole new syntax that comes with the DSL. I promise you teh same will happen when people start DSLify Maven. written by Matt Gumbley, October 27, 2009
Foo, Elwyn Malethan and Sakaruba said it best. If you want an example of prior art as to why this is a bad, bad idea, the Tower of Babel should give you ample evidence.
Look at the Maven documentation online - sure, this has improved by an order of magnitude since The Definitive Guide was published, but it's hard enough finding out The Maven Way as it is, with the XML pom. The knowledge one has to accrete is best described in a single, universally-understood language, not in the plethora of different styles that will undoubtedly ensue. Will my Maven build will slow down as it has to load its Groovy/Scala/Clojure/YAML/Ruby/Befunge parsers/language runtimes? How, apart from removing the angle brackets (big deal), does this equate to being "more flexible and expressive"? Why do I need this in a build system? Has this been forgotten: "The Inner-Platform Effect roughly states that by making a system too flexible and configurable, the configuration of the system itself becomes so complex it takes a specialist in order to maintain it - thus re-introducing the problem that the system was attempting to solve. Or, in other words, the configuration becomes a platform itself, requiring all of the tools and special knowledge of any programming language... effectively creating a system in a system." -- from early editions of Maven:The Definitive Guide. written by Maven Watcher, November 08, 2009
@John: Jason van Zyl
\n This e-mail address is being protected from spambots. You need JavaScript enabled to view it
/msg82018.html'>says "No it's not available and won't be until I'm finished a fully working beta." When asked when that would be he
\n This e-mail address is being protected from spambots. You need JavaScript enabled to view it
/msg82032.html'>said "No." The message is clear: don't expect Maven to ever support POMs written in anything other than XML.
written by Ken Liu, November 17, 2009
It does seem attractive to be able to write the POM in a more concise form than XML, but once you move away from XML to a DSL, you lose the ability to easily parse/validate/transform the POM.
Currently I have many build scripts that manipulate POMs files, for example custom release scripts that update the Write comment
|
Live online Maven course: MVN-101 Maven Mechanics Two 4-hour sessions 12pm-4pm Sydney time, January 27 and 29 |
Live online Maven course: MVN-201 Designing Development Infrastructure Two 4-hour sessions 12pm-4pm Sydney time, February 3 and 5 |
Agile ALL Annotations Artifactory Automated Testing BDD Bugzilla Build Automation Cargo Code Coverage Code Quality Code Reviews Continuous Integration Continuum Distributed Builds EasyB Eclipse Grails Groovy Hibernate Hudson Humour Integration Tests JasperReports Java Javascript JDave JIRA JUnit Jupiter Lucene Maven Mock Objects Mockito Nexus Performance PMD Rome RSS Selenium Smack API Subversion Tapestry TDD Testing Trac training Unit Testing Unit Tests Web Services
There's still some redundancy, no doubt this is because of the needs of Groovy, so take your example
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' }
}
By sticking hard to the "convention-first" style of interaction, this could be reduced yet further to
dependencies {
org.hamcrest:hamcrest-all:1.1
log4j:log4j:1.2.12
test {
junit:junit:4.7
}
}
it's not Groovy, but it's certainly shorter
One aspect of the POM that has always irked me a bit is the fact that everything is in one file. Sometimes I want to mess with the repositories, sometimes I want to change the dependencies, sometimes I want to update the profiles, etc. If there was an inclusion mechanism that would allow separation of the model into different files, then reassembly, that might be a useful thing. (Hey - it might already exist, if it does, I just haven't found out about it yet).