Defining named set of dependencies in parent pom - maven

I would like to be able to define set of dependencies in parent pom and to be able to include these sets in children poms.
For instance:
parent pom {
set1 {artifact1, artifact2, artifact3}
set2 {artifact4, artifact5}
set3 {artifact6, artifact7}
}
child1 pom {
dependencies {set1, set2}
}
child2 pom {
dependencies {set2, set3}
}
This behaviour is also described here (not implemented): http://docs.codehaus.org/display/MAVEN/Profiles+for+optional+dependencies
Is there any way to do this? Thanks!

I don't think there is a way to achieve what you want via parent/child relationship of POMs (although would be glad to be corrected on this), but one solution that might work for you is to define groups of dependencies in their own POM file and then add a dependency to this POM in your individual modules.
So for example, here is a POM definition for some Spring dependencies:
<groupId>com.xyz</groupId>
<artifactId>spring-deps</artifactId>
<version>SNAPSHOT</version>
<packaging>pom</packaging>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>3.1.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.1.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>3.1.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>3.1.4.RELEASE</version>
</dependency>
</dependencies>
Then in your module's pom you define a dependency to this pom:
<groupId>com.xyz</groupId>
<artifactId>module1</artifactId>
<version>SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>com.xyz</groupId>
<artifactId>spring-deps</artifactId>
<version>SNAPSHOT</version>
<type>pom</type>
</dependency>
</dependencies>
and all the Spring dependencies defined in the spring-deps pom are automatically included for you.

Related

How to lock version Dependency/Plugin with Maven archetype

I'm currently working on how to fix version of dependencies and plugins with maven archetype. Here is how my archetype-resources/pom.xml look like.
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>${spring-version}</version>
The archetype-metadata.xml look like that:
<requiredProperties>
<requiredProperty key="spring-version">
<defaultValue>2.1.5.RELEASE</defaultValue>
</requiredProperty>
</requiredProperties>
Then i added the property to the archetype.properties file
spring-version=2.1.5.RELEASE
When I create an project from this archetype it will correctly show the 2.1.5.RELEASE version.
However this method seems not the best when you have a lot more dependencies or it is not the proper manner on how to lock version?
from https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
Dependency Management
The dependency management section is a mechanism for centralizing dependency information. When you have a set of projects that inherits a common parent it's possible to put all information about the dependency in the common POM and have simpler references to the artifacts in the child POMs. The mechanism is best illustrated through some examples. Given these two POMs which extend the same parent:
Project A:
<project>
...
<dependencies>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-a</artifactId>
<version>1.0</version>
<exclusions>
<exclusion>
<groupId>group-c</groupId>
<artifactId>excluded-artifact</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-b</artifactId>
<version>1.0</version>
<type>bar</type>
<scope>runtime</scope>
</dependency>
</dependencies>
</project>
Project B:
<project>
...
<dependencies>
<dependency>
<groupId>group-c</groupId>
<artifactId>artifact-b</artifactId>
<version>1.0</version>
<type>war</type>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-b</artifactId>
<version>1.0</version>
<type>bar</type>
<scope>runtime</scope>
</dependency>
</dependencies>
</project>
These two example POMs share a common dependency and each has one non-trivial dependency. This information can be put in the parent POM like this:
<project>
...
<dependencyManagement>
<dependencies>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-a</artifactId>
<version>1.0</version>
<exclusions>
<exclusion>
<groupId>group-c</groupId>
<artifactId>excluded-artifact</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>group-c</groupId>
<artifactId>artifact-b</artifactId>
<version>1.0</version>
<type>war</type>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-b</artifactId>
<version>1.0</version>
<type>bar</type>
<scope>runtime</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
Then the two child poms become much simpler:
<project>
...
<dependencies>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-a</artifactId>
</dependency>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-b</artifactId>
<!-- This is not a jar dependency, so we must specify type. -->
<type>bar</type>
</dependency>
</dependencies>
</project>
<project>
...
<dependencies>
<dependency>
<groupId>group-c</groupId>
<artifactId>artifact-b</artifactId>
<!-- This is not a jar dependency, so we must specify type. -->
<type>war</type>
</dependency>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-b</artifactId>
<!-- This is not a jar dependency, so we must specify type. -->
<type>bar</type>
</dependency>
</dependencies>
</project>
you can do this also for plugins with
What is pluginManagement in Maven's pom.xml?

How to remove spring boot dependency using dependencyManagement?

In my pom file i have the following:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
I use this because the project already have a parent pom.
I want to remove some of its dependencies such as:
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>6.4.3</version>
</dependency>
How do I do this?
spring-boot-dependencies does not add any dependency. It mostly consists out of a giant <dependencyManagement> block containing managed versions for several libraries. This allows you to use versions of libraries that are known to work properly with the given version of Spring boot.
That means that you no longer have to add the <version> to each dependency you define.
It also means that if you have a dependency upon elasticsearch, it certainly doesn't come from spring-boot-dependencies.
If your goal is to override one of the versions, you can, by manually adding <version> to your dependency.
Otherwise, you can usually exclude a dependency by using <exclusions>:
<dependency>
<groupId>com.xyz</groupId>
<artifactId>artifact-abc</artifactId>
<exclusions>
<exclusion>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
</exclusion>
</exclusions>
</dependency>

Maven 2.xx dependency override in child

Are there any way to override a dependecy version in child project over parent's version?
Parent pom.xml
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>3.1.1.RELEASE</version>
<dependency>
Child pom.xml
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>3.2.1.RELEASE</version>
<dependency>
I did not find any working articles on this subject.

Why does my project always try to download the latest spring-beans 3.2.*.RELEASE artefact

I have a spring MVC web application that has the following spring dependencies:
spring-aop-3.2.1.RELEASE
spring-beans-3.2.1.RELEASE
spring-context-support-3.2.1.RELEASE
spring-context-3.2.1.RELEASE
spring-core-3.2.1.RELEASE
spring-expression-3.2.1.RELEASE
spring-jdbc-3.2.1.RELEASE
spring-jms-3.2.1.RELEASE
spring-orm-3.2.1.RELEASE
spring-test-3.2.1.RELEASE
spring-tx-3.2.1.RELEASE
spring-web-3.2.1.RELEASE
spring-webmvc-3.2.1.RELEASE
spring-aspects-3.2.1.RELEASE
spring-spring-security-core-3.2.0.RELEASE
spring-security-web-3.2.0.RELEASE
spring-security-config-3.2.0.RELEASE
spring-security-taglibs-3.2.0.RELEASE
My question is that when i build using mvn clean install does it try and download spring-beans-3.2.10.RELEASE. I am assuming one of my dependencies is dragging it in but not sure which.
Any help would be greatly appreciated.
Thanks in advance.
You can define your dependencies in the <dependencyManagement> section of POM. The versions that you define in <dependencyManagement> will apply not only to the dependencies that you mention in the top-level <dependencies> section, but also to their transitive dependencies.
For example:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>3.2.1.RELEASE</version>
</dependency>
...
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>
...
</dependencies>
These fragments will make sure that Maven uses only version 3.2.1.RELEASE. (Note that there are no <version> in the second section.)
If you still want to find out where that dependency comes from, and if you use Eclipse, open your pom.xml and have a look at the Dependency Hierarchy tab. If necessary, you can double-click on dependencies there: it will open the dependency's own pom.xml where you can research transitive dependencies further.
You can solve your proble in the following way:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>4.1.0.BUILD-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependencies>
and then you can manage your dependency without worry of single version number. In this way all spring dependencies will have the same 4.1.0.BUILD-SNAPSHOT version

Resolve maven transitive dependency conflict

My project depends on a thirdparty library, the dependency is defined in my POM like this:
<dependency>
<groupId>thirdparty</groupId>
<artifactId>main</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
This thirdparty main library in turn depends on other two libraries, here's a part of dependency management defined in its pom:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>thirdparty</groupId>
<artifactId>x</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>thirdparty</groupId>
<artifactId>y</artifactId>
<version>1.0.0</version>
</dependency>
...
Now the thirdparty x library has a dependency on y defined in its pom like this:
<dependency>
<groupId>thirdparty</groupId>
<artifactId>y</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
Note the snapshot version! This looks like a problem in thirdparty poms, but I have no control over it.
The interesting thing though is that if you try to maven build the main thirdparty project it uses (resolves and installs to local repo) the correct thirdparty:y:1.0.0 version of artifact. But when I'm building my original project it tries to resolve the snapshot version of thirdparty:y.
My questions are:
Why does this happen? I was sure that maven should choose the artifact version that is found closest to the project root, which would be 1.0.0 in my case.
Is there any way to fix this problem without adding explicit dependencies to thirdparty:y:1.0.0 to my project's pom?
First of all make sure you realy need the snapshot version. There should normaly be a released version (without -SNAPSHOT).
if you do need it, this should do the trick:
<properties>
<dependeny.main.version>1.0.0-SNAPSHOT</dependeny.main.version>
<dependeny.x.version>1.0.0</dependeny.x.version>
<dependeny.y.version>1.0.0</dependeny.y.version>
<properties>
<dependencies>
...
<dependency>
<groupId>thirdparty</groupId>
<artifactId>main</artifactId>
</dependency>
<dependency>
<groupId>thirdparty</groupId>
<artifactId>x</artifactId>
</dependency>
<dependency>
<groupId>thirdparty</groupId>
<artifactId>y</artifactId>
</dependency>
...
</dependencies>
<dependencyManagement>
<dependencies>
...
<dependency>
<groupId>thirdparty</groupId>
<artifactId>main</artifactId>
<version>${dependeny.main.version}</version>
<exclusions>
<exclusion>
<groupId>thirdparty</groupId>
<artifactId>x</artifactId>
</exclusion>
<exclusion>
<groupId>thirdparty</groupId>
<artifactId>y</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>thirdparty</groupId>
<artifactId>x</artifactId>
<version>${dependeny.x.version}</version>
<exclusions>
<exclusion>
<groupId>thirdparty</groupId>
<artifactId>y</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>thirdparty</groupId>
<artifactId>y</artifactId>
<version>${dependeny.y.version}</version>
</dependency>
...
</dependencies>
</dependencyManagement>
I hope this helps you out.

Resources