I'm getting the following error. It seems there are multiple logging frameworks bound to slf4j. Not sure how to resolve this. Any help is greatly appreciated.
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/C:/Users/admin/.m2/repository/org/slf4j/slf4j-log4j12/1.6.4/slf4j-log4j12-1.6.4.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/C:/Users/admin/.m2/repository/org/slf4j/slf4j-log4j12/1.6.1/slf4j-log4j12-1.6.1.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
Resolved by adding the following exclusion in the dependencies (of pom.xml) that caused conflict.
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
Gradle version;
configurations.all {
exclude module: 'slf4j-log4j12'
}
The error probably gives more information like this (although your jar names could be different)
SLF4J: Found binding in
[jar:file:/D:/Java/repository/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in
[jar:file:/D:/Java/repository/org/apache/logging/log4j/log4j-slf4j-impl/2.8.2/log4j-slf4j-impl-2.8.2.jar!/org/slf4j/impl/StaticLoggerBinder.class]
Noticed that the conflict comes from two jars, named logback-classic-1.2.3 and log4j-slf4j-impl-2.8.2.jar.
Run mvn dependency:tree in this project pom.xml parent folder, giving:
Now choose the one you want to ignore (could consume a delicate endeavor I need more help on this)
I decided not to use the one imported from spring-boot-starter-data-jpa (the top dependency) through spring-boot-starter and through spring-boot-starter-logging, pom becomes:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
in above pom spring-boot-starter-data-jpa would use the spring-boot-starter configured in the same file, which excludes logging (it contains logback)
Sbt version:
Append exclude("org.slf4j", "slf4j-log4j12") to the dependency that transitively includes slf4j-log4j12. For example, when using Spark with Log4j 2.6:
libraryDependencies ++= Seq(
// One SLF4J implementation (log4j-slf4j-impl) is here:
"org.apache.logging.log4j" % "log4j-api" % "2.6.1",
"org.apache.logging.log4j" % "log4j-core" % "2.6.1",
"org.apache.logging.log4j" % "log4j-slf4j-impl" % "2.6.1",
// The other implementation (slf4j-log4j12) would be transitively
// included by Spark. Prevent that with exclude().
"org.apache.spark" %% "spark-core" % "1.5.1" exclude("org.slf4j", "slf4j-log4j12")
)
1.Finding the conflicting jar
If it's not possible to identify the dependency from the warning, then you can use the following command to identify the conflicting jar
mvn dependency: tree
This will display the dependency tree for the project and dependencies who have pulled in another binding with the slf4j-log4j12 JAR.
Resolution
Now that we know the offending dependency, all that we need to do is exclude the slf4j-log4j12 JAR from that dependency.
Ex - if spring-security dependency has also pulled in another binding with the slf4j-log4j12 JAR, Then we need to exclude the slf4j-log4j12 JAR from the spring-security dependency.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
Note - In some cases multiple dependencies have pulled in binding with the slf4j-log4j12 JAR and you don't need to add exclude for each and every dependency that has pulled in.
You just have to do that add exclude dependency with the dependency which has been placed at first.
Ex -
<dependencies>
<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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
</dependencies>
If you work with gradle then add following code to your build.gradle file to exclude SLF4J binding from all the modules
configurations.all {
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
}
I just ignored/removed that jar file.
<!--<dependency>-->
<!--<groupId>org.springframework.boot</groupId>-->
<!--<artifactId>spring-boot-starter-log4j2</artifactId>-->
<!--</dependency>-->
I solved by delete this:spring-boot-starter-log4j2
Just use only required dependency, not all :))). For me, for normal work of logging process you need this dependency exclude others from pom.xml
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.8</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.1.8</version>
</dependency>
This is issue because of StaticLoggerBinder.class class belongs to two different jars. this class references from logback-classic-1.2.3.jar and same class also referenced from log4j-slf4j-impl-2.10.0.jar. both of jar in classpath. Hence there is conflict between them.
This is reason of log file is not generation even though log4j2.xml file in classpath [src/main/resource].
We have so select one of jar, I recommend use log4j-slf4j-impl-2.10.0.jar file and exclude logback-classic-1.2.3.jar file.
Solution: open pom file and view the dependency Hierarchy [eclipse] or run
mvn dependency:tree command to find out the dependency tree and source of dependency that download the dependency. find the conflicting dependency and exclude them. For Springboot application try this.
<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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
This is working fine for me after struggling a lots.
...
org.codehaus.mojo
cobertura-maven-plugin
2.7
test
ch.qos.logback
logback-classic
tools
com.sun
...
## I fixed with this
...
org.codehaus.mojo
cobertura-maven-plugin
2.7
test
ch.qos.logback
logback-classic
tools
com.sun
...
For me, it turned out to be an Eclipse/Maven issue after switch from log4j to logback. Take a look into your .classpath file and search for the string "log4j".
In my case I had the following there:
<classpathentry kind="var" path="M2_REPO/org/slf4j/slf4j-log4j12/1.7.1/slf4j-log4j12-1.7.1.jar"/>
<classpathentry kind="var" path="M2_REPO/log4j/log4j/1.2.17/log4j-1.2.17.jar" />
Removing those entries from the file (or you could regenerate it) fixed the issue.
For me the answer was to force a Maven rebuild. In Eclipse:
Right click on project-> Maven -> Disable Maven nature
Right click on project-> Spring Tools > Update Maven Dependencies
Right click on project-> Configure > Convert Maven Project
I solved this by going to Project Structure from my Intellij project.
I deleted the file named: Maven: org.apache.logging.log4j:log4j-to-slf4j-impl:2.14.1
This file is not shown in this picture. You may see two libraries mentioned as log4j-to-slf4j. Delete one and you are good to go.
For all those looking for the solution for spring-boot-type dependencies, the magic incantation for Gradle is this:
configurations.all {
exclude group: 'ch.qos.logback', module: 'logback-classic'
}
in your build.gradle at the top level (not inside the dependencies block).
All other solutions found in the interwebs (including the one here suggesting to exclude the slf4j module) did not work for me.
This is what I have in my build.gradle (snippet):
// Removes the annoying warning about the multiple SLF4J implementations:
// SLF4J: Class path contains multiple SLF4J bindings.
configurations.all {
exclude group: 'ch.qos.logback', module: 'logback-classic'
}
dependencies {
annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"
implementation ('org.springframework.boot:spring-boot-starter-actuator')
implementation ('org.springframework.boot:spring-boot-starter-data-mongodb-reactive')
implementation ('org.springframework.boot:spring-boot-starter-webflux')
annotationProcessor "org.projectlombok:lombok:${lombokVersion}"
compileOnly "org.projectlombok:lombok:${lombokVersion}"
// Removes the annoying warning:
// warning: unknown enum constant When.MAYBE
// reason: class file for javax.annotation.meta.When not found
// See: https://stackoverflow.com/questions/29805622/could-not-find-or-load-main-class-org-gradle-wrapper-gradlewrappermain/31622432
implementation group: 'com.google.code.findbugs', name: 'jsr305', version: '3.0.2'
// other stuff...
YMMV
I had the same problem. In my pom.xml i had both
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.28</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
When i deleted the spring-boot-starter-web dependency, problem was solved.
I got this issue in a non-maven project, two depended jar each contained a slf4j. I solved
by remove one depended jar, compile the project(which of course getting failure) then add the removed one back.
In case these logs are the result of this fix:
https://stackoverflow.com/a/9919375/2894819
When one of your libraries actually use it. And your application doesn't need SL4J just replace implementation to runtimeOnly.
// contains dependency to sl4j-api
implementation("com.github.doyaaaaaken:kotlin-csv-jvm:1.2.0")
// add this to remove both warnings
runtimeOnly("org.slf4j:slf4j-nop:1.7.36")
In that case when you run your app the actual dependency will be included once by the library and won't be included to the bundle of your application.jar itself.
In my case I had 2 sources of dependencies for log4 one in C:\Program Files\smcf.ear directory and the second from maven which caused the multiple binding for sl4j.
Deleting the smcf.ear directory solved the issue for me.
The combination of <scope>provided</scope> and <exclusions> didn't work for me.
I had to use this:
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<scope>system</scope>
<systemPath>${project.basedir}/empty.jar</systemPath>
</dependency>
Where empty.jar is a jar file with literally nothing in it.
Seems removing .m2 directory and :
mvn install -DskipTests -T 4 resolved this issue for me.
I'm getting a "Cannot create a secure XMLInputFactory" error when sending a request with SoapUI, i tried some of the stackoverflow mentioned solutions like adding woodstox and stax2-api, but the issue persists
from build.gradle:
compile 'org.codehaus.woodstox:woodstox-core-asl:4.4.1'
compile 'org.codehaus.woodstox:stax2-api:4.0.0'
compile 'org.apache.cxf:cxf-rt-frontend-jaxws:3.1.12'
compile 'org.apache.cxf:cxf-rt-ws-security:3.1.12'
compile 'org.apache.cxf:cxf-rt-transports-http:3.1.12'
it was working before with woodstox-core, but started to throw the error
compile 'com.fasterxml.woodstox:woodstox-core:5.0.3'
from previous solutions from version 3 CXF does not even require woodstox, i tried also without woodstox.
Could it be any other dependency updated like axis2?
What should be my next steps to find out? thanks
Note: using tomcat 8.5.19
So solution found, at SaxUtils.java as someone mentioned there is a
factory = XMLInputFactory.newInstance();
Where we can see from where it is loaded.
There was actually a conflict in axis2 so by excluding neethi
compile('org.apache.axis2:axis2-transport-http:1.5.1') {
exclude group: 'javax.servlet', module: 'servlet-api'
exclude module: 'XmlSchema'
exclude group: 'org.apache.neethi', module: 'neethi'
exclude group: 'org.codehaus.woodstox'
}
runtime ('org.apache.axis2:axis2-transport-local:1.5.1'){
exclude group: 'org.codehaus.woodstox', module: 'wstx-asl'
}
the conflict was gone.
I would like to confirm with 'dotmindlabs' on the issue with Axis2. I also used a few packages from Axis2 whilst implementing Apache CXF 3.2.1. I had the same problem "Cannot create a secure XMLInputFactory"
The issue was strictly to do with the additional libraries Axis2 Implements.
I have provided below the dependency (Maven) changes required to resolve this issue.
<!-- https://mvnrepository.com/artifact/org.apache.axis2/axis2-transport-http -->
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-transport-http</artifactId>
<version>1.6.2</version>
<exclusions>
<exclusion>
<groupId>org.apache.ws.commons.schema</groupId>
<artifactId>XmlSchema</artifactId>
</exclusion>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.neethi</groupId>
<artifactId>neethi</artifactId>
</exclusion>
<exclusion>
<groupId>org.codehaus.woodstox</groupId>
<artifactId>wstx-asl</artifactId>
</exclusion>
</exclusions>
</dependency>
I hope this helps people in the future who run into this problem.
I want to use the last version of the powermock library (1.6.5) through Maven. But My package cannot be compiled, since Maven finds dependency Convergence error. Below you can see that there are 2 different versions of org.objenesis:objenesis library in the same dependency:
Dependency convergence error for org.objenesis:objenesis:2.1 paths to
dependency are:
+-mypackage:v1-SNAPSHOT
+-org.powermock:powermock-api-mockito:1.6.5
+-org.mockito:mockito-core:1.10.19
+-org.objenesis:objenesis:2.1
and
+-mypackage:v1-SNAPSHOT
+-org.powermock:powermock-api-mockito:1.6.5
+-org.powermock:powermock-api-mockito-common:1.6.5
+-org.powermock:powermock-api-support:1.6.5
+-org.powermock:powermock-reflect:1.6.5
+-org.objenesis:objenesis:2.2
I tried to make an exclusion, but I cannot exclude only one version, I need to exclude all of them, which does not pass me, as I think.
Did you have the same problem? What can I do?
There two different version of objenesis, because two different libraries depends on two different version ofobjenesis`: PowerMock and Mockito. You have two options to resolve the issue:
Exclude org.objenesis:objenesis from PowerMock dependencies and add it manually to your pom.
Exclude mockito-core from PowerMock dependencies and add it as separated decency to your pom with excluding objenesis.
I followed the answer from Arthur, but only made an exclusion for objenesis to the powermock-module-junit dependency. After that the enforcer plugins was happy.
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.7.0</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.objenesis</groupId>
<artifactId>objenesis</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>1.7.0</version>
<scope>test</scope>
</dependency>
I'm having some problems with conflicting versions of some jars. I have a dependency on a library group-a:artifact-a:0.0.1 that has a dependency on group-b:artifact-b:0.0.1, but I don't want that group-b:artifact-b:0.0.1 to be included given that I know that at runtime there will be group-b:artifact-b:0.0.2.
How do I have to write the pom.xml file?
Is this one of the following correct? And what's the difference between these?
Solution 1:
Exclude group-b:artifact-b from group-a:artifact-a:0.0.1:
<dependencies>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-a</artifactId>
<version>0.0.1</version>
<exclusions>
<exclusion>
<groupId>group-b</groupId>
<artifactId>artifact-b</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
Solution 2:
Add group-b:artifact-b dependency as provided:
<dependencies>
<dependency>
<groupId>group-b</groupId>
<artifactId>artifact-b</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-a</artifactId>
<version>0.0.1</version>
</dependency>
</dependencies>
Solution 3:
Add group-b:artifact-b dependency as runtime:
<dependencies>
<dependency>
<groupId>group-b</groupId>
<artifactId>artifact-b</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-a</artifactId>
<version>0.0.1</version>
</dependency>
</dependencies>
Solution 4:
Add group-b:artifact-b dependency as provided or runtime and exclude it from group-a:artifact-a:0.0.1.
UPDATE:
Sorry for not being explicit, but yes #Tunaki's assumption is correct, the dependency group-b:artifact-b:0.0.2 is not required at compile time.
Option 5: Just declare the version explicitly in your POM.
Maven will overwrite the transitive dependencies if you explicitly declare them in the pom. You don't need to do any mucking about with provided or runtime scope.
According to the docs (emphasis mine):
Dependency mediation - this determines what version of a dependency will be used when multiple versions of an artifact are encountered. Currently, Maven 2.0 only supports using the "nearest definition" which means that it will use the version of the closest dependency to your project in the tree of dependencies. You can always guarantee a version by declaring it explicitly in your project's POM. Note that if two dependency versions are at the same depth in the dependency tree, until Maven 2.0.8 it was not defined which one would win, but since Maven 2.0.9 it's the order in the declaration that counts: the first declaration wins.
So your pom should just be:
<dependencies>
<dependency>
<groupId>group-b</groupId>
<artifactId>artifact-b</artifactId>
<version>0.0.2</version>
</dependency>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-a</artifactId>
<version>0.0.1</version>
</dependency>
</dependencies>
You should use solution 4. Let's go through each solution:
Solution 1
This is using the exclusions principle of Maven. Maven resolves dependencies transitively. But when you do not want a specific transitive dependency to be included in your classpath, you can exclude it using this mechanism.
The excluded dependency will not be used at compile-time or run-time.
But this is not what you want, since you know that your project requires group-b:artifact-b at run-time. In this scenario, the pom.xml does not declare it.
Solution 2
You are using the provided scope. provided in Maven means that this dependency is required at compile-time but should not be included in the final artifact. Typically, this dependency will be provided at run-time by a container, such as a web server.
As such, Maven will override the transitive dependency group-b:artifact-b:0.0.1 of group-a:artifact-a. In the final dependency tree, group-b:artifact-b:0.0.2 will be resolved as a provided dependency and will not be included in the final artifact (for example, if building a war, this library will not end up in WEB-INF/lib).
Solution 3
This time, you are using the runtime scope. This is much like Solution 2.
The difference is that in the final dependency tree, group-b:artifact-b:0.0.2 will be resolved as a run-time dependency and will be included in the final artifact (for example, if building a war, this library will end up in WEB-INF/lib).
Solution 4
This is the same as solution 2 and 3. The difference is that Maven will not override the dependency since you are explicitely excluding it from the list of transitive dependencies of artifact-a. But the result will be the same.
What is the correct solution?
This really depends on how your dependency will be present at run-rime. If it provided by a container, you should use Solution 4 with the provided scope. If not, you should use Solution 4 with the runtime scope.
I am suggesting this solution because:
You are explicitely excluding the unwanted dependency from artifact-a transitive dependency: this makes it more clear that that specific dependency should not be used in the project.
You are explicitely including the wanted dependency in the right scope and the right version. Again, this makes the pom.xml easier to read and to understand.
<dependencies>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-a</artifactId>
<version>0.0.1</version>
<exclusions>
<exclusion>
<groupId>group-b</groupId>
<artifactId>artifact-b</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>group-b</groupId>
<artifactId>artifact-b</artifactId>
<version>0.0.2</version>
<scope>provided</scope> <!-- or runtime, depending on your specific case -->
</dependency>
</dependencies>
I got Exception
java.lang.NoSuchFieldError: reportUnusedDeclaredThrownExceptionIncludeDocCommentReference outside eclipse in command line using maven.
The gwt libraries are declared at the top of list of dependencies and GWT 2.5.1 is being used.
How to solve this issue? Please help
Well, I figured out what is the problem.
In my pom.xml , I have this dependency
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports</artifactId>
<version>4.7.0</version>
The problem with this is that, jasper reports has a dependency on jdtcore
<dependency>
<artifactId>jdtcore</artifactId>
<groupId>eclipse</groupId>
<version>3.1.0</version>
</dependency>
jdtcore actually creates a conflict with the gwt compiler. To solve this problem, I need to add an exclusion in the jasper dependency like this
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports</artifactId>
<version>4.7.0</version>
<exclusions>
<exclusion>
<artifactId>jdtcore</artifactId>
<groupId>eclipse</groupId>
</exclusion>
</exclusions>
</dependency>
Now if still need the jdtcore library in the web app (normally to dynamically compile jasper reports) we can add the dependency with scope runtime like this
<dependency>
<artifactId>jdtcore</artifactId>
<groupId>eclipse</groupId>
<version>3.1.0</version>
<scope>runtime</scope>
</dependency>
Last note, if anybody gets the problem, then should look if any dependency in pom.xml has got a dependency on jdtcore, exclude it and include it as runtime
Hope this helps
For gradle exclude transitive dependency as follows in build.gradle:
dependencies {
compile('net.sf.jasperreports:jasperreports:3.7.4') {
//Exclude as it caused problems with GWT:
//http://stackoverflow.com/questions/17991063/java-lang-nosuchfielderror-reportunuseddeclaredthrownexceptionincludedoccomment
exclude group: 'eclipse', module: 'jdtcore'
}
}
Except after I made this change my jasper compilation fails. I am not sure yet how can I get Jasper compilation and GWT compilation to coexist in same project?