Maven dependency exclusion doesn't seem to work - maven

I have a Maven project depending on couple other Maven projects. I am using Spring 3.1.1 in my project and dependent projects have 3.0.6. I am trying to exclude Spring 3.0.6 when deploying since having both isn't possible. I have added an explicit exclusion in my POM for that but for some reason I still see old version of spring core jars in the WEB-INF/lib folder when I start the Tomcat server. Can someone point me out where I am going wrong. Here is my pom.xml:
<project>
....
<properties>
<org.springframework-version>3.1.1.RELEASE</org.springframework-version>
</properties>
<dependency>
<groupId>com.test.abc</groupId>
<artifactId>abc</artifactId>
<version>1.0</version>
<type>war</type>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
<exclusions>
<!-- Exclude Commons Logging in favor of SLF4j -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>3.0.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.ws</groupId>
<artifactId>spring-xml</artifactId>
<version>1.0-m2</version>
</dependency>
....
</project>

Your dependency type is war so there is no resolution happening here. Maven overlays the war contents over your project.
When the war is published to repository, the artifact will contain dependent libraries in WEB-INF lib folder. During overlay it does not treat lib folder any different from any static resource unless you tell it to exclude in different way.Check 'overlay' property here

In my case I thought I excluded the right dependency. With eclipse, on dependency hierarchy tab you can right click on it and click exclude artifact and it excluded the right dependency (they both had the same artifactId but different groupId)

Related

How can I download the third-party dependencies of spring-web.jar by maven?

The dependencies of Spring-web.jar do not contain third-party dependencies now. It only has other jar of spring framework. For example it depends on spring-core.jar. But the spring-web depends on some third-party jars. httpclient.jar is one of them. When I use maven to package my project that depends on spring-web, the httpclient.jar is not download automatically.
this is a segement of spring-web-5.2.15.RELEASE.pom.
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.2.15.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.2.15.RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
I read the pom of spring-web in early version. I find that the denpendencies include httpclient.jar. But it is disappear in new version now. this is a segment of spring-web-5.1.8.RELEASE.pom.
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.9</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
<optional>true</optional>
</dependency>
How can I download the dependencies?

maven pom.xml exclusion for transitive and normal dependancy

i tried adding maven dependency directly, say spring context 3.0.7.release
and tried adding spring-context 3.2.8.release(this has also spring context as transitive depedency), how to exclude spring context 3.0.7. is it to comment or to remove or can we use exclusion here?
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring-version} </version>
<!-- <exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
</exclusion>
</exclusions> -->
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>3.0.7.RELEASE</version>
</dependency>
</dependencies>
No need for an exclusion here, the version of spring-expression you have in your own POM overwrites the other version, and Maven takes care that only one version is used.

Spring BOM, commons-logging, Log4j2 and Maven dependency management

I'm building a parent POM for several modules. They are using Spring and Log4j2, so I want to define relevant configuration in section of parent POM and make use of new Spring BOM feature to avoid a mess with versions of Spring components.
According to documentation, this is the correct use of Spring BOM:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>4.2.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
.......
</dependencyManagement>
Now, I need to exclude dependency on commons-logging from spring-core. This is the right way to do it, according to Spring docs:
<dependencyManagement>
.......
<!-- Remove JCL from Spring deps -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.2.0.RELEASE</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Add Log4j2 with JCL bridge -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j2.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j2.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-jcl</artifactId>
<version>${log4j2.version}</version>
</dependency>
.......
</dependencyManagement>
Removing version number from the definition of spring-core dependency causes missing spring-core version error during compilation phase ('dependencies.dependency.version' for org.springframework:spring-core:jar is missing). Effectively, it requires me to re-specify Spring version number - something that Spring BOM was supposed to solve.
Do you know any way to make this work based on BOM version only?
Why don't you put the exclusion directly into the bom declaration:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>${spring.version}</version>
<type>pom</type>
<scope>import</scope>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</dependencyManagement>
Or you could add commons-logging to dependencyManagement as well, if you want to directly control its version. This is what I did in a recent project:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>${spring.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>${commons-logging.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
The log4j jcl bridge does not replace the commons-logging jar. Leave it in. It just creates a binding between commons logging and log4j2.

What are the jars needed for only Spring-MVC?

I need to run the Spring-MVC in my scratch project. At the same time i have minimum memory area to store all the jar files. So any body recommend me only need for the Spring-MVC not any other jar files. Thanks in Advance.
according to maven, spring-webmvc 3.1.2 need following jar:
aopalliance-1.0.jar
commons-logging-1.1.1.jar
spring-webmvc-3.1.2.RELEASE.jar
spring-asm-3.1.2.RELEASE.jar
spring-beans-3.1.2.RELEASE.jar
spring-core-3.1.2.RELEASE.jar
spring-context-3.1.2.RELEASE.jar
spring-aop-3.1.2.RELEASE.jar
spring-expression-3.1.2.RELEASE.jar
spring-context-support-3.1.2.RELEASE.jar
spring-web-3.1.2.RELEASE.jar
things provided by servlet container (f.e. servlet-api) are left out.
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>3.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>3.1.0.RELEASE</version>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>3.1.0.RELEASE</version>
</dependency>

How to exclude maven dependencies?

I have a question about exclusion of maven dependencies. Consider the following
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>${spring-security.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>3.1.0.RELEASE</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>3.1.0.RELEASE</version>
</dependency>
<dependency>
I am trying to achieve a transition from Spring 3.0.6 to 3.1.0 . Spring security 3.1.0 had a dependency on spring-security-web version 3.0.6 which in turn had a dependency on spring-web 3.0.6. I need to bring it all to 3.1.0. So I exclude spring-security-web from Spring security, have a separate dependency for spring-security-web 3.1.0 which in turn excludes the spring-web 3.0.6 version and I provide a separate spring-web 3.1.0 version. This work but I feel there would be a much easier approach. I tried putting an exclusion for spring web under Spring security but it did not work.
You can utilize the dependency management mechanism.
If you create entries in the <dependencyManagement> section of your pom for spring-security-web and spring-web with the desired 3.1.0 version set the managed version of the artifact will override those specified in the transitive dependency tree.
I'm not sure if that really saves you any code, but it is a cleaner solution IMO.
Global exclusions look like they're being worked on, but until then...
From the Sonatype maven reference (bottom of the page):
Dependency management in a top-level POM is different from just
defining a dependency on a widely shared parent POM. For starters, all
dependencies are inherited. If mysql-connector-java were listed as a
dependency of the top-level parent project, every single project in
the hierarchy would have a reference to this dependency. Instead of
adding in unnecessary dependencies, using dependencyManagement allows
you to consolidate and centralize the management of dependency
versions without adding dependencies which are inherited by all
children. In other words, the dependencyManagement element is
equivalent to an environment variable which allows you to declare a
dependency anywhere below a project without specifying a version
number.
As an example:
<dependencies>
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>3.0.5.RELEASE</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</dependencyManagement>
It doesn't make the code less verbose overall, but it does make it less verbose where it counts. If you still want it less verbose you can follow these tips also from the Sonatype reference.

Resources