Managing multiple Maven versions

Nov 2nd, 20093 Comments

Lately I’ve been using Apache Maven 3.0 snapshots to test build compatibility on ServiceMix, Karaf and some of the other projects I work on.  I’m also using 2.0.9, 2.0.10, and 2.2.1 to replicate customer environments and build servers, so it gets to be a real pain in the ass to change these around all the time.  To make my life easier, this weekend I hacked up a Maven version of the awesome setjdk and defaultjdk commands written by David Blevins for Mac OSX (if you’re on a Mac and not using these scripts, you should be).

This script makes some assumptions about where your Maven versions are and how they are named.  First of all, it is assumed that you put all of your Maven installs in the same place.  It could be hacked to look in multiple locations, but we’re lazy developers so why the fuss?  Second assumption is that you retain the directory naming of the tar.gz or .zip distributions of Maven.  These begin with apache-maven-* and that’s how the script finds the versions.  I’m building the 3.0-SNAPSHOTs into the same common location so that I can switch between them easily as well.

As a bonus, if you set up your default M2_HOME to point to the symlink “apache-maven” in your $MAVEN_PARENT location, you can change the default Maven version for new terminal instances as well using defaultmvn.

I know there is some room for improvement, but as it is this script works well on Mac OSX as well as Linux, so hopefully someone else can find it useful.

Installation: Click the “copy to clipboard” link in the top right corner and save this as /etc/profile.d/setmvn.sh or just source it into your terminal by some other means.  Modify the MAVEN_PARENT to your parent location such as /opt or /usr/local/share, etc.

Usage: The command includes completions, so from your shell just “setmvn <hit tab>” and you should see all of your maven versions.  Partial completions work too, so if you are a tab-happy completion-abusing lazy developer like me, this will be right up your alley.

#!/bin/bash
MAVEN_PARENT=/usr/share

function defaultmvn {
    local mvndir=$MAVEN_PARENT
    local ver=${1?Usage: defaultmvn &lt;version&gt;}
    local mvnprefix=apache-maven-

    [ -z &quot;$2&quot; ] || error=&quot;Too many arguments&quot;
    [ -d $mvndir/$mvnprefix$ver ] || local error=&quot;Unknown Maven version: $ver&quot;
    [ &quot;$(readlink $mvndir/apache-maven)&quot; != &quot;$mvndir/$mvnprefix$ver&quot; ] || local error=&quot;Default Maven already set to $ver&quot;

    if [ -n &quot;$error&quot; ]; then
    echo $error
    return 1
    fi

    echo &quot;Setting default Maven to $ver ... &quot;

    if [ &quot;$(/usr/bin/id -u)&quot; != &quot;0&quot; ]; then
    SUDO=sudo
    fi

    $SUDO /bin/rm $mvndir/apache-maven
    $SUDO /bin/ln -s $mvndir/$mvnprefix$ver $mvndir/apache-maven

    echo Done.
}

function setmvn {
    local mvndir=$MAVEN_PARENT
    local ver=${1?Usage: setmvn &lt;version&gt;}
    local mvnprefix=apache-maven-

    [ -d $mvndir/$mvnprefix$ver ] || {
    echo Unknown Maven version: $ver
    return 1
    }

    echo &quot;Setting current Maven version to $ver ...&quot;

    export M2_HOME=$mvndir/$mvnprefix$ver
    PATH=$(echo $PATH | tr ':' '\n' | grep -v $mvndir/$mvnprefix | tr '\n' ':')
    export PATH=$M2_HOME/bin:$PATH

    mvn -v
}

function _setmvn_completion (){
    COMPREPLY=()

    local mvndir=$MAVEN_PARENT
    local cur=${COMP_WORDS[COMP_CWORD]//\\\\/}
    local options=$(cd $mvndir; ls -d -1 apache-maven-* | awk '{match($0,&quot;apache-maven-.*&quot;); print substr($0,14,RLENGTH-13)}' | tr '\n' ' ')

    COMPREPLY=($(compgen -W &quot;${options}&quot; ${cur}))
}

complete -F _setmvn_completion -o filenames setmvn
complete -F _setmvn_completion -o filenames defaultmvn

In order to get the defaultmvn part to work, I have the following in my /etc/profile.d/maven.sh file (adjust based on your OS).

M2_HOME=/usr/share/apache-maven
PATH=$M2_HOME/bin:$PATH
export M2_HOME PATH

So thanks to David Blevins for the still awesome after all these years setjdk script which I completely and unabashedly stole for the basis for the setmvn script.

About author:

All entries by Chris Custine

3 Responses to “Managing multiple Maven versions”

  1. Toni Menzel says:

    Nice.. but.. what exactly is not ok with using flat smybolic links ?
    At least this works for me for all maven versions ( switch regularly with 2.0.10, 2.2.1 and 3-SNAPSHOT, works perfect)
    cheers,
    Toni

  2. Toni Menzel :

    Nice.. but.. what exactly is not ok with using flat smybolic links ?
    At least this works for me for all maven versions ( switch regularly with 2.0.10, 2.2.1 and 3-SNAPSHOT, works perfect)
    cheers,
    Toni

    Mostly because I will regularly have multiple shells open, and need to use different Maven versions at the same time. This way I don’t have any surprises. The symlink approach is fine but it means everything uses that version.

  3. Toni Menzel says:

    Sure, if you want that, you’ll need something like you did.

Leave a Reply