I have a pom.xml
like this to be used as a BOM (Bill of Materials). One of the defined dependencies is a *-test
artifact used for testing your code that uses the libraries from this BOM.
The question is: is it appropriate / good practice to specify that the *-test
artifact is just for test
scope in the BOM itself, or should this be left for the users of the BOM to specify in their project's POM, if needed?
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example.mylib</groupId>
<artifactId>mylib-bom</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>MyLib (Bill of Materials)</name>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.example.mylib</groupId>
<artifactId>mylib-cool-library</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.example.mylib</groupId>
<artifactId>mylib-test</artifactId>
<version>${project.version}</version>
<scope>test</scope> <!-- === HERE === -->
</dependency>
</dependencies>
</dependencyManagement>
</project>
I was looking at how existing projects do this and, for example, the Spring Framework BOM does not, indeed, define any scope explicitly. But I am still wondering if there is some unwritten rule for this or something like that?
BOM stands for Bill Of Materials. Maven lets us define the versions of the dependencies or transitive dependencies in a separate POM. A BOM package is a POM only jar file that is used to control the versions of a project's dependencies and provide a central place to define and update those versions.
Dependency scope is used to limit the transitivity of a dependency and to determine when a dependency is included in a classpath. This is the default scope, used if none is specified. Compile dependencies are available in all classpaths of a project. Furthermore, those dependencies are propagated to dependent projects.
Maintainer. A Maven pom defines the project structure including the stated dependencies. A bom defines the complete bill of materials of what dependencies are actually used - the effective dependencies.
Maven defines 6 scopes: compile, runtime, provided, system, test, and import.
Best practice is to let the user decide scope, and not set it in BOM (or parent pom).
When you set scope in BOM (to anything other than compile
) you change the default scope for that dependency, as seen from user projects. The default dependency scope in maven is compile
, so it's common practice to omit scope for a dependency when you want it to be compile. If the BOM imposes another scope, it can be a nasty surprise for other developers that use the BOM (or even yourself at a later point in time).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With