Duplicate JARs are getting copied though excluded in pom.xml - maven

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>

Related

Excluded maven dependency still showing up

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.

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/

Using Spring 4.0 with spring-data-jpa

I am using Spring 4.0 in my JavaEE application, and I tried to use the Spring-data-jpa.
However when I add the Spring-data-jpa dependency, I found that the Spring-data-jpa will depend on Spring-3.x.
Then I wonder this will cause any problem? Since my application will have Spring-4.x with Spring-3.x.
Anyone have the same experience?
Update:
I am using Spring-data-jpg-1.4.3:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.4.3.RELEASE</version>
</dependency>
But when I run mvn dependency:tree I got this:
+- org.springframework:spring-context:jar:4.0.0.RELEASE:compile
| +- org.springframework:spring-beans:jar:4.0.0.RELEASE:compile
| +- org.springframework:spring-core:jar:4.0.0.RELEASE:compile
| | \- commons-logging:commons-logging:jar:1.1.1:compile
| \- org.springframework:spring-expression:jar:4.0.0.RELEASE:compile
+- org.springframework:spring-aop:jar:4.0.0.RELEASE:compile
| \- aopalliance:aopalliance:jar:1.0:compile
+- org.springframework.data:spring-data-jpa:jar:1.4.3.RELEASE:compile
| +- org.springframework.data:spring-data-commons:jar:1.6.3.RELEASE:compile
| +- org.springframework:spring-orm:jar:3.1.4.RELEASE:compile
| | \- org.springframework:spring-jdbc:jar:3.1.4.RELEASE:compile
| +- org.springframework:spring-tx:jar:3.1.4.RELEASE:compile
| +- org.aspectj:aspectjrt:jar:1.7.2:compile
| +- org.slf4j:slf4j-api:jar:1.7.1:compile
| \- org.slf4j:jcl-over-slf4j:jar:1.7.1:runtime
+- org.aspectj:aspectjweaver:jar:1.7.4:compile
+- org.springframework:spring-test:jar:4.0.0.RELEASE:test
It seems that the spring 4.0.. is mixed with spring 3.1.4..
This is an error in the spring-data-jpa 1.4.3.RELEASE pom denepdency.
What actually happens is that it loads spring dependencies that exist in this maven pom instead of the ones you want to import.
The short answer is add this as a parent to your maven project:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.0.0.RC5</version>
</parent>
so that it can inherit the correct dependencies.
Another way to solve this is to use the <exclusions> tag to exclude them and then import the correct dependecies but this takes more time and is not as clean. If you don't want to add spring-boot-start-parent though, then this is how to solve this error.
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>1.4.1.RELEASE</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
<exclusion>
...
</exclusion>
</exclusions>
</dependency>
For more info see here

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