Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Accelerating Maven Builds: From Snail's Pace ๐ŸŒ ...

Accelerating Maven Builds: From Snail's Pace ๐ŸŒ to Rocket Speedย ๐Ÿš€

Are you tired of watching Maven builds crawl at a snailโ€™s pace, wasting precious development time? Spending too much time at the coffee machine, or fighting battles with wooden swords under the excuse โ€œmy codeโ€™s compilingโ€?

Join us to learn how to supercharge your Maven build! Weโ€™ll cover three main steps to start speeding up your project build. Learn how each speeds up your build, when they provide the biggest gains, and what pitfalls await.

Take the next step in boosting your developer productivity by learning practical tips to decrease context switching and increase development speed and feedback cycle. Your journey from snailโ€™s pace to rocket speed begins today!

Avatar for Maarten Mulders

Maarten Mulders

June 11, 2025
Tweet

More Decks by Maarten Mulders

Other Decks in Programming

Transcript

  1. , licensed under CC BY-NC 2.5, adopted to match the

    dark background and not hurt your eyes. "Compiling" by Randall Munroe #snail2rocket #maven Maarten Mulders (@mthmulders)
  2. (Hans Dockter, Gradle Inc.) โ€œ We havenโ€™t seen a company

    yet where investing into more ef cient builds was not leading to a signi cant return on investment. The most successful software teams on the planet are the ones with an ef cient build infrastructure. Quantifying the Costs of Builds #snail2rocket #maven Maarten Mulders (@mthmulders)
  3. SOME CONTEXT Mojo a goal inside a Maven plugin. Maven

    extension much like a Maven plugin, but more powerful. Lifecycle an ordered sequence of build phases (e.g. compile , test ). Module a subproject of a larger Maven project; not a Java module as part of the Java Module System. #snail2rocket #maven Maarten Mulders (@mthmulders)
  4. MEASURE YOUR BUILD MEASURE YOUR BUILD MEASURE YOUR BUILD MEASURE

    YOUR BUILD MEASURE YOUR BUILD #snail2rocket #maven Maarten Mulders (@mthmulders)
  5. THE OPENTELEMETRY MAVEN EXTENSION Time execution recorder for Maven Log

    time taken by each Mojo in the build lifecycle Comes as a Maven extension #snail2rocket #maven Maarten Mulders (@mthmulders)
  6. INSTALL THE EXTENSION 1. Create .mvn/extensions.xml in your project 2.

    Register the extension 3. Start an OpenTelemetry collector (such as Jaeger "all-in-one") Alternatively, declare it in your pom.xml. โ†’ <extensions> <extension> <groupId>io.opentelemetry.contrib groupId> <artifactId>opentelemetry maven extension artifactId> <version>1.46.0-alpha version> extension> extensions> Simpler alternatives #snail2rocket #maven Maarten Mulders (@mthmulders)
  7. ACTIVATE THE EXTENSION Run Maven as you did before, but

    add -Dotel.traces.exporter=otlp When done, open OpenTelemetry #snail2rocket #maven Maarten Mulders (@mthmulders)
  8. PARALLEL TEST EXECUTION PARALLEL TEST EXECUTION PARALLEL TEST EXECUTION PARALLEL

    TEST EXECUTION PARALLEL TEST EXECUTION #snail2rocket #maven Maarten Mulders (@mthmulders)
  9. WHAT IS IT? Parallel execution of tests inside a module.

    #snail2rocket #maven Maarten Mulders (@mthmulders)
  10. WHEN TO APPLY If you have idle cores or tests

    waiting for I/O. 1. Executes large number of tests in parallel 2. Executes long-running tests in parallel #snail2rocket #maven Maarten Mulders (@mthmulders)
  11. โš  CAVEATS 1. Tests must be parallelizable Non-thread safe tests

    will make the build will fail miserably. a Fix the tests a Add @Execute(SAME_THREAD) (JUnit speci c) 2. Can bottleneck a parallel build Use resources that would've built another Maven module. a Disable parallel test execution for speci c modules. #snail2rocket #maven Maarten Mulders (@mthmulders)
  12. HOW TO EXECUTE TESTS IN PARALLEL? 1. Through Sure re

    2. Through JUnit #snail2rocket #maven Maarten Mulders (@mthmulders)
  13. 1. USING MAVEN'S SUREFIRE PLUGIN Specify what to run in

    parallel using the parallel parameter: 1. none 2. methods 3. classes 4. classesAndMethods 5. all #snail2rocket #maven Maarten Mulders (@mthmulders)
  14. 1. USING MAVEN'S SUREFIRE PLUGIN (CTD.) Command line: mvn -Dparallel=classesAndMethods

    verify . In pom.xml : <plugin> <groupId>org.apache.maven.plugins groupId> <artifactId>maven suref re plugin artifactId> <version>3.5.3 version> <conf guration> <parallel>classesAndMethods parallel> conf guration> plugin> #snail2rocket #maven Maarten Mulders (@mthmulders)
  15. PROS AND CONS Advantages: Supports both JUnit 4 and TestNG.

    Maintained by the Maven core team. Disadvantages: All tests in a module need to be thread-safe. Con guration can be repetitive / verbose. Does not work with JUnit Jupiter. #snail2rocket #maven Maarten Mulders (@mthmulders)
  16. 2. USING JUNIT JUPITER 1. Using src/test/resources/junit-platform.properties. 2. Using system

    properties through argLine parameter. 3. Using Java annotations. #snail2rocket #maven Maarten Mulders (@mthmulders)
  17. Using src/test/resources/junit-platform.properties # activation of parallel test execution junit.jupiter.execution.parallel.enabled =

    true # tests per class (but classes in sequence) junit.jupiter.execution.parallel.mode.default = concurrent # classes in parallel junit.jupiter.execution.parallel.mode.classes.default = concurrent # both options can be combined! #snail2rocket #maven Maarten Mulders (@mthmulders)
  18. Using system properties through argLine parameter <plugin> <groupId>org.apache.maven.plugins groupId> <artifactId>maven

    suref re plugin artifactId> <version>3.5.3 version> <conf guration> <argLine> -Djunit.jupiter.execution.parallel.enabled=true -Djunit.jupiter.execution.parallel.mode.default=concurrent argLine> conf guration> plugin> #snail2rocket #maven Maarten Mulders (@mthmulders)
  19. Using Java annotations @Execution(CONCURRENT) class MyServiceTest { test methods are

    now being executed in parallel } #snail2rocket #maven Maarten Mulders (@mthmulders)
  20. PROS AND CONS Advantages: Finer granularity of test executions. Run

    single tests selectively in sequence. Maintained by the JUnit Jupiter team. Great IDE support w/ property les and annotations. Disadvantages: Speci c to JUnit Jupiter, not in TestNG, Spock and others. Harder to control from the command line. #snail2rocket #maven Maarten Mulders (@mthmulders)
  21. MAVEN DAEMON MAVEN DAEMON MAVEN DAEMON MAVEN DAEMON MAVEN DAEMON

    #snail2rocket #maven Maarten Mulders (@mthmulders)
  22. WHAT IS IT? Provides faster Maven builds using a daemon

    process. #snail2rocket #maven Maarten Mulders (@mthmulders)
  23. HOW DOES IT HELP? 1. Keeps the JVM and plugins

    "warm". 2. Runs multi-threaded by default without cluttering output. 3. Improved parallelism compared to "vanilla" Maven. Uses to build in topological order. Takari Smart builder #snail2rocket #maven Maarten Mulders (@mthmulders)
  24. WHEN TO APPLY? 1. Large project. 2. Many plugins. 3.

    "Heavy" plugins. #snail2rocket #maven Maarten Mulders (@mthmulders)
  25. โš  CAVEATS 1. Multi-threaded by default Non-threadsafe plugins may make

    build fail miserably. a Circumvent by specifying -T 1 a Address the root cause: x the plugin(s) #snail2rocket #maven Maarten Mulders (@mthmulders)
  26. HOW? 1. Install Maven Daemon 2. Retrain nger gymnastics: mvn

    โ†’ mvnd #snail2rocket #maven Maarten Mulders (@mthmulders)
  27. HOW? (CTD.) A few new tricks: Use mvnd --status to

    inspect details of the daemon process. Add -Dmvnd.buildTime=true for simple timing report. Add -Dsmartbuilder.profiling=true for advanced timing report. #snail2rocket #maven Maarten Mulders (@mthmulders)
  28. PARALLELIZING YOUR BUILD PARALLELIZING YOUR BUILD PARALLELIZING YOUR BUILD PARALLELIZING

    YOUR BUILD PARALLELIZING YOUR BUILD ! MAVEN MODULES EVERYWHERE ! #snail2rocket #maven Maarten Mulders (@mthmulders)
  29. EVALUATION PROS Faster builds when there are enough modules with

    few, distinct dependencies. (Almost) no need for ArchUnit or alike. Easier to exclude transient dependencies via Maven. Easier to build/test speci c parts (-pl services/github -am ). Plugins/annotation proc. cover as few sources as necessary. CONS Could hinder navigation between classes and modules. Needs awareness of runtime vs compile dependencies. May not be suitable for libraries. #snail2rocket #maven Maarten Mulders (@mthmulders)
  30. TO DO OR NOT TO DO? As always: it depends!

    Pro ts vs. added complexity For libraries: impact for consumers? For applications: does it impact architecture? #snail2rocket #maven Maarten Mulders (@mthmulders)
  31. DEMO (BACKUP) sysctl a | grep machdep.cpu machdep.cpu.cores_per_package: 10 machdep.cpu.core_count:

    10 machdep.cpu.logical_per_package: 10 machdep.cpu.thread_count: 10 machdep.cpu.brand_string: Apple M1 Max Screenshot #snail2rocket #maven Maarten Mulders (@mthmulders)
  32. MAVEN BUILD CACHE EXTENSION MAVEN BUILD CACHE EXTENSION MAVEN BUILD

    CACHE EXTENSION MAVEN BUILD CACHE EXTENSION MAVEN BUILD CACHE EXTENSION #snail2rocket #maven Maarten Mulders (@mthmulders)
  33. HOW DOES THE BUILD CACHE WORK? Reduces build time by

    skipping parts of the build which don't need to be executed. 1. Only execute parts of the build which changed. 2. Build subtrees of a multi-module project in isolation. 3. Normalize the version to avoid rebuilding across forks. 4. Project state restoration (e.g. artifacts). #snail2rocket #maven Maarten Mulders (@mthmulders)
  34. 1. WHICH PARTS HAVE CHANGED? A. MODIFICATIONS TO THE POM

    Changing dependencies, modifying plugins or executions, will invalidate the cache. B. MODIFICATION OF SOURCE CODE Use content ngerprinting to invalidate cache when source code changes. #snail2rocket #maven Maarten Mulders (@mthmulders)
  35. WHEN TO USE THE CACHE EXTENSION? 1. You use Maven

    3.9 or Maven 4. 2. Your project does not rely on 'quirks'. 3. Speed up 1. local developer build, and/or 2. CI builds (PRs), and/or 3. want to share cache with co-workers. 4. You are willing to invest time to make the cache portable. #snail2rocket #maven Maarten Mulders (@mthmulders)
  36. INSTALL THE EXTENSION 1. Create .mvn/extensions.xml in your project. 2.

    Register the extension by adding the following content: 3. (Optional) extend the default cache con guration. <extensions> <extension> <groupId>org.apache.maven.extensions groupId> <artifactId>maven build cache extension artifactId> <version>1.2.0 version> extension> extensions> #snail2rocket #maven Maarten Mulders (@mthmulders)
  37. โš  CAVEATS 1. Con gure relevant input les. 2. Add

    plugin parameters for reconciliation. 3. Filter non-essential les (IDE, etc). 4. Expect your tests not to run. 5. Remote cache not used (OS, pro les...). 6. Cache eviction. #snail2rocket #maven Maarten Mulders (@mthmulders)
  38. HONOURABLE MENTIONS HONOURABLE MENTIONS HONOURABLE MENTIONS HONOURABLE MENTIONS HONOURABLE MENTIONS

    We did not cover: Reduce logging (Logback, Log4J, mvn -q ) Logback has a NOPAppender SLF4J has a slf4j-nop binding Christian Stein's "junit5-looming" (showcase): JUnit 5 test engine with virtual thread support. Virus and threat protection. User home directory on network drive. #snail2rocket #maven Maarten Mulders (@mthmulders)
  39. WHAT DID WE LEARN? WHAT DID WE LEARN? WHAT DID

    WE LEARN? WHAT DID WE LEARN? WHAT DID WE LEARN? 1. Measure your builds. 2. Parallel test execution per module. 3. Using the Maven Daemon. 4. Feed mvnd with architecture improvements. 5. Maven Build Cache Extension. #snail2rocket #maven Maarten Mulders (@mthmulders)
  40. REFERENCES Please โญ โญ โญ โญ โญ this talk in

    the "My Devoxx" app โค bit.ly/snail-pace-rocket-speed-demos blog.bmarwell.de maarten.mulders.it @bmarwell.de @mthmulders @bmarwell @mthmulders #snail2rocket #maven Maarten Mulders (@mthmulders)