Excluded maven dependency still showing up - maven

So this API I'm building uses a dependency (A) that uses javax-validation:validation-api:1.1.0-Final.
Instead I want to make use of the 2.0.1-Final so in the dependency of (A) I added an exclusion.
Next I added the dependency of the version I do want to use...
After that I ran a 'mvn clean install', running mvn dependency:tree shows me I use the correct version of the validation-api in the API.
Problem is however that if I run a mvn dependency:tree in the service where I added my fresh API, the old validation-api still shows up!
I'm sure it already uses the new API because when I go browsing through the dependency sources I see it's already the new pom...
I really don't know what is wrong here...
API POM:
<dependency>
<groupId>com.xxx.test</groupId>
<artifactId>xxx-test</artifactId>
<version>2.0.4</version>
<exclusions>
<exclusion>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
API tree:
[INFO] com.xxx-api:xxx-api:jar:1.0.0-SNAPSHOT
[INFO] +- javax.validation:validation-api:jar:2.0.1.Final:compile
Service tree:
[INFO] +- com.xxx-api:xxx-api:jar:1.0.0-SNAPSHOT:compile
[INFO] | +- com.xxx.test:xxx-test:jar:2.0.4:compile
[INFO] | | +- ....
[INFO] | \- javax.validation:validation-api:jar:1.1.0.Final:compile

I know this might have solved OP's answer - but running
mvn clean install
showed me an updated dependency tree after excluding dependencies.

Related

Why do we need to add additional dependency for log42j in Spring Boot?

Why do we need to add an additional dependency for log42j since all the transitive dependencies are already present in spring-boot-starter-web?
From whatever tutorials I could read up on the internet everybody mentioned to add the dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
They also mentioned excluding spring-boot-starter-logging from spring-boot-starter-web.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
But why do we need to do this? I see all the dependencies in spring-boot-starter-log4j2 are already there in spring-boot-starter-logging.
The default dependency for logging is not log4j but logback. If you remove the dependency, ideally speaking you should not be able to use the log4j imports in your project. Can you check this once?
The log4j dependency is only declared in the dependency-management, but you would need to include the dependency to be able to use this declared dependency.
Reference: https://docs.spring.io/spring-boot/docs/2.0.x/reference/html/howto-logging.html
Spring by default logging is backed by Logback which is powered by Apache. So if you want to provide logging in the system you can do so using logback. Now if you are asking the question for exclusion for logback it is just for letting spring know that you are using the different logging framework.
Logging
When spring-boot-starter-logging is included:
org.springframework.boot:spring-boot-starter-logging:jar:2.4.2:compile
+- ch.qos.logback:logback-classic:jar:1.2.3:compile
| +- ch.qos.logback:logback-core:jar:1.2.3:compile
| \- org.slf4j:slf4j-api:jar:1.7.30:compile
+- org.apache.logging.log4j:log4j-to-slf4j:jar:2.13.3:compile
| \- org.apache.logging.log4j:log4j-api:jar:2.13.3:compile
\- org.slf4j:jul-to-slf4j:jar:1.7.30:compile
, then log4j-core does not exist.
On the other hand, when spring-boot-starter-log4j2 is included:
org.springframework.boot:spring-boot-starter-log4j2:jar:2.4.2:compile
+- org.apache.logging.log4j:log4j-slf4j-impl:jar:2.13.3:compile
| +- org.slf4j:slf4j-api:jar:1.7.30:compile
| \- org.apache.logging.log4j:log4j-api:jar:2.13.3:compile
+- org.apache.logging.log4j:log4j-core:jar:2.13.3:compile
+- org.apache.logging.log4j:log4j-jul:jar:2.13.3:compile
\- org.slf4j:jul-to-slf4j:jar:1.7.30:compile
, then it exists.

Duplicate JARs are getting copied though excluded in pom.xml

I am trying to add jdom 2.0.2 dependency in one of my project.In order to do that I added following entry in pom.xml
<dependency>
<groupId>org.jdom</groupId>
<artifactId>jdom</artifactId>
<version>2.0.2</version>
</dependency>
But after building the project I found that both jdom 1.0 and jdom 2.0.2 got copied. Then I ran mvn dependency:tree
command which shows that jdom 1.0 jars are coming from jaxen 1.1 dependency through transitive dependency.
To exclude that dependency I added an exclusions in jaxen dependency
<dependency>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
<version>1.1</version>
<exclusions>
<exclusion>
<groupId>org.jdom</groupId>
<artifactId>jdom</artifactId>
</exclusion>
</exclusions>
</dependency>
But still I am facing same issue. Both(jdom 1.0 and 2.0.2) jars are getting copied. mvn dependency:tree also is showing the same result
INFO] +- jaxen:jaxen:jar:1.1:compile
INFO] | +- dom4j:dom4j:jar:1.6.1:compile
INFO] | +- jdom:jdom:jar:1.0:compile
Could you please help on this issue?
Thanks
Look carefully at the dependency output:
INFO] +- jaxen:jaxen:jar:1.1:compile
INFO] | +- dom4j:dom4j:jar:1.6.1:compile
INFO] | +- jdom:jdom:jar:1.0:compile
The group ID for the jdom dependency is just jdom, not org.jdom. Fix the exclusion and that should do it.
<exclusion>
<groupId>jdom</groupId>
<artifactId>jdom</artifactId>
</exclusion>

Understanding Maven Dependency tree output

I am trying to compile a Spring application in which the ApplicationConfig file has #EnableAspectJAutoProxy anotation I am facing this error when trying to run the project:
Failed to instantiate [org.springframework.aop.aspectj.annotation.
AnnotationAwareAspectJAutoProxyCreator]:
Constructor threw exception; nested exception is
java.lang.NoClassDefFoundError: org/aspectj/lang/annotation/Around
I have to say when I remove the above annotation the project is running successfully.
Having read on Internet I thought maybe it's because of incompatible versions for of libraries and jar files.
When I run mvn dependency:tree the output is as below:
[INFO] task-segment: [dependency:tree]
[INFO] ------------------------------------------------------------------------
[INFO] [dependency:tree {execution: default-cli}]
[INFO] groupId:myProject:jar:1.0-SNAPSHOT
[INFO] +- junit:junit:jar:4.11:compile
[INFO] | \- org.hamcrest:hamcrest-core:jar:1.3:compile
[INFO] +- org.springframework:spring-webmvc:jar:4.3.0.RELEASE:compile
[INFO] | +- org.springframework:spring-aop:jar:4.2.6.RELEASE:compile (version m
anaged from 4.3.0.RELEASE)
[INFO] | | \- aopalliance:aopalliance:jar:1.0:compile
[INFO] | +- org.springframework:spring-beans:jar:4.2.6.RELEASE:compile
[INFO] | +- org.springframework:spring-context:jar:4.2.6.RELEASE:compile (versi
on managed from 4.3.0.RELEASE)
[INFO] | +- org.springframework:spring-core:jar:4.2.6.RELEASE:compile
[INFO] | +- org.springframework:spring-expression:jar:4.2.6.RELEASE:compile
[INFO] | \- org.springframework:spring-web:jar:4.2.6.RELEASE:compile (version m
anaged from 4.3.0.RELEASE)
[INFO] +- org.aspectj:aspectjweaver:jar:1.8.9:compile
[INFO] +- javax.servlet:javax.servlet-api:jar:3.1.0:compile
[INFO] \- org.aspectj:aspectjrt:jar:1.8.9:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3 seconds
and this is the content of the pom.xml file :
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.9</version>
</dependency>
</dependencies>
Question: I don't understand this output is saying that everything is fine or there might be some incompatibility in my project, and if there are how to solve them?
If you have worked on maven in your projects for dependency management, then you must have faced one problem at least once or may be more than that. And the problem is version mismatch. It generally happens when you got some dependencies which bring it’s related dependencies together with certain version. And if you have included those dependencies with different version numbers already, they can face undesired results in compile time as well as runtime also.
Ideally to avoid above issue you need to explicitly exclude the related dependency, but it is quite possible that you can forget to do so.
To solve version mismatch issue, you can use the concept of a “bill of materials” (BOM) dependency. A BOM dependency keep track of version numbers and ensure that all dependencies (both direct and transitive) are at the same version.
How to add BOM [Bill Of Materials] dependency
Maven provides a tag dependencyManagement for this purpose. You need to add the bom information in this tag as follows. I am taking the example of Spring bom file.
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>4.3.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
An added benefit of using the BOM is that you no longer need to specify the version attribute when depending on Spring Framework artifacts. So it will work perfectly fine.
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependencies>
Doing like above will resolve all version comparability issues and application works fine as we are not going to use unmatched versions

ERROR SLF4J: Class path contains multiple SLF4J bindings jenkins cobertura maven

I'm with this error on third day already and I can't resolved. There is something that I can't grasp on and no matter what I do the error still persists.
I'm reading a book called "Jenkins a definitive guide" (http://www.wakaleo.com/books/jenkins-the-definitive-guide) and I'm stuck on chapter two. Basically is a example of how to use Jenkins with Javadoc, JUnit and Cobertura plugin for Jenkins. Everything works until I get to Cobertura plugin part, where I get next error:
[ERROR] SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/C:/Windows/System32/config/systemprofile/.m2/repository/ch/qos/logback/logback-classic/1.0.13/logback-classic-1.0.13.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/C:/Windows/System32/config/systemprofile/.m2/repository/org/slf4j/slf4j-simple/1.6.1/slf4j-simple-1.6.1.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorStaticBinder]
I have seen other problems like mine and the conclusion I got is that I have either to include o exclude a dependency in my pom.xml file/s (this examples only uses pom files at this stage). My pom.xml file that has slf4j-simple looks like this:
<project>
......
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.1</version>
</dependency>
</dependencies>
</project>
and there is no explicit dependency to logback-classic hence I don't know in what dependency is being used. I tried to use dependency plugin for jenkins and I got this result:
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) # gameoflife-web ---
[INFO] com.wakaleo.gameoflife:gameoflife-web:war:1.0-SNAPSHOT
[INFO] +- com.wakaleo.gameoflife:gameoflife-core:jar:1.0-SNAPSHOT:compile
[INFO] +- org.springframework:spring-webmvc:jar:3.0.2.RELEASE:compile
[INFO] | +- org.springframework:spring-asm:jar:3.0.2.RELEASE:compile
[INFO] | +- org.springframework:spring-beans:jar:3.0.2.RELEASE:compile
[INFO] | +- org.springframework:spring-context:jar:3.0.2.RELEASE:compile
[INFO] | | \- org.springframework:spring-aop:jar:3.0.2.RELEASE:compile
[INFO] | +- org.springframework:spring-context-support:jar:3.0.2.RELEASE:compile
[INFO] | \- org.springframework:spring-expression:jar:3.0.2.RELEASE:compile
[INFO] +- org.springframework:spring-core:jar:3.0.2.RELEASE:compile
[INFO] | \- commons-logging:commons-logging:jar:1.1.1:compile
[INFO] +- org.springframework:spring-web:jar:3.0.2.RELEASE:compile
[INFO] | \- aopalliance:aopalliance:jar:1.0:compile
[INFO] +- javax.servlet:jstl:jar:1.2:compile
[INFO] +- javax.servlet:servlet-api:jar:2.5:provided
[INFO] +- org.mockito:mockito-all:jar:1.8.5:test
[INFO] +- org.easytesting:fest-assert:jar:1.4:compile
[INFO] | \- org.easytesting:fest-util:jar:1.1.6:compile
[INFO] +- org.slf4j:slf4j-simple:jar:1.6.1:compile
[INFO] +- org.slf4j:slf4j-api:jar:1.6.1:compile
[INFO] +- junit:junit:jar:4.11:test
[INFO] | \- org.hamcrest:hamcrest-core:jar:1.3:test
[INFO] \- org.hamcrest:hamcrest-all:jar:1.1:test
Maybe I'm blind, but I still can't see who uses logback-classic (by the way I'm not sure what values are correct for and for logback-classic).
I tried to remove the slf4j dependency's and I error is gone, but I don't get any cobertura reports. I tried to exclude logback-classic with
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.6.1</version>
<exclusions>
<exclusion>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.1</version>
<exclusions>
<exclusion>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</exclusion>
</exclusions>
</dependency>
and the error persists.
I don't know what to do anymore, please help!
The good news is that even if SLF4J is reporting an error, it's actually warning you that SLF4J will be bound to ch.qos.logback.classic.util.ContextSelectorStaticBinder since there are two bindings available on the class path. SLF4J will pick the first one available on the class path. Your application should continue to work just fine albeit logging with logback.
I can't tell you why logback-classic.jar is on the class path but I suggest you investigate the "System profile" mentioned in the class path.
You are trying to exclude the logback-classic from the slf dependency itself. The issue is that as mentioned here, you were using more than one binding in your class path. Actual way is to keep exclusion for logback-classic, in the dependency which uses it and not in your slf4j dependency. Unfortunately, I am not sure which of your jars, are having a reference to slf4j which is causing the issue. One workaround is, use Ctrl+Sft+T to see the existence of the StaticLoggerBinder class, in different jars, and place the logback-classic exclusion in that. Other work around is, you can try keeping exclusion, as trial and error. These are just work arounds, but the concept is same. We need to find other dependency which has reference to logback-classic in your classpath
Please follow the below
Steps
Step1: Identify the classic logback using the mvn dependency:tree
Step2: Add the below exclusion in pom.xml
<exclusions>
<exclusion>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-to-slf4j</artifactId>
</exclusion>
</exclusions>
Step3: Test the application
Credits go to the https://java2blog.com/fixed-slf4j-warning-class-path-contains-multiple-slf4j-bindings/

Maven Transitive Dependency Issue with CXF and ACEGI

I have a pom file which originally had the following dependency:
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>2.5.2</version>
<scope>runtime</scope>
</dependency>
According to mvn dependency:tree, the above dependency has the following transitive dependencies:
[INFO] \- org.apache.cxf:cxf-rt-transports-http:jar:2.5.2:runtime
[INFO] +- org.apache.cxf:cxf-rt-transports-common:jar:2.5.2:runtime
[INFO] \- org.springframework:spring-web:jar:3.0.6.RELEASE:runtime
[INFO] +- aopalliance:aopalliance:jar:1.0:runtime
[INFO] +- org.springframework:spring-beans:jar:3.0.6.RELEASE:runtime
[INFO] +- org.springframework:spring-context:jar:3.0.6.RELEASE:runtime
[INFO] | +- org.springframework:spring-aop:jar:3.0.6.RELEASE:runtime
[INFO] | +- org.springframework:spring-expression:jar:3.0.6.RELEASE:runtime
[INFO] | \- org.springframework:spring-asm:jar:3.0.6.RELEASE:runtime
[INFO] \- org.springframework:spring-core:jar:3.0.6.RELEASE:runtime
I then add the following dependency to my pom file:
<dependency>
<groupId>org.acegisecurity</groupId>
<artifactId>acegi-security-cas</artifactId>
<version>1.0.3</version>
</dependency>
When I run a mvn package, it erases the spring dependencies from cxf (i.e. - spring-beans-3.0.6.RELEASE.jar, etc...) and replaces them with the 1.0 versions from the acegi plugin. If I run a dependency:tree, it now says the following:
[INFO] \- org.apache.cxf:cxf-rt-transports-http:jar:2.5.2:runtime
[INFO] \- org.apache.cxf:cxf-rt-transports-common:jar:2.5.2:runtime
How do I force maven to use the newer versions from cxf instead of the older versions from the acegi dependency? I tried adding an exclusion to the acegi dependency:
<dependency>
<groupId>org.acegisecurity</groupId>
<artifactId>acegi-security-cas</artifactId>
<version>1.0.3</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
</exclusion>
</exclusions>
</dependency>
However, when I run mvn package, I now get no spring-aop jar (it doesn't include the version needed by cxf or the version included with the acegi security).
I know that I could manually write out each of the transitive dependencies from cxf. However, is there any better approach that I could use to get maven to use the spring dependencies from cxf and not from the old acegi?
Thanks.

Resources