Easy Maven Config Switching

Easy switching of Maven user configurations when working at home or in the office.

Easy Maven Config Switching

Maven is my preferred build tool for working with Java projects in the office or at home.

When you install Maven, it relies on three layers for configurations when running a build:

  • Global config; that exists in the directory where the maven distributable is, I've never had to edit this file.
  • User config; settings.xml that exists in the .m2/ directory in the user home directory. This is normally used for specifying custom repositories and mirrors for private artifacts.
  • Project config; the pom.xml which can contain project specific settings and dependencies.

This information can be viewed on your machine with the following command

mvn -X | grep "settings"

Generally it is regarded as best practice to configure private repositories and other information in the settings.xml in the user's .m2/ folder for consistency and security.

This is generally fine when you are using your machine in one location or if you are constantly connected to a VPN to gain access to those private repositories. However if you are unable to connect, you will start coming across build failures. like I did recently when having network issues.

You can try forcing maven to build in offline mode, which tells it to use locally cached artifacts mvn clean build -o

Unfortunately if you are creating a fresh project without any downloaded dependencies, or you are just hacking away at a simple project then you will be blocked by this error, until you disable or change the settings.xml config.

Quick Fix

A quick solution for when you need to disable the default config, is to just move the settings file or rename it in your terminal, so that Maven doesn't pick it up.

#turn off default settings
mv ~/.m2/settings.xml ~/.m2/settings.xml.off

#turn on again
mv ~/.m2/settings.xml.off ~/.m2/settings.xml

This can get a bit frustrating to manage, so you could easily alias those commands and put them into your .bashrc file

alias mvnconfon="mv ~/.m2/settings.xml.off ~/.m2/settings.xml"
alias mvnconfoff="mv ~/.m2/settings.xml ~/.m2/settings.xml.off"

When Maven can't find this config it will revert to the global settings, which means Maven will build everything with vanilla configuration.

Better Fix

Changing or disabling a config is not a sustainable solution for long term, especially if you have multiple configs or work with multiple clients.

Unfortunately it is not possible to specify a settings file in the pom.xml as that would break the rules of preventing contamination of different people's system environments into the build, resulting in a big mess.

Luckily you can specify a settings file like so with Maven

mvn clean compile -s ~/.m2/foo-settings.xml

However this relies on you constantly supplying an argument when running maven. Therefore I opted for an environment variable set to my alternative settings file. This variable can be set in .bashrc and updated.

export MVN_SETTINGS=~/.m2/foo-settings.xml

mvn clean compile -s $MVN_SETTINGS

To take this a step further you can have aliases or a script that can toggle this environment variable to a specific Maven settings file.

#!/bin/bash

if [[ $0 == "work"]]
then
  export MVN_SETTINGS=~/.m2/work-settings.xml
else
  export MVN_SETTINGS=~/.m2/foo-settings.xml
fi

mvn_conf.sh

Then all it takes is a little clever alias to automatically add this environment variable for anytime you invoke Maven, meaning it will use the specified settings.xml file.

alias mvn="mvn -s $MVN_SETTINGS"

Conclusion

This is definitely an edge case for Maven brought about by the Coronavirus lockdown; with people working from home for extended periods of time, on flaky VPN connections.

With this workaround I was able to easily build and test my projects without being blocked by connection failures to remote private repositories.

Here are some useful links when researching this topic:

http://maven.40175.n5.nabble.com/Conveniently-switch-between-settings-td126255.html

https://stackoverflow.com/questions/24136068/how-can-i-tell-maven-to-use-specific-settings-xml-on-project-bases

https://stackoverflow.com/questions/24136068/how-can-i-tell-maven-to-use-specific-settings-xml-on-project-bases

http://maven.apache.org/settings.html#quick-overview