Skip to content

Maven tips and good practices

mdutoo edited this page Aug 23, 2012 · 10 revisions

Content of POM files

Avoid duplication: configuration is inherited from the parent POM, no need to redefine everything in each POM.

Always set artifacts' versions in dependencyManagement/dependencies, not directly in dependencies. That eases management, helps to keep coherence, to uniform the versions used by sub-modules and ensure the build and test environment will be relevant regarding the final runtime environment.

Same rule for plugins which versions must be defined in build/pluginManagement/plugins rather than directly in build/plugins. That also allows to share some common plugin configuration between modules.

Never use ${project.version}, ${version} or ${pom.version} in dependencyManagement, prefer use of a property. Such dynamic properties will be overridden at inheritance, generating issues for any dependent project with a different versioning.

If using artifacts not available from the Maven Central, it's better to use a self-hosted Maven repository (for instance Nexus) that will proxy other repositories. That way, required artifacts for building are kept in a cache and still available even if the source repository is down (or encounters any issue). So, when needing an artifact for a third-party public repository, ask your Maven repository administrator to add a proxy on it rather than referencing it into the POM. A specific Maven profile can still be set to circumvent that rule and directly call the repository.

There's no need to distinguish the POM listing modules to build and the parent POM of those modules. That practice is confusing and doesn't provide big benefits, even if it's still often used in Apache projects.

Root POM and other module listing POMs should only contain versions for dependencies (and not dependencies themselves), and some project properties/build profiles/information . They should never contain e.g. assembly configuration (otherwise they could not be built independently using the -N option, see below), which should rather go in a specific submodule.

To run a specific test with maven :

mvn -Dtest=className test

How to use common test classes in different projects ?

Situation : There are some service mocks in the HTTP discovery project that I want to re-use in another project. These mocks are packaged in src/test/java so they are unavailable in other projects, even with a dependency.

One solution is to create a separated project containing only the mock code and then add dependencies in other projects to get access to the mock classes. Of course, the mock package must be in src/main/java to be usable. In addition, you need to set the dependency scope to 'test' to avoid to have the mock classes in the final jar.

See http://stackoverflow.com/questions/174560/sharing-test-code-in-maven#174670

Another solution, which avoid to create a specific project, is to use the following goal :

<goals>
    <goal>test-jar</goal>
</goals>

See : http://stackoverflow.com/questions/174560/sharing-test-code-in-maven

How to build a submodule whitout its parent :

Use the "-N" Maven option (-N,--non-recursive: Do not recurse into sub-projects). This is useful to focus on build problems in a submodule when you've checked it out for the first time in a while (and therefore don't have the parent installed yet). NB. alternatively, you might use separate parent pom and module aggregator pom.

How to solve m2e "Plugin execution not covered by lifecycle configuration" problem in pom.xml :

Like said here, tell m2e to ignore it, either by right-click > Quick Fix on error in Problems view or by adding in pom.xml the right snippet in pluginManagement, or use one of the other methods listed there.

More tips and options

See http://doc.nuxeo.com/display/CORG/Maven+usage#Mavenusage-AdvancedMavenoptions

Clone this wiki locally