• Always use the maven-enforcer-plugin
    • Enforce dependency convergence
      • Otherwise it’s possible that you depend on two different jars which both depend on log4j. Which one gets used at compile time depends on a set of rules that you shouldn’t have to remember. They can both (!) get exported as transitive dependencies.
    • Require plugin versions (for all plugins, even the built in ones)
      • Define them in pluginManagement in the parent pom to define versions
        • Otherwise a new version of maven-surefire-plugin could break your build
  • Use dependencyManagement in the parent pom to use versions consistently across all modules
  • Periodically run mvn dependency:analyze
    • It’s possible that you’re getting a dependency transitively that you directly depend on at compile time. If so, it’s important to add it to your pom with the version you require. This plays nicely with the enforcer plugin.
    • It’s possible that you’re declaring extra dependencies that you don’t use. This doesn’t work properly 100% of the time, especially with libraries that are designed to have optional pieces (i.e. slf4j-api gets detected properly, but slf4j-log4j12 fails).
  • Maven CI best practices http://www.sonatype.com/people/2009/01/maven-continuous-integration-best-practices/
    • Automate Snapshot Deployment through the CI system
    • Isolate Local Repostitories
      • use -Dmaven.repo.local=%system.teamcity.build.workingDir%/.m2
    • Regularly purge local repositories
    • Enable Batch Mode with -B
      • This will make the logs shorter since it avoids the dependency download progress logging. It also ensures that the build won’t hang due to waiting for user input.
    • Enable Full Stack Traces with -e
  • Put the parent POM in the root directory, next to the child modules
  • Other resources