How to make your Maven build fast again

When the project starts we do not think about the certain things like dependency hell, modularisation or time needed to build the project. It is quite normal, the codebase is pretty small, there are not that many dependencies, etc.
However when the time is passing, the time spend on building the application starts to be noticeable.
It is high time to think how to cut down on the build time.
Here you can find a few tips which could help you in this field.

Build in parallel

By default Maven builds the project sequentially. Modern computers have at least a few logical cores which are not fully utilised during Maven build. The Maven is able to analyze the dependency graph and build the project in parallel if possible.

mvn -T 4 clean install

It is telling the Maven to use 4 threads when building the project.

The time that can be saved depends on the project but on every advice you have an example times (MacBook Pro 2,3 GHz Intel Core i5).

one module project:

mvn clean install

Total time: 01:16 min

mvn -T 4 clean install

Total time: 01:04 min

multi module project:

mvn clean install

Total time: 02:44 min

mvn -T 4 clean install

Total time: 01:44 min

Build incrementally

The way we usually build projects is:

mvn clean install

But do we really need to clean the project every time? Obviously cleaning is one of the first things to try when we face weird caching problems or some strange bugs. However, generally we do not need to clean the project. From the performance point of view it is better to build it incrementally:

mvn install

or

mvn install -pl module_name -am

which builds only module_name and dependent modules.

multi module project:

mvn clean install

Total time: 02:32 min

mvn -T 4 install

Total time: 51.396 s

Build offline

This is not only Maven problem that it seems to try to download the whole Internet every time you build the application. Other build tools like sbt, gradle or npm do the same.
We can prevent Maven from trying to download dependencies from the Internet using offline option;

mvn --offline install

multi module project:

mvn clean install

Total time: 02:28 min

mvn --offline clean install

Total time: 02:21 min

JVM tuning

Since Maven is normal Java program we can try to do some Java tuning in order to speed up the build.
One possible optimization would be to reduce JIT (Just In Time) compilation. Basically, JIT compiler runs after the Java program started and compiles the code on the fly into a form that is usually faster to run on the particular CPU. While it is good for a long running programs, it is not necessarily helpful for a short running programs like Maven build.
We can try to force the JVM to make only basic JIT compilation:

-XX:+TieredCompilation -XX:TieredStopAtLevel=1

multi module project:

mvn clean install

Total time: 02:28 min

export MAVEN_OPTS="-XX:+TieredCompilation -XX:TieredStopAtLevel=1"; 
mvn clean install

Total time: 01:44 min

Run tests in parallel

We know how much time it takes to execute all those unit and integration tests during the build. These days tests execution time takes most of the time spend in Maven build.
To reduce that time one possible option is to use that infamous skipTests=true option. I do not advise this practise. However there is another way to speed up the tests: run them in parallel.
The maven-surefire-plugin has an configuration option to run the tests in parallel:

parallel>classes</parallel>
<threadcount>10</threadcount>

multi module project:

mvn clean install

Total time: 02:40 min

#tests running in parallel (10 threads used);
mvn clean install

Total time: 02:25 min

Conclusion

In this post we looked at a few basic ways to speed up a Maven build. Not all of them can be used in every project but you can pick those which fit into your model and save a few seconds on the Maven build.

Java application performance monitoring

I am going to present quick overview of useful tools which can be helpful when you trying to troubleshoot application in case of performance issues.

Describing each tool, some overview is provided, the way the tool is installed, free/paid info, inclusion in the JDK and the information if it can be used in production environment.

  • logs
    • application logs, application server logs, database logs
    • no installation
    • free
    • included with JDK
    • can be used in production
  • application server monitoring
    • administration console
    • provided by default with application server or installation needed – varies between application servers
    • free (comes with application server)
    • not included with JDK
    • can be used in production (if properly secured)
  • New Relic
    • application performance management and monitoring
    • application has to be started with agent
    • basic features: free; advanced features: paid
    • not included with JDK
    • can be used in production
  • AppDynamics
    • application performance management software; useful for developers as well as operations; great visual tool
    • application has to be started with agent
    • lite version: free; pro version: paid
    • not included with JDK
    • can be used in production
    • YourKit
      • cpu and memory profiler
      • installation needed
      • paid
      • not included with JDK
      • cannot be used in production
    • JVisualVM
      • cpu and memory profiler
      • no installation needed
      • free
      • provided with JDK
      • some features can be used in production
    • JConsole
      • JMX metrics
      • no installation needed
      • free
      • provided with JDK
      • can be used in production
    • JMap/JHat
      • prints Java process memory map
      • no installation needed, attaches to the running process
      • free
      • included with JDK
      • cannot be used in production
    • JStack
      • prints thread dump of Java process
      • no installation needed, attaches to the running process
      • free
      • included with JDK
      • can be used in production