Maven and JBoss: how to use BOMs to keep releases in sync
- Published: 08 December 2012
When using Maven for creating and building your projects you have quite lots of freedom when it comes to choosing the library versions. However keeping in sync all the releases of a Java EE 6 project can be cumbersome. This tutorial shows how to use BOM (Bill of Materials) to solve this issue in a minute.
Each time you declare a dependency in your pom.xml you need by default to specify the version of a library you are going to use:
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.8.1</version> <scope>test</scope> </dependency>
Although it's true that you can use lots of strategies to pickup the LATEST/RELEASE version of a library (See this tip for learning more about it), when it comes to mixing lots of technologies, it would be easier if you could select a stack of libraries.
JBoss makes this process easier by distributing a complete set of Java EE 6 APIs including a Bill of Materials (BOM). A BOM specifies the versions of a "stack" . So, instead of specifying all the single library versions, you can just define which BOM version you are going to use and you'll be always sure to get the correct versions of artifacts.
Which BOM version for a Java EE 6 application stack ?
In order to use a Java EE 6 stack for your application, the suggested BOM is the 1.0.0.Final version of jboss-javaee-6.0-with-hibernate. If you want to further enhance your development environment with deployment and test tooling (e.g. Arquillian) include also jboss-javaee-6.0-with-tools stack. So here' what you need to add to your pom.xml in order to use a full Java EE 6 stack:
<dependencyManagement> <dependencies> <dependency> <groupId>org.jboss.bom</groupId> <artifactId>jboss-javaee-6.0-with-tools</artifactId> <version>1.0.0.Final</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.jboss.bom</groupId> <artifactId>jboss-javaee-6.0-with-hibernate</artifactId> <version>1.0.0.Final</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
Then, it's a simple matter to declare which module dependencies your project requires by adding them inside the dependencies section. There's no need to specify a version of the module as it gets inherited from the JBoss BOM.
<dependency> <groupId>org.jboss.spec.javax.faces</groupId> <artifactId>jboss-jsf-api_2.1_spec</artifactId> <scope>provided</scope> </dependency>
To see which version is going to get selected, use the dependency analysis tools in Maven:
[INFO] +- javax.enterprise:cdi-api:jar:1.0-SP4:provided
[INFO] | +- org.jboss.spec.javax.interceptor:jboss-interceptors-api_1.1_spec:jar:1.0.1.Final:provided
[INFO] | \- javax.inject:javax.inject:jar:1:provided
[INFO] +- org.jboss.spec.javax.annotation:jboss-annotations-api_1.1_spec:jar:1.0.1.Final:provided
[INFO] +- org.jboss.spec.javax.ws.rs:jboss-jaxrs-api_1.1_spec:jar:1.0.0.Final:provided
[INFO] +- org.hibernate.javax.persistence:hibernate-jpa-2.0-api:jar:1.0.1.Final:provided
[INFO] +- org.jboss.spec.javax.ejb:jboss-ejb-api_3.1_spec:jar:1.0.2.Final:provided
[INFO] +- org.hibernate:hibernate-validator:jar:4.2.0.Final:provided
[INFO] | \- javax.validation:validation-api:jar:1.0.0.GA:provided
[INFO] +- org.jboss.spec.javax.faces:jboss-jsf-api_2.1_spec:jar:2.0.2.Final:provided
[INFO] \- org.hibernate:hibernate-validator-annotation-processor:jar:4.2.0.Final:provided
You may upgrade an individual module by specifying the version explicitly. There's no crime in doing so. The JBoss BOM is there as a convenience and a reference point for the recommended module version matrix. It's up to you how closely to follow it.