How to Speed up Your Maven Build
In this article, we look at the popular Java build tool, Apache Maven, and give five tips on how to speed up Maven for Java developers. But first, let's get some background on MVN.
Maven, or MVN, is a powerful software project management tool used in the Java development environment to manage and build projects as well asa to maintain dependencies.
It boasts features that range from easy project and module creation to a large repository of libraries and metadata for out-of-the-box usability. The objectives of the tool include:
- Making the build process easy.
- Providing a uniform build system.
- Providing quality project information.
- Providing guidelines for best practices development.
- Allowing transparent migration to new features.
Common issues with Maven can include dependency conflict, cache resolution, and, as we talk about below, slow build times.
Learn more in this blog >>What Is Maven?
4 Tips for Troubleshooting Slow Maven Builds
We often dream that things will run faster, or happen sooner than they do so they’re not as annoying. It’s particularly painful, when you have little or no control over the thing you’re waiting for. Time seems to stop and every second feels like an eternity. Multiply that by 10 add 5, divide by 2 and square it. You now have a measure of how annoying this can feel. An example of such an annoyance might be the build time of your project. Perhaps you use Maven as your a build tool of choice?
In the next five sections, I try to explain some of the most common reasons as to why Maven build is taking longer than it should and figure out how it can be improved. So, if you’re one of those people who counts the seconds in a slow Maven build, keep reading, this should help you. Or at least it will line up your thoughts to help figure out how to improve it. Here are five tips for troubleshooting slow Maven builds.
1. Parallel Builds in Maven
By default, Maven does not utilize the full power of your hardware. It builds all modules sequentially rather than in parallel. However, often your project setup does not require it to be sequential. Often you can command Maven to analyze your project including the dependency graph and build the project in parallel where possible. You can either specify the exact number of threads to use for building your project or use a portable version of the parameter and specify the number of thread in terms of CPUs available on the machine.
mvn -T 4 install -- will use 4 threads mvn -T 1C install -- will use 1 thread per available CPU core
While it might happen that your project is not easy to build in parallel it’s worth trying, the speedup can be substantial. Using one thread per CPU core is a good default. Your development machine probably has spare computing power and speeding up the build is always useful.
2. Running Maven Tests in Parallel
An aspect of build which probably has the biggest impact on your build speed are the tests. The most common practice is to disable the tests when you’re just interested in building your artifacts, but we cannot recommend such a non-conventional engineering practice. If you really do intend to skip your test goals during your Maven build, then the most common property that the majority plugins respect is: -DskipTests=true However, you can achieve faster build times without damaging your feedback loop that much.
The answer is running tests in parallel. The parallelization technique that we just discussed works on the module level. If you’re using an established plugin for running tests, let’s say, Surefire, you can also configure it for parallel execution within the module. Running tests in parallel might lead to unwanted side-effects, especially if they are tangled together and expect to be executed in a certain order. However, that’s another story altogether and you should totally try it to see if it works for you and by how much it speeds up your build. You can always figure out the failures later.
3. Build Necessary Modules Only
What command do you usually use to build your project? Is the answer:
mvn clean install
While cleaning Maven is removing all the generated artifacts, all temporary files, except hopefully the configuration and the files checked in into the version control. It then generates fresh copies of those files again. It’s great for when you hit a weird caching issue or some obscure bug that you have but nobody else is able to reproduce.
However, it will take extra precious seconds and CPU cycles to do what is essentially a needless job of recreating already existing files. Instead what you most typically want to do is to build your project incrementally. Say you have a multi-module project with common core modules that rarely change and a web-interface that you’re currently working on. After changing the web-interface module try running a command like the following:
mvn install -pl $moduleName -am
First of all, we removed the implicit call to the clean phase. The project rarely requires cleaning, so we won’t want to do it all the time. Let’s take a look at the descriptions of the other options in the Maven command we just used:
- -pl - makes Maven build only specified modules and not the whole project.
- -am - makes Maven figure out what modules out target depends on and build them too.
The result of using these options together is the perfect combination of the flexibility and speed. We know what module we’re usually working on and if we have changed any dependencies, they will be renewed as well. At the same time a large chunk of your project build will be skipped either because it’s still fresh and doesn’t require rebuilding or because it’s not a part of the target module and won’t play a role.
4. Limit Internet Access
If you sometimes feel like Maven is downloading the internet, know that you’re not alone! This is one of the most common complaints of any build system, npm, gradle, sbt. You name it, you’ll be surprised at how many libraries and transitive dependencies known to humanity will need to be downloaded at an arbitrary, and usually most inopportune time. However, there’s a simple option you can enable that will make Maven work offline. You’ve probably guessed correctly, it’s the infamous offline key.
When the offline mode is enabled, Maven won't connect to any remote repositories when resolving dependencies. All the jar files in the local repository will still be available, so it won't break your usual workflow. So just append your mvn command with --offline or --o and Maven won’t be tempted to check for a new snapshot of your favorite dependency and won't make you wait for the network to respond.
In this post we’ve looked at several common reasons why a Maven build might be slow and could be annoying you each and every time it’s run. In a nutshell, I think the default command for your build should be something along the lines of the following snippet:
mvn -T 1C install -pl $moduleName -am —offline
It will deny Maven its annoying right to download the internet, build only the necessary modules and their dependencies, and won’t relentlessly clean the whole project again and again. You’re welcome. I bet you’ve been waiting for me to say this next bit, so wait no longer! If you have an opportunity, consider trying out another build tool. For example Gradle is said to be more intelligent with greater “optimizations” as built-in defaults.
There might be a way to skip the build phase of your Java project completely. Check out JRebel, a revolutionary tool which reloads your code changes instantly without building your project at all!. It will make your development cycle faster by skipping your build, redeploy and restart stages. Your development experience will become more enjoyable and you will be a happier and more productive developer.
Note: This post was originally published on August 11, 2015 and has been updated for accuracy and comprehensiveness.