what are the maven dependency policies on transient exclusions - maven

I am using Maven 3, and I have a small project with a module that depends on another module of this project. The lower one is basically the JPA entity model and the other one the REST service using it. All of them have spring-boot dependencies
I wanted to use more recent Hibernate and EhCache dependencies and sorted these out in the JPA module, excluding them, and the maven dependency:tree shows everything as I wanted it.
But when I add that module in my other module as dependency, all those excluded dependency versions are back again in my dependency tree.
Why does Maven pick the dependencies deeper in the tree branches (and excluded) before the versions I defined on first level in my module?

I guess you defined the exclusions in the <dependencyManagement> section of the POM of the first module. When another module referenced the first module, these exclusions are gone, right?
What I would suggest:
If you need newer versions of a given dependency, do not use exclusions, but use <dependencyManagement> to define the new version. This overwrites all transitive version definitions.

Related

How to exclude a transitive dependency inside a transitive dependency?

I have a maven project "Project-1". This project uses some dependencies, let's consider jackson databind 2.9.8
Another maven project "Project-2" uses "Project-1" as a dependency.
"Project-3" uses "Project-2" as a dependency.
In the "Project-3", I used jackson databind 2.10.0 using the dependency management tag. Additionally, under the dependency tag of "Project-2" inside the pom of "Project-1", I added the exclusion tag of jackson databind.
In the dependency tree of "Project-3", only one version of jackson databind is getting resolved which is 2.10.0
But, In a security scan in the pipeline, it is still reporting some security issue for the jackson databind 2.9.8
I am not sure how come this version is getting resolved even though it is not mentioned in the dependency tree.
I am trying to add the exclusion in the "Project-1" now. But, is there any better way to exclude it in "Project-3"?
It seems like the dependency "jackson databind" is not pulled by Maven, so their is no way to exclude it in Maven.
It may be the dependency of a Maven plugin you run, and you can try to find that out by running Maven with the debug flag -X. Then you might need to remove that plugin.
It may as well be the case that your "scanner" does not only scan the dependencies of the project, but other things as well. Maybe it is a bug in the scanner so that excluded artifacts are also scanned.

Need to know the difference between spring-boot-starter-parent and spring-boot-parent

Can some one explain me the difference between spring-boot-parent and spring-boot-starter-parent, As i have seen in one of the GIT HUB code link attached below where they have written separate modules for spring-boot-starter-parent and spring-boot-parent.
https://github.com/spring-projects/spring-boot/blob/master/spring-boot-project/
If any one knows the difference between these two dependencies pls let me know, Also in most of the projects we generally use spring-boot-starter-parent as parent but not spring-boot-parent when both of them shares the same parent spring-boot-dependencies.
https://github.com/spring-projects/spring-boot/blob/master/spring-boot-project/
As described at https://www.baeldung.com/spring-boot-starter-parent
Spring-boot-starter-parent
The spring-boot-starter-parent project is a special starter project –
that provides default configurations for our application and a
complete dependency tree to quickly build our Spring Boot project.
It also provides default configuration for Maven plugins such as
maven-failsafe-plugin, maven-jar-plugin, maven-surefire-plugin,
maven-war-plugin.
Beyond that, it also inherits dependency management from
spring-boot-dependencies which is the parent to the
spring-boot-starter-parent.
spring-boot-parent
Sometimes we have a custom Maven parent. Or, we may prefer to declare
all our Maven configurations manually.
In that case, we may opt to not use the spring-boot-starter-parent
project. But, we can still benefit from its dependency tree by adding
a dependency spring-boot-dependencies in our project in import scope.
Spring Boot Starter Parent helps us with managing dependency versions, the java version used by project and the default configuration for plug-ins, as we don't have to specify a lot of things manually.
It helps us with the following :
Configuration
Dependency management
Default plugin configuration (default configurations for maven-failsafe-plugin, maven-jar-plugin and maven-surefire-plugin etc)
According to spring-boot doc :
Starters are a set of convenient dependency descriptors that you can
include in your application. You get a one-stop shop for all the
Spring and related technologies that you need without having to hunt
through sample code and copy-paste loads of dependency descriptors
The spring-boot-starter is the Core starter and provides functionalities including auto-configuration support, logging and YAML.It defines spring-boot-dependencies as the parent pom .
In the github url that you provided , they have kept a separate module to specify the parent spring-boot-dependencies in the pom.It might be because they needed to use the spring-boot-dependencies , dependency tree alone without the auto-configuration and plugin configuration , and publish it as separate jar for some use-case.
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${revision}</version>
<relativePath>../spring-boot-dependencies</relativePath>
</parent>
https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-parent/2.1.6.RELEASE
I believe you meant the difference between spring-boot-starter-parent and spring-boot-starter.
spring-boot-starter-parent - has spring-boot-dependencies as the parent and hence provides various spring-boot dependencies and helps in dependency management. In addition to this spring-boot-starter-parent on it's own helps in plugin management as well.
So if you use only spring-boot-dependencies you can benefit from the dependency management provided by it but instead if you use the spring-boot-starter-parent, you get dependency management + plugin management.
spring-boot-starter - It is a dependency provided by spring-boot-dependencies which provides dependencies for autoconfigure, logging and also spring-core. In order to pull any dependency from the starter or from spring-boot-dependencies, you need to explicitly add it as a dependency in your main pom.

Spring boot war file with unnecessary jars

I am making war packaging of my spring boot. made spring boot starter tomcat as provided, removed spring boot maven plugin.
But I still see tomcat jdbc and tomcat juli, to name a few (even junit, but it could be from other custom dependencies, so discounting this for this question). I am using logback, but I see log4j over slf4j from starter web.
Can I ask, how to skip unwanted jars and keep my package nice and tidy
Maven has the concept of "scope" for dependencies. You probably know the scope test which is used for unit test dependencies which should not go into the final product. Use this scope for junit.
What you need is the scope provided for the Tomcat dependencies. This tells Maven: "Don't include it; when the code is run, someone else will make sure this dependency is on the classpath".
The dependency log4j-over-slf4j is necessary when one of your dependencies still uses log4j to log. log4j-over-slf4j contains the code to redirect those calls to logback.
Now you will face the case where you can't change the scope because it's in a POM of someone else.
The correct solution here is to define the dependency with the correct scope (and version) in a dependencyManagement element in your POM. This definition will be used when any POM asks for this group+artifactId. So even when some deep dependency of Spring Boot pulls that in, your WAR will be build with the version and scope from the dependencyManagement element.
See also:
Dependency Scopes
Dependency Management

Maven: How to include a dependency with a specific build profile?

I have a project where I use Spring Boot 1.1.2.RELEASE which uses Spring 4.1.5, and Spring HATEOAS 0.10.0.RELEASE which uses Spring 4.0.9. This causes some dependency problems like the infamous java.lang.ClassNotFoundException: org.springframework.beans.factory.SmartInitializingSingleton.
I dug into the POM of spring-hateoas and found that there are different profiles defined, one of them being spring41 which depends on Spring 4.1.5. Is it possible to select this profile in my <dependency> section, or do I have to exclude the Spring dependencies?
Automatically selecting a profile for a build isn't easy. You can enable it by default in your personal settings.xml but that breaks the build for everyone who doesn't have the same file.
You can't enable a profile in the POM of the project.
With Maven 3.3, you can add the profile to ${maven.projectBasedir}/.mvn/maven.config. Since this file is part of the project, it's easy to share. You can use the Maven Enforcer plugin to make sure everyone uses a Maven version with actually uses the file.
If you can't use 3.3, then your best bet is to exclude the dependencies. If you have a parent POM, then you can use a dependencyManagement element to do it for all POMs in the reactor build.

Dependency conflict resolution with different group id?

Artifacts with conflicting content:
org.javassist:javassist:jar:3.17.1-GA && javassist:javassist:jar:3.12.1.GA
The former comes from Hibernate and the latter from Guava. Both end up in the final war file. The problem is that the classic conflict resolution mechanisms fail because the group id is different. So both the jars end up in the final project deliverable.
I can't just exclude Guava's dependency in the managed dependencies because the project is a multi-module. Some modules use Guava w/o Hibernate. They would miss their javassist dependency. But if I don't the "excess" artifact will pop up in the project's war file.
Is there a way to tell Maven those two dependencies are in fact two different versions of the same code ?
I'd stick with the following solution:
Add explicit dependency on javassist artifact in main pom.xml of your project (so that all of the child modules inherit this dependency).
Exclude javassist both from Hibernate and Guava.
Most important: add a comment indicating why you need javassist dependency :)

Resources