Thomas Sundberg

February 28, 2014

Scripting with Ruby and Maven

Filed under: Automation, Maven, Programming — Tags: , , , , — Thomas Sundberg @ 18:43

This post has been migrated to

In my assignment as a Configuration Manager, CM, I need to script a lot of things. I also need to automate the execution. Most of the stuff I build is built using Maven. Some is built using Ant. Both Maven and Ant are easy to run from TeamCity. But none of them are very flexible when it comes to scripting. Maven isn’t designed for it and Ant is missing some features and get very verbose. The most important feature I am missing in Ant is repetition.

I saw a panel debate a while ago where three guys were discussing their favorite tools. The tools represented were Scala, Ruby and Groovy. One thing that I remembered from that session was that the Scala guy mentioned that he often used Ruby when scripting. My problem with using Ruby is that I don’t have control over my execution environment. I can’t install tools in it. I am not interested, either, because that wouldn’t scale very well since the installation done on our build servers are done manually. I can, however, expect that Maven and Ant will work.

Given that I can expect Maven to work, I decided to try to execute a Ruby script from Maven. It turned out to work very well. I was able to reduce the size of an Ant script with 50% on my first attempt. In my opinion, the readability increased a lot. I was able to write the script more or less as prose.

If you are interested, this is how I did.

The file structure I use in this example looks like this:

|-- pom.xml
`-- src
    `-- main
        `-- ruby
            `-- script_from_maven.rb

I will execute a Ruby script from Maven. Let me start with a simple script that will demonstrate this. It is a little more than a Hello World, but not much. If you are a Ruby guy, you might have opinions about my style. Please let me know, I am just starting out on the Ruby path.

This is my script. I define a Ruby class. At the end of the file I create an instance of the class and executes one method.


class Script_from_maven def hello puts 'Hello!' puts ENV['JAVA_HOME'] end end s = s.hello

The only thing I do is print hello to greet any user and print the value of my JAVA_HOME environment variable. But this is enough for me to know that my script was possible to execute.

I need a Maven pom that calls my script above. An example may look like this:


<?xml version="1.0" encoding="UTF-8"?> <project> <modelVersion>4.0.0</modelVersion> <groupId></groupId> <artifactId>example</artifactId> <version>1.0-SNAPSHOT</version> <build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.2.1</version> <executions> <execution> <phase>process-resources</phase> <goals> <goal>java</goal> </goals> </execution> </executions> <configuration> <mainClass>org.jruby.Main</mainClass> <arguments> <argument>${basedir}/src/main/ruby/script_from_maven.rb</argument> </arguments> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>org.jruby</groupId> <artifactId>jruby-complete</artifactId> <version>1.7.10</version> </dependency> </dependencies> </project>

The two important things in this pom are the Maven exec plugin that I use to call JRuby and the dependency to JRuby.

I execute JRuby in the same Java process as Maven is executed. This has the benefit that I will not risk leaving any dangling processes behind if something fails unexpectedly. I also connect the execution to a Maven lifecycle phase to make my life easier. I have decided that this fantastic script should always be executed during the process-resources phase.

Why not write a Maven plugin that will solve the same problem? This is a valid question and the simple answer is that sometimes I don’t have a need to be a part of the Maven eco system. In these cases, it definitely makes sense to script using something else. In other situations, it may be a good thing to be a part of the Maven eco system. When I have that need I will write a Maven plugin instead.

As usual, it all depends, and using the right tool at the right time is important.

Why is this so good then?

  • I have access to a complete programming language with all the possibilities this brings to the table
  • I can easily develop my script using my favorite tool, Jetbrains IntelliJ Idea
  • I can test drive my code
  • I can execute this wherever I can execute Maven

Do I need more reasons than this? No, not really. Two of them would have been enough.



  1. Thomas, did you try the gmaven plugin, see It does something similar but handles all the details for you out of the box. Of course it is using Groovy, but the idea is the same.

    Comment by Peter Kofler — March 14, 2014 @ 00:24

  2. No, I didn’t consider the gmaven plugin. The main reason was that I wanted to practice some Ruby.


    Comment by Thomas Sundberg — March 14, 2014 @ 16:42

  3. Excellent write-up. Thank you for taking the time!

    Comment by chahn1138 (@chahn1138) — March 3, 2015 @ 02:15

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at

%d bloggers like this: