There are few things more frustrating than running into issues with your
build tool. One moment your build runs smoothly, and the next it fails
inexplicably. Or maybe you’ve been typing mvn clean package
for years
without really knowing why. In this post, I’ll share some best
practices for using Maven more effectively, and attempt to demystify
some of its features.
Understand the Clean Plugin
Running the Clean plugin during every build will spend unnecessary time
on recompilation and packaging. The Clean plugin is used to delete the
output of a previous build. Using it only when you need it could save
you a little time every day; so when do you need it? Maven recompiles
source files, but it won’t clean up the class files of deleted and
renamed source files for you. If you delete or rename a source or a
resource file, it’s a good idea to run a clean build to avoid
compilation errors, and to prevent old files from being bundled into
packages. If you run mvn clean
every build, you delete everything,
including class files with unchanged source files, which means a longer
rebuild.
Run Verify After Pulling Code or Changing Branches
Before you start working on new code, make sure you can build it.
Usemvn verify
to ensure that everything is in working order. Verify
runs the entire build including integration tests, which is why the
documentation describes it as the best default way to run a
build.
Be sure to run clean after you pull or switch branches to get rid of any
old class files you have that may not belong in the new source tree.
Review Build Warnings
Check and fix any build warnings that pop up, including seemingly small things such as encoding problems or undefined versions. These issues can easily sneak into a project, and fixing them can prevent problems from piling up and help avoid unpleasant surprises down the road. It’s difficult to see all the warnings in a stream of output, so here’s a tip: set the log level to WARN and run the build.
mvn -Dorg.slf4j.simpleLogger.defaultLogLevel=warn compile
Don’t Depend on Transitive Dependencies
Explicitly declare any dependencies that your code uses, rather than relying on transitive dependencies. Transitive dependencies (the dependencies of your dependencies) are usually available on your project’s classpath, making it tempting to reach-in and use them. Don’t, as this hurts build repeatability. When several versions of the same dependency exist, it’s likely you won’t be aware of where your dependency is coming from, and it’s almost certain the version will change upstream without your knowledge, possibly stoping your code from compiling. Avoid this by explicitly declaring all required dependencies in your project’s POM. You can go further, and ban transitive dependencies with the Maven Enforcer Plugin.
Create Custom Plugins
While Maven comes with a large set of default plugins, sometimes you need more. Instead of scripting, take some time to learn to build custom plugins. By creating plugins you’ll have more control over your build process, and you can make them into reusable components. Maven plugins can exist in a multi-modular project, or they can be published to a repository.
Finally, Embrace Maven Conventions
Maven has a set of conventions and best practices that are widely used in projects. These conventions cover everything from project structure to naming, and they’re designed to make Maven projects more maintainable and portable. While it is sometimes tempting to deviate from these conventions, you’re better off sticking to them. When you follow the conventions, you’ll have fewer battles with the tool, and your project will be more recognisable to other Maven users. You would struggle to find better examples of Maven projects than the Maven project itself on GitHub. Using Maven effectively requires a bit more than just knowing the commands. Other build tools emphasise customisation over everything else, Maven focusses on maintainability, reliability, and reusability. Nobody wants an exciting build, and keeping builds boring makes Maven the best available tool for Java projects.