[devnexus 2026] Maven’s Hidden Secrets to Speed up your Build

Speaker: Ko Turk (@KoTurk77)

See the DevNexus live blog table of contents for more posts


Waiting

  • Showed spring boot app with tests. Took 51 seconds
  • Real builds could even take 30 minutes

General

  • About 75% use Maven, about half use Gradle (so many both) and small percentage Ant.
  • Maven created in 2002
  • Became top level Apache project in 2023
  • Maven 4 is a release candidate – it does parallel building better
  • mvnup check – for migrating to Maven 4
  • Can install through website, brew, sdkman, daemon, wrapper, etc

Daemon

  • JDK background process stays in memory so warm
  • Reuses plugins

Hierarcy

  • Lifecycles – clean, build, etc
  • Phases – clean, process-resources, compile, etc
  • Maven plugins
  • Maven goals

Also showed

  • Profiling plugins such as jcgay/maven-profiler or Gradle develocity
  • Adding echo ot the pre-clean phase
  • Maven clean verify vs mvn clean install
    • failsafe vs surefire. Can run integration tests in profile so control when run

Covered after I left: see deck

My take

I liked that he played music while running a build to show how long a simple build takes. The pirate/treasure map theme was fun. I had to leave this session at the halfway part but I enjoyed the part I saw. Good mix of slides and showing.

[devnexus 2024] apache maven 4

Speakers: Chandra Gunter and Rodrigo Graciano

@CGuntur and @rodrigograciano

For more, see the 2024 DevNexus Blog Table of Contents


General

  • Apache Maven 4 is still in alpha
  • Avoid profiles where can
  • Shoutout for mvn verify (vs maven install)
  • Sample code: https://github.com/c-guntur/maven4

Pain Points in Maven 3

  • Painful to maintain versions in multi module projects – flatten-maven-plugin helps with child versions but has hissues with profile interpolation. ci-friendly-flatten-maven-plugin solves profile interpolation problem but requires including third party plugin
  • No implicit way to separate build info from consumer info. Why do consumers need SCM location and Jira link – flatten-maven-plugin and c-friendly-flatten-maven-plugin help
  • Handling versions of sibling modules is a chore
  • We use default versions for plugins. Ex: compiler version has default so not everyone specifies.
    Creating BOM (Bill of Materials) not easy. No way to identify that default version is in use

Maven 4

  • Requires Java 17+ to run Maven and Java 17 to compile (but can use Java 17 to compile earlier version)
  • New schema version in <project> xmlns
  • <moduleVersion> is now 4.1.0
  • Can use <version>${revision}</version> without plugin – can pass from root pom or command line
  • Get warning in build log if use the default version number of any plugins
  • Two poms in .m2 for artifact. artifact-version-build.pom is what is used to build and artifact-version.pom is the consumer pom that goes to the repo when deploy
  • No need to specify version number of parent in multi module project. Figures out automatically. Version is still allowed. It is an optional field so can specify older version at will.
    • Build caching is improved so faster performance. ex: less re-compiling

My take

I didn’t take notes on Maven itself only the differences between Maven 3 and 4. I know it was necessary to get everyone on the same page. Given everyone raised their hand on using Maven, I wonder if could have been briefer. (Got to limitations of Maven 3 at 20 minute mark) I liked the interaction between the presenters to make it a conversation. The list of Maven 3 problems was great. And the demo of how Maven 4 fixes was good.

Switching your Gradle builds from JCenter to Maven Central

JCenter is being decommissioned on May 1st, 2021. Since many Gradle builds use JCenter by default, this means your Gradle build file is likely to have jcenter() in it. This means you have a few months to switch to Maven Central. Don’t worry, it’s easy.

Note: If you work for a company, you are hopefully using an internal binary repository proxy. (ex: Nexus, Artifactory, etc)

What’s the difference between JCenter and Maven Central?

The main benefits of JCenter are:

  • Some artifacts are in JCenter and not Maven Central – their authors are working on moving them to Maven Central. This is unlikely to affect FRC teams, but might affect people using an artifact that is more specialized.
  • It’s easier to publish to JCenter – Sonatype has been working on making it easier for Maven Central. Some of that is intrinsic though because Sonatype does a lot of verification.
  • JCenter is faster – Remember that artifacts are cached on your machine. So once you’ve downloaded the artifacts, your build performance is the same.

How do I find the affected files in GitHub?

Searching on github for either of these does not do what you might expect

  • jcenter user:boyarsky filename:build.gradle- the code tab returns 0 results
  • jcenter org:stuypulse filename:build.gradle – the code tab returns 2 results

That’s because github search only looks in files that have been updated or returned in search results in the past year. Unfortunately, the last year has not been particularly representative of a normal year. And people edit/search the contents of build.gradle files way less frequently than other file types.

I recommend just searching for the filename. That returns all your build.gradle files so you can edit them. (And since you are probably consistent in your choice of binary repository, you can sample a few matches to see if you have to change.

  • user:boyarsky filename:build.gradle – the code tab returns 5 results
  • org:stuypulse filename:build.gradle – the code tab returns 24 results

Tip: You may also have a reference to jcenter in your settings.gradle so I recommend searching that as well.

How do I edit the file?

GitHub has good Rest APIs so you can script this if you have a lot. If you don’t have a ton, either of the following is viable. (I had 5 build.gradle files in my personal repo and 3 of them were already using Maven)

Option 1 – Use the browser

  1. Open each link from the code tab of the search
  2. Choose the default branch (ex: main/master) from the pull down – search often returns a specific commit
  3. Drill down to the build.gradle file if not already there.
  4. Click the edit/pencil icon in the top right (just above the code)
  5. Change jcenter() to mavenCentral()
  6. Enter a commit comment and save
  7. If you want to make sure your build still works, run it (ex: Travis)

Option 2 – Clone the repos

(Tested on Mac; I don’t have Git Bash on my home computer so don’t know if it works exactly the same. I have used find on Git Bash though so I think it does)

  1. Clone the affected repos (if you don’t already have them)
  2. Go to a parent directory of the github repos (ex: <userHome>/git
  3. Run a UNIX command to update the list files find . -name build.gradle
  4. Run a UNIX command to update the affected files: find . -name build.gradle -exec sed -i ” -e ‘s/jcenter/mavenCentral/g’ {} \;
  5. Commit/push the affected repos (listed in step 3)
  6. If you want to make sure your build still works, run it (ex: ./gradlew build)