Spring-Boot: How can we remove some dependencies from Effective pom? - java

I am using spring-boot 2.0.3.RELEASE. When I am clicking on "show Effective POM" option by using IntelliJ IDEA, it loads Effective POM. And there I can see a few dependencies that my client don't want to have at there side.
Is there any way to tell Maven not to include these dependencies? How can we exclude dependencies from effective poms?

Maven provides a way to exclude dependencies with the exclude tag
Here is an example taken from the documentation website https://maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html
<dependencies>
<dependency>
<groupId>sample.ProjectA</groupId>
<artifactId>Project-A</artifactId>
<version>1.0</version>
<scope>compile</scope>
<exclusions>
<exclusion> <!-- declare the exclusion here -->
<groupId>sample.ProjectB</groupId>
<artifactId>Project-B</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
The idea is to locate parent dependencie from where you are getting deps you don't want and add an exclusion tag.
If they are needed in runtime you can specify the scope to provided
<dependency>
<groupId>sample.ProjectA</groupId>
<artifactId>Project-A</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
That will tell maven to use the deps to compile but not no include them in the target package, and they will be provided in the production environment by the JVM executing the code.
Hope this helps

Related

Exlude package from maven dependency

I have error java: module com.example.learningfx reads package jfxtras.labs.util.event from both vworkflows.fx and jfxtras.labs and I think I need to exclude package from jfxtras.labs or vworkflow.fx. Jow can I not include some packages from dependency? Do I need to make this in pom.xml or module-info.java? I use maven and IntelliJ. I think there is already some questions like this but I don't find it
You can only include/exclude whole dependencies, not packages from dependencies.
See https://maven.apache.org/pom.html#Exclusions
You do not provide complete groupId:artifactId:version coordinates, so the example cannot be exact:
<dependencies>
<dependency>
<groupId>...</groupId>
<artifactId>vworkflows.fx</artifactId>
<version>...</version>
<exclusions>
<exclusion>
<groupId>org.jfxtras</groupId>
<artifactId>jfxtras.labs.util.event</artifactId>
</exclusion>
</exclusions>
</dependency>
...

How to override default version of library included by artifact in maven?

I have a spring batch dependency in my pom.xml declared as below:
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-core</artifactId>
<version>3.0.9.RELEASE</version>
</dependency>
There is one artifact xstream that is included by above with version 1.4.7 and it needs to be updated to 1.4.11.
It can be added as follow:
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.11</version>
</dependency>
What is the correct way for this?I am thinking of following approach:
Both above pieces of code will be there but do I need to use < exclusions > to specifically exclude xstream artifact old version from spring-batch-core or does maven takes care of this automatically?
Better way will be using <dependencyManagement/> tag. Dependency management will make sure the version will be maintained even if some other transitive dependency brings higher version of the dependency.
Usage:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.11</version>
</dependency>
</dependencies>
</dependencyManagement>
Note: dependencyManagement tag is used for defining the version and scope (if not in the default scope which is compile) of a dependency it does not add the dependencies in it to you project, you must define separate <dependencies/> section in your pom.xml for adding dependencies to your project.
In your case it will be like.
<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">
...
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.11</version>
</dependency>
</dependencies>
...
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-core</artifactId>
<version>3.0.9.RELEASE</version>
</dependency>
...
</dependencies>
...
</project>
In this case spring-batch-core is added as a direct dependency and if it has xstream as dependecny you project will use 1.4.11 version even spring-batch-core has a different version of xstream as dependency.
Ref: Dependency Management

How to replace a transitive dependency library in a maven project

I have a dependency library which is being pulled in by a library which I have included in my POM.
This transitive dependency has been flagged as an operational risk by a security scan and asked to upgrade it to the latest version. I need to understand how that can be done?
I tried excluding the library from the POM and then declare a direct dependency on the latest version of the same transitive dependency but I get classNotFound exception.
Code elaboration:-
Direct dependency -> hibernate-core
Transitive dependency which as been flagged -> ANTLR 2.7.7
The failed fix that I have tried ->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.4.18.Final</version>
<exclusions>
<exclusion>
<groupId>antlr</groupId>
<artifactId>antlr</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>antlr</groupId>
<artifactId>antlr</artifactId>
<version>3.0ea8</version>
</dependency>
Please suggest a generic approach to replacing a transitive library.
There is no need for exclusions. You can override transitive dependencies in the <dependencyManagement> like:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>antlr</groupId>
<artifactId>antlr</artifactId>
<version>3.0ea8</version>
</dependency>
...
This will override all transitive occurrences of the library with the version you specify.
But this does not protect you from classNotFound exceptions. If you update a library, class names may have changed and your program might break.

maven: how to disable certain dependencies?

Well, I'm not talking about the well-known commons-logging problem, I know I can disable it by setting the 99.0-does-not-exist version.
My problems is, some packages are contained in different dependencies, say, aspectjlib is contained both in org.aspectj:aspectjlib and aspectj:aspectjlib. In some cases, transitive dependencies may introduce the two jars at the same time, while of different versions, e.g., org.aspectj:aspectjlib:1.7.3, aspectj:aspectjlib:1.6.1. And mis-loading aspectj:aspectjlib:1.6.1 accidentally is not my intention. So is there a way like commons-logging that I can disable aspectj:aspectjlib completely?
I tried the same trick using 99.0-does-not-exist, only to find an error from maven:
[ERROR] Failed to execute goal on project XXX: Could not resolve
dependencies for project XXX:jar:1.0.0-SNAPSHOT: The following
artifacts could not be resolved:
aspectj:aspectjlib:jar:99.0-does-not-exist,
aspectj:aspectjrt:jar:99.0-does-not-exist,
aspectj:aspectjweaver:jar:99.0-does-not-exist: Could not find artifact
aspectj:aspectjlib:jar:99.0-does-not-exist in tbmirror
(http://mvnrepo.taobao.ali.com/mvn/repository) -> [Help 1]
Well, although some repositories do provide 99.0-does-not-exist for logging system dependencies like log4j, slf4j-log4j, commons-logging, etc., this is not a universal solution.
I find a solution to do this: use 'provided' scope.
To clarify, in my example above, I have two conflicting dependencies: org.aspectj:aspectjlib:1.7.3, aspectj:aspectjlib:1.6.1, I want to disable aspectj:aspectjlib:1.6.1, I only need to put this in top-level pom:
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjlib</artifactId>
<version>1.6.1</version>
<scope>provided</scope>
</dependency>
in this way, aspectj:aspectjlib:1.6.1 will never appear in the final built lib.
You can use Maven's dependency exclusions to eliminate the version you don't want. Using your example:
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>includes-new-aspectj</groupId>
</dependency>
<dependency>
<groupId>com.example</groupId>
<artifactId>includes-old-aspectj</groupId>
<exclusions>
<exclusion>
<groupId>org.aspectj<groupId>
<artifactId>aspectjlib</artifactId>
<exclusion>
</exclusions>
</dependency>
</dependencies>
Alternatively, you can simply pin the version you desire using dependency management:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjlib</artifactId>
<version>1.7.3</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>includes-new-aspectj</groupId>
</dependency>
<dependency>
<groupId>com.example</groupId>
<artifactId>includes-old-aspectj</groupId>
</dependency>
</dependencies>
If you are not sure which dependencies include which versions, you can use this to discover that info:
mvn dependency:tree -Dincludes='org.aspectj:aspectjlib'
There is no 99.0 version for aspectj:aspectjlib, your project is configured to use wrong version, check for 99.0 in your pom.xml

How to mark main dependency as "compile" and sub-dependencies as "provide"?

One of my Android projects requires oauth.signpost artifact, so I have something like this in my pom.xml:
...
<dependency>
<groupId>oauth.signpost</groupId>
<artifactId>signpost-core</artifactId>
<version>1.2.1.1</version>
<scope>compile</scope>
</dependency>
...
The problem is that this depends on more artifacts, for instance: org.apache.httpcomponents:httpclient:4.0.1. The problem is that Android already provides that package and thus it makes my building process crash.
So, what I usually do is going to the dependencies configuration on IntelliJ and manually mark those redundant artifacts as provide instead of compile:
This process is annoying, not only because I have a lot of Maven dependencies, but also because sometimes IntelliJ forgets what dependencies were market as provide and it will mark'em all as compile.
The only solution I see is to specify, in the pom.xml, which dependencies are provide and which are compile. But there are a lot of them, so it would take some time (also, I'd have to manually check which version is needed for each artifact, etc.).
So, is it a way to tell Maven to mark sub-dependencies as provide, while keeping main dependencies as compile?
There is the option to add dependency exclusions.
Consider the following:
Let's assume you have two projects - bar and foo.
Bar dependends on log4j.
You would like foo to depend on a different version of log4j.
This would be your pom.xml in the foo module:
<project>
<groupId>kung.fu</groupId>
<artifactId>foo</artifactId>
...
<dependencies>
<dependency>
<groupId>kung.fu</groupId>
<artifactId>bar</artifactId>
<version>1.0</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.3</version>
</dependency>
</dependencies>
</project>

Categories

Resources