Working Efficiently with Maven Modules

When working with Java you will sooner or later come across Maven and Maven modules. Before you start developing a new module feature, upstream modules need to be built, and before you finish you must build downstream modules to make sure that you have not broken any dependencies or tests. However, it is not always obvious how different modules relate to each other. If you just call mvn clean install at the project root it does not really matter, but as the project grows the builds will become more and more tedious. This blog aims to demonstrate how you can take advantage of Maven command line options to work in a smarter, more efficient way.

Project

Let us assume that we have a project structure with the modules below and that we will add a new feature to the A1 module:

If you are in the master folder and execute mvn clean install -Pitest, then all projects will be compiled, tests will be executed, integration tests will be executed and the resulting binaries will be deployed to your local Maven repo as expected. All is good, but it may take a while to complete. In the following example, we will see how it is possible to work on the A1 module without rebuilding the non-dependent A2* and B2* modules.

Build a single module

If you are working with a single module, it is possible to compile and test just the specific project by providing the -pl (or --projects) option and add a colon before the specific artifact id. For example, if you just would like to build the A1 project, simply execute:

If you would like to build more than one project, just add list the artifact ids separated by comma. To build both A1 and A2:

Build dependencies and module

Building a single module will only work if you have access to its dependencies. If it is the first time you build a project, or if you have updated your project with the latest changes from the version control, you may have to rebuild the module’s upstream dependencies. Continuing with the example, this implies that you need to build both the master and the A module before attempting to build the A1 module. Of course, the just mentioned -pl can be used, but there is another Maven option that works out the dependency graph for you so that the master, A and A1 will be built in one command. The -am (or --also-make), option does exactly that:

Build module and dependents

When you have finished the implementation of your A1 feature, you would like to be sure that all downstream modules that depend on A1 still works. To build the A1 and the B1 projects in one command you can use the -amd (or --also-make-dependents) option:

Similarly, if you also would like to execute the integration test, you must enable the itest profile with the -P option. The modules A1, B2, A1-ITest and B1-ITest will be built consequently:

Reference

Maven has many other command line options such as -o, -fae and -rf that can be used to tweak and improve your builds if used wisely. See the Maven command line help for reference, or simply execute Maven with the -h (or --help) option:

Mattias Severson

Mattias is a senior software engineer specialized in backend architecture and development with experience of cloud based applications and scalable solutions. He is a clean code proponent who appreciates Agile methodologies and pragmatic Test Driven Development. Mattias has experience from many different environments, including everything between big international projects that last for years and solo, single day jobs. He is open-minded and curious about new technologies. Mattias believes in continuous improvement on a personal level as well as in the projects that he is working on. Additionally, Mattias is a frequent speaker at user groups, companies and conferences.

This Post Has 11 Comments

  1. Hi,

    one note:

    mvn -pl :A1,:A2 clean install

    ist not correct, you have to name the modules without the colon.

    mvn -pl A1,A2 clean install

    would be correct.

    1. @Sascha: Well, it depends if you are addressing your modules based on their artifact ids (i.e. they are prefixed with colons), or on their relative paths (no colons), see the output of mvn -help:

      $ mvn -help
      […]
      -pl,–projects Comma-delimited list of specified
      reactor projects to build instead
      of all projects. A project can be
      specified by [groupId]:artifactId
      or by its relative path.
      […]

  2. Looks like reactor is retired, is there any other way to achieve this?

    1. @Krishna: I am sorry, I do not know. It was quite some time ago since I last used Maven and I have not been keeping up with its tools and plugins development.

  3. Thanks for sharing. This really helped me better understand how to conditionally compile/test specific modules in my multi module project

  4. Hey,

    I’m trying to tun exclusive test, using the module specification command, but the tests aren’t running.

    Do you know what is the reason?

    Here is my command:

    mvn -pl :tika-parsers -am test surefire:test -DfailIfNoTests=false -Dmaven.test.failure.ignore=true -Dtest=org.apache.tika.mime.TestMimeTypes

    1. @Rotem: When debugging CLI tools in general, my recommendation is that you start from the basics. For example, start by executing mvn test. When that works, add another option such as the “projects” option , e.g. mvn -pl :tika-parsers test. If is still working add the “also make” option mvn -pl :tika-parsers -am test and so on until you no longer get the expected result. At that point you know which option failed and you can make appropriate changes.

Leave a Reply

Close Menu