Enforce managed dependencies in Maven projects

Enforce managed dependencies in Maven projects

2 Kommentare zu Enforce managed dependencies in Maven projects

Working with dependencies between project modules or to external libraries is one of Maven’s core features – it’s simply done by declaring the reference to the required artifact in a pom.xml file:

<project ...>
...
  <dependencies>
    <dependency>
      <groupId>com.buschmais.jaxbfx</groupId>
      <artifactId>jaxbfx</artifactId>
      <version>1.1.0</version>
    </dependency>
  <dependencies>
...
</project>

If the project grows it becomes very likely that such an artifact will be used by several modules. In most cases it’s not just a good idea but also necessary to make sure that the same version is used in all cases.

Maven therefore provides a mechanism to manage dependencies, i.e. to declare the version to be used for a specific artifact

<project ...>
...
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>com.buschmais.jaxbfx</groupId>
        <artifactId>jaxbfx</artifactId>
        <version>1.1.0</version>
      </dependency>
    <dependencies>
  <dependencyManagement>
...
</project>

The dependency can now be referenced without the version, this information will be taken from the dependency management section:

<project...>
...
  <dependencies>
    <dependency>
      <groupId>com.buschmais.jaxbfx</groupId>
      <artifactId>jaxbfx</artifactId>
    </dependency>
  <dependencies>
...
</project>

There’s a further benefit of this approach: It becomes very easy to change the version of a required library even for large multi-module projects.

To achieve this it’s necessary that all used dependencies are managed and no dependency with an explicit version is declared.

Such a constraint can be defined and verified using jQAssistant:

<constraint id="maven:DependencyVersionMustBeManaged">
  <description>All dependency versions must be managed.</description>
  <cypher><![CDATA[
    match
     (project:Maven:Project)-[:HAS_MODEL]->(model)-[:DEPENDS_ON]->(dependency:Artifact)
    where
      has(dependency.version)
    return
      project.fqn as MavenProject, dependency.fqn as Dependency
  ]]></cypher>
</constraint>

Another question which may come up is in which pom.xml the management section should be placed. Usually the answer is: take the root project. This rule can also be be enforced by a constraint:

<constraint id="maven:ManageDependencyInRootProject">
  <description>All dependencies must be managed in the root project.</description>
  <cypher><![CDATA[
    match
      (project:Maven:Project)-[:HAS_MODEL]->()-[:MANAGES_DEPENDENCY]->(dependency:Artifact)
    where
      (project)-[:HAS_PARENT]->() // the root module has no parent
    return
      project.fqn as MavenProject, dependency.fqn as Dependency
  ]]></cypher>
</constraint>

About the author:

@dirkmahler

2 Comments

    • Dirk Mahler  - 14. Oktober 2015 - 8:28

      You’re right, there’s the enforcer plugin but jQAssistant gives you more options. The converge rule of the Maven enforcer plugin makes sure that versions of dependencies are the same – a common way of achieving this is using the dependency management. In larger projects you might want to ensure that dependency management sections are only allowed in certain POM files (e.g. parents or BOMs) – this will be difficult with the enforcer plugin and that’s the point where jQAssistant may help.

Leave a comment

Back to Top