Effect of "overriding" exclusions in maven dependency - maven

How are exclusions in the parent pom affected by exclusions in the child pom? Are the exclusions additive? Here's an example:
....
<dependencyManagement>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
<exclusions>
<exclusion>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencyManagement
....
In Child pom -
.....
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<exclusions>
<exclusion>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
</exclusion>
</exclusions>
</dependency>
....
Ultimately, are both commons-collections and cglib excluded? If so, is there any way I can "bring back" commons-collections for the child project?

Yes, Maven's exclusions are additive. You'll have both exclusions. There is no way to cancel some inherited exclusion other than just re-add it as a new local dependency.
And by the way, it is about 1-2 minutes to verify this at your own computer...

Related

Overwrite exclusion with non-exclusion in child POM

If I have an exclusion in my parent POM, something like this:
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>1.2.3</version>
<exclusions>
<exclusion>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
</exclusion>
</exclusions>
</dependency>
How would I get rid of that exclusion or unexclude in my child POM whatever I've excluded via parent POM?
I've tried an empty <exclusions> tag, hoping it would overwrite the entirety of the exclusion (with now none) coming from the parent, but it doesn't seem to be working:
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<exclusions>
</exclusions>
</dependency>
Is there any way to do that?
Just figured it out,
just include the dependency in the child POM, two negatives make a positive
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.2.3</version>
</dependency>
In fact the first dependency doesn't even have to be restated, just the ones explicitly excluded in the parent POM.

Where to get the exclusion items in Spring Boot Starter Packages

I'm using Spring initializr to have the necessary package and downloading. Once I download, there are changes that I'm making in the pom.xml like excluding packages like slf4j, logging (when i plan to use log4j2) and excluding tomcat when trying to deploy into standalone server.
I don't know what are the other items that are capable to exclude. Is there any documentation like which package contains additional artifacts? Trying to avoid certain jars while packaging so that I think I can reduce the package(jar/war) size.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
All spring boot starter packages can be found here:
https://github.com/spring-projects/spring-boot/tree/master/spring-boot-project/spring-boot-starters
They are all just pom.xml files. You can exclude anything you want from any dependency you are using by analyzing the pom's dependencies in the started packages.

Why isn't maven including a needed transitive dependency?

I am converting our Jenkins Freestyle build to Declarative Pipeline mode. I am using the same POM files.
But whenever i run the pipeline build, i see that the desired war is missing a transitive dependency. The Freestyle build includes that missing dependency however.
The Main parent POM includes:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>net.sf.dozer</groupId>
<artifactId>dozer</artifactId>
<version>5.5.1</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</dependencyManagement>
The second parent includes section below, :
<dependencies>
<dependency>
<groupId>net.sf.dozer</groupId>
<artifactId>dozer</artifactId>
</dependency>
</dependencies>
For both build processes, the dozer artifact is contained in the war file. But dozer contains a dependency of its own:
<dependencies>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.1</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
It is this commons-beanutils that I am missing from my final war when i do the Pipeline build. Since I am using the same POM files for both build processes, how can this be possible?
Please help

Override version of transitive dependencies in Maven

I have the following in my pom
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>2.4.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-core</artifactId>
<version>1.0-groovy-2.4</version>
<scope>test</scope>
<exclusions>
<exclusion>
<artifactId>org.codehaus.groovy</artifactId>
<groupId>groovy-all</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-spring</artifactId>
<version>1.0-groovy-2.4</version>
<scope>test</scope>
<exclusions>
<exclusion>
<artifactId>org.codehaus.groovy</artifactId>
<groupId>groovy-all</groupId>
</exclusion>
</exclusions>
</dependency>
Basically, I want to force my second and third dependencies to use the version of groovy-all that I'm setting in my first dependency. Is there a better way to do this than setting an exclusion on each of them?
Since as a first dependency you're explicitly defining a version of the groovy-all dependency, this will override the version of this dependency for all transitive dependencies needing this exact dependency. Hence, you won't have to define explicit exclusions.
To validate this, you can run the following before and after the change:
mvn dependency:tree -Dverbose
And compare the output.
Fix is to lock down the version, either via a direct dependency, or a dependency-management section.

unable to remove tomcat jdbc dependency

I am building a spring-boot application using an alternative to tomcat related stuff (jetty instead of tomcat and hikariCP instead of tomcat-jdbc) and want to exclude them from my dependencies written in pom.xml
I did that for 2 of the packages as shown below -
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>2.6.0</version>
</dependency>
But there is some dependency which is including tomcat-jdbc as part of it.
Is there a way to debug that and find out which dependency is including tomcat jdbc as part of it?
mvn dependency:tree
If you run mvn dependency:tree, you will see that there are now a number of additional dependencies.

Resources