Enforce managed dependencies in Maven projects
Enforce managed dependencies in Maven projects
5. Juni 2015 2 Kommentare zu Enforce managed dependencies in Maven projectsWorking 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
- either in a top level pom.xml file
- or in a pom.xml file which acts as a BOM (bill of materials):
<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>
2 Comments
I thought that managing dependencies is the reason why there is maven-enforcer-plugin:
https://github.com/jtulach/minesweeper/blob/master/pom.xml#L59
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.