Related
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 have a Java library built using Gradle 5.6 with some transitive dependencies suppressed
api('org.springframework.boot:spring-boot-starter-web') {
exclude module: 'spring-boot-starter-logging'
exclude module: 'spring-boot-starter-tomcat'
}
When I publish it to Maven repo I get a corresponding section of POM.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<scope>compile</scope>
<exclusions>
<exclusion>
<artifactId>spring-boot-starter-tomcat</artifactId>
<groupId>*</groupId>
</exclusion>
<exclusion>
<artifactId>spring-boot-starter-logging</artifactId>
<groupId>*</groupId>
</exclusion>
</exclusions>
</dependency>
...
</dependencies>
But when I add my library as a dependency also using Gradle 5.6
dependencies {
implementation 'my.group:my.lib:1.0.0'
}
I see the excluded dependency (e.g., spring-boot-starter-tomcat) appearing in my compileClasspath configuration. Is there any way to exclude it once and for all or should I instead do it in all projects that use my library manually?
As stated in the docs (emphasis mine):
Excluding a particular transitive dependency does not guarantee that it does not show up in the dependencies of a given configuration. For example, some other dependency, which does not have any exclude rules, might pull in exactly the same transitive dependency. To guarantee that the transitive dependency is excluded from the entire configuration please use per-configuration exclude rules: Configuration.getExcludeRules(). In fact, in majority of cases the actual intention of configuring per-dependency exclusions is really excluding a dependency from the entire configuration (or classpath).
Rather then specifying an exclusion rule for each configuration, you can apply the rule to all configurations:
// Kotlin DSL
configurations.all {
exclude(mapOf("module" to "spring-boot-starter-logging"))
exclude(mapOf("module" to "spring-boot-starter-tomcat"))
}
I'm using JUnit-dep 4.10 and Hamcrest 1.3.RC2.
I've created a custom matcher that looks like the following:
public static class MyMatcher extends TypeSafeMatcher<String> {
#Override
protected boolean matchesSafely(String s) {
/* implementation */
}
#Override
public void describeTo(Description description) {
/* implementation */
}
#Override
protected void describeMismatchSafely(String item, Description mismatchDescription) {
/* implementation */
}
}
It works perfectly fine when run from the command line using Ant. But when run from IntelliJ, it fails with:
java.lang.NoSuchMethodError: org.hamcrest.Matcher.describeMismatch(Ljava/lang/Object;Lorg/hamcrest/Description;)V
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:18)
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:8)
at com.netflix.build.MyTest.testmyStuff(MyTest.java:40)
My guess is that it's using the wrong hamcrest.MatcherAssert. How do I find which hamcrest.MatcherAssert it's using (ie which jar file it's using for hamcrest.MatcherAssert)? AFAICT, the only hamcrest jars in my classpath is 1.3.RC2.
Is IntelliJ IDEA using it's own copy of JUnit or Hamcrest?
How do I output the runtime CLASSPATH that IntelliJ is using?
Make sure the hamcrest jar is higher on the import order than your JUnit jar.
JUnit comes with its own org.hamcrest.Matcher class that is probably being used instead.
You can also download and use the junit-dep-4.10.jar instead which is JUnit without the hamcrest classes.
mockito also has the hamcrest classes in it as well, so you may need to move\reorder it as well
This problem also arises when you have mockito-all on your class path, which is already deprecated.
If possible just include mockito-core.
Maven config for mixing junit, mockito and hamcrest:
<dependencies>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
The problem was that the wrong hamcrest.Matcher, not hamcrest.MatcherAssert, class was being used. That was being pulled in from a junit-4.8 dependency one of my dependencies was specifying.
To see what dependencies (and versions) are included from what source while testing, run:
mvn dependency:tree -Dscope=test
The following should be the most correct today. Note, junit 4.11 depends on hamcrest-core, so you shouldn't need to specify that at all, mockito-all cannot be used since it includes (not depends on) hamcrest 1.1
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>1.10.8</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
</exclusion>
</exclusions>
</dependency>
This worked for me after struggling a bit
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
I know this is an old thread but what solved the issue for me was adding the following to my build.gradle files.
As already stated above there is a compatibility issue with mockito-all
Possibly useful post:
testCompile ('junit:junit:4.12') {
exclude group: 'org.hamcrest'
}
testCompile ('org.mockito:mockito-core:1.10.19') {
exclude group: 'org.hamcrest'
}
testCompile 'org.hamcrest:hamcrest-core:1.3'
Try
expect(new ThrowableMessageMatcher(new StringContains(message)))
instead of
expectMessage(message)
You may write a custom ExpectedException or utility method to wrap up the code.
As of July, 2020 the following dependencies in pom.xml worked for me:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest</artifactId>
<version>2.1</version>
</dependency>
With this 4.13 junit library and hamcrest, it uses hamcrest.MatcherAssert when asserting and throws exception-
enter image description here
Despite the fact that this is a very old question
and probably many of the beforementioned ideas solved many problems,
I still want to share the solution with the community that fixed my problem.
I found that the problem was a function called "hasItem"
which I was using to check whether or not a JSON-Array contains a specific item.
In my case I checked for a value of type Long.
And this led to the problem.
Somehow, the Matchers have problems with values of type Long.
(I do not use JUnit or Rest-Assured so much so idk. exactly why,
but I guess that the returned JSON-data does just contain Integers.)
So what I did to actually fix the problem was the following.
Instead of using:
long ID = ...;
...
.then().assertThat()
.body("myArray", hasItem(ID));
you just have to cast to Integer.
So the working code looked like this:
long ID = ...;
...
.then().assertThat()
.body("myArray", hasItem((int) ID));
That's probably not the best solution,
but I just wanted to mention that the exception can also be thrown because of wrong/unknown data types.
I have a gradle project and when my build.gradle dependencies section looks like this:
dependencies {
implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.8.1'
testImplementation group: 'org.mockito', name: 'mockito-all', version: '1.10.19'
testImplementation 'junit:junit:4.12'
// testCompile group: 'org.mockito', name: 'mockito-core', version: '2.23.4'
compileOnly 'org.projectlombok:lombok:1.18.4'
apt 'org.projectlombok:lombok:1.18.4'
}
it leads to this exception:
java.lang.NoSuchMethodError: org.hamcrest.Matcher.describeMismatch(Ljava/lang/Object;Lorg/hamcrest/Description;)V
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:18)
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:8)
to fix this issue, I've substituted "mockito-all" with "mockito-core".
dependencies {
implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.8.1'
// testImplementation group: 'org.mockito', name: 'mockito-all', version: '1.10.19'
testImplementation 'junit:junit:4.12'
testCompile group: 'org.mockito', name: 'mockito-core', version: '2.23.4'
compileOnly 'org.projectlombok:lombok:1.18.4'
apt 'org.projectlombok:lombok:1.18.4'
}
The explanation between mockito-all and mockito-core can be found here:
https://solidsoft.wordpress.com/2012/09/11/beyond-the-mockito-refcard-part-3-mockito-core-vs-mockito-all-in-mavengradle-based-projects/
mockito-all.jar besides Mockito itself contains also (as of 1.9.5) two
dependencies: Hamcrest and Objenesis (let’s omit repackaged ASM and
CGLIB for a moment). The reason was to have everything what is needed
inside an one JAR to just put it on a classpath. It can look strange,
but please remember than Mockito development started in times when
pure Ant (without dependency management) was the most popular build
system for Java projects and the all external JARs required by a
project (i.e. our project’s dependencies and their dependencies) had
to be downloaded manually and specified in a build script.
On the other hand mockito-core.jar is just Mockito classes (also with
repackaged ASM and CGLIB). When using it with Maven or Gradle required
dependencies (Hamcrest and Objenesis) are managed by those tools
(downloaded automatically and put on a test classpath). It allows to
override used versions (for example if our projects uses never, but
backward compatible version), but what is more important those
dependencies are not hidden inside mockito-all.jar what allows to
detected possible version incompatibility with dependency analyze
tools. This is much better solution when dependency managed tool is
used in a project.
In my case, I had to exclude an older hamcrest from junit-vintage:
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest</artifactId>
<version>2.1</version>
<scope>test</scope>
</dependency>
This worked for me. No need to exclude anything. I just used mockito-core instead mockito-all
testCompile 'junit:junit:4.12'
testCompile group: 'org.mockito', name: 'mockito-core', version: '3.0.0'
testCompile group: 'org.hamcrest', name: 'hamcrest-library', version: '2.1'
What worked for me was excluding the hamcrest group from the junit test compile.
Here is the code from my build.gradle:
testCompile ('junit:junit:4.11') {
exclude group: 'org.hamcrest'
}
If you're running IntelliJ you may need to run gradle cleanIdea idea clean build to detect the dependencies again.
I know that's not the best answer, but if you can't get the classpath working, this is a plan B solution.
In my test classpath, I added the following interface with a default implementation for the describeMismatch method.
package org.hamcrest;
/**
* PATCH because there's something wrong with the classpath. Hamcrest should be higher than Mockito so that the BaseMatcher
* implements the describeMismatch method, but it doesn't work for me.
*/
public interface Matcher<T> extends SelfDescribing {
boolean matches(Object item);
default void describeMismatch(Object item, Description mismatchDescription) {
mismatchDescription.appendDescriptionOf(this).appendValue(item);
}
#Deprecated
void _dont_implement_Matcher___instead_extend_BaseMatcher_();
}
For jUnit 4.12, the following dependency combination fixed my issue.
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
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'm using JUnit-dep 4.10 and Hamcrest 1.3.RC2.
I've created a custom matcher that looks like the following:
public static class MyMatcher extends TypeSafeMatcher<String> {
#Override
protected boolean matchesSafely(String s) {
/* implementation */
}
#Override
public void describeTo(Description description) {
/* implementation */
}
#Override
protected void describeMismatchSafely(String item, Description mismatchDescription) {
/* implementation */
}
}
It works perfectly fine when run from the command line using Ant. But when run from IntelliJ, it fails with:
java.lang.NoSuchMethodError: org.hamcrest.Matcher.describeMismatch(Ljava/lang/Object;Lorg/hamcrest/Description;)V
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:18)
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:8)
at com.netflix.build.MyTest.testmyStuff(MyTest.java:40)
My guess is that it's using the wrong hamcrest.MatcherAssert. How do I find which hamcrest.MatcherAssert it's using (ie which jar file it's using for hamcrest.MatcherAssert)? AFAICT, the only hamcrest jars in my classpath is 1.3.RC2.
Is IntelliJ IDEA using it's own copy of JUnit or Hamcrest?
How do I output the runtime CLASSPATH that IntelliJ is using?
Make sure the hamcrest jar is higher on the import order than your JUnit jar.
JUnit comes with its own org.hamcrest.Matcher class that is probably being used instead.
You can also download and use the junit-dep-4.10.jar instead which is JUnit without the hamcrest classes.
mockito also has the hamcrest classes in it as well, so you may need to move\reorder it as well
This problem also arises when you have mockito-all on your class path, which is already deprecated.
If possible just include mockito-core.
Maven config for mixing junit, mockito and hamcrest:
<dependencies>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
The problem was that the wrong hamcrest.Matcher, not hamcrest.MatcherAssert, class was being used. That was being pulled in from a junit-4.8 dependency one of my dependencies was specifying.
To see what dependencies (and versions) are included from what source while testing, run:
mvn dependency:tree -Dscope=test
The following should be the most correct today. Note, junit 4.11 depends on hamcrest-core, so you shouldn't need to specify that at all, mockito-all cannot be used since it includes (not depends on) hamcrest 1.1
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>1.10.8</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
</exclusion>
</exclusions>
</dependency>
This worked for me after struggling a bit
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
I know this is an old thread but what solved the issue for me was adding the following to my build.gradle files.
As already stated above there is a compatibility issue with mockito-all
Possibly useful post:
testCompile ('junit:junit:4.12') {
exclude group: 'org.hamcrest'
}
testCompile ('org.mockito:mockito-core:1.10.19') {
exclude group: 'org.hamcrest'
}
testCompile 'org.hamcrest:hamcrest-core:1.3'
Try
expect(new ThrowableMessageMatcher(new StringContains(message)))
instead of
expectMessage(message)
You may write a custom ExpectedException or utility method to wrap up the code.
As of July, 2020 the following dependencies in pom.xml worked for me:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest</artifactId>
<version>2.1</version>
</dependency>
With this 4.13 junit library and hamcrest, it uses hamcrest.MatcherAssert when asserting and throws exception-
enter image description here
Despite the fact that this is a very old question
and probably many of the beforementioned ideas solved many problems,
I still want to share the solution with the community that fixed my problem.
I found that the problem was a function called "hasItem"
which I was using to check whether or not a JSON-Array contains a specific item.
In my case I checked for a value of type Long.
And this led to the problem.
Somehow, the Matchers have problems with values of type Long.
(I do not use JUnit or Rest-Assured so much so idk. exactly why,
but I guess that the returned JSON-data does just contain Integers.)
So what I did to actually fix the problem was the following.
Instead of using:
long ID = ...;
...
.then().assertThat()
.body("myArray", hasItem(ID));
you just have to cast to Integer.
So the working code looked like this:
long ID = ...;
...
.then().assertThat()
.body("myArray", hasItem((int) ID));
That's probably not the best solution,
but I just wanted to mention that the exception can also be thrown because of wrong/unknown data types.
I have a gradle project and when my build.gradle dependencies section looks like this:
dependencies {
implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.8.1'
testImplementation group: 'org.mockito', name: 'mockito-all', version: '1.10.19'
testImplementation 'junit:junit:4.12'
// testCompile group: 'org.mockito', name: 'mockito-core', version: '2.23.4'
compileOnly 'org.projectlombok:lombok:1.18.4'
apt 'org.projectlombok:lombok:1.18.4'
}
it leads to this exception:
java.lang.NoSuchMethodError: org.hamcrest.Matcher.describeMismatch(Ljava/lang/Object;Lorg/hamcrest/Description;)V
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:18)
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:8)
to fix this issue, I've substituted "mockito-all" with "mockito-core".
dependencies {
implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.8.1'
// testImplementation group: 'org.mockito', name: 'mockito-all', version: '1.10.19'
testImplementation 'junit:junit:4.12'
testCompile group: 'org.mockito', name: 'mockito-core', version: '2.23.4'
compileOnly 'org.projectlombok:lombok:1.18.4'
apt 'org.projectlombok:lombok:1.18.4'
}
The explanation between mockito-all and mockito-core can be found here:
https://solidsoft.wordpress.com/2012/09/11/beyond-the-mockito-refcard-part-3-mockito-core-vs-mockito-all-in-mavengradle-based-projects/
mockito-all.jar besides Mockito itself contains also (as of 1.9.5) two
dependencies: Hamcrest and Objenesis (let’s omit repackaged ASM and
CGLIB for a moment). The reason was to have everything what is needed
inside an one JAR to just put it on a classpath. It can look strange,
but please remember than Mockito development started in times when
pure Ant (without dependency management) was the most popular build
system for Java projects and the all external JARs required by a
project (i.e. our project’s dependencies and their dependencies) had
to be downloaded manually and specified in a build script.
On the other hand mockito-core.jar is just Mockito classes (also with
repackaged ASM and CGLIB). When using it with Maven or Gradle required
dependencies (Hamcrest and Objenesis) are managed by those tools
(downloaded automatically and put on a test classpath). It allows to
override used versions (for example if our projects uses never, but
backward compatible version), but what is more important those
dependencies are not hidden inside mockito-all.jar what allows to
detected possible version incompatibility with dependency analyze
tools. This is much better solution when dependency managed tool is
used in a project.
In my case, I had to exclude an older hamcrest from junit-vintage:
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest</artifactId>
<version>2.1</version>
<scope>test</scope>
</dependency>
This worked for me. No need to exclude anything. I just used mockito-core instead mockito-all
testCompile 'junit:junit:4.12'
testCompile group: 'org.mockito', name: 'mockito-core', version: '3.0.0'
testCompile group: 'org.hamcrest', name: 'hamcrest-library', version: '2.1'
What worked for me was excluding the hamcrest group from the junit test compile.
Here is the code from my build.gradle:
testCompile ('junit:junit:4.11') {
exclude group: 'org.hamcrest'
}
If you're running IntelliJ you may need to run gradle cleanIdea idea clean build to detect the dependencies again.
I know that's not the best answer, but if you can't get the classpath working, this is a plan B solution.
In my test classpath, I added the following interface with a default implementation for the describeMismatch method.
package org.hamcrest;
/**
* PATCH because there's something wrong with the classpath. Hamcrest should be higher than Mockito so that the BaseMatcher
* implements the describeMismatch method, but it doesn't work for me.
*/
public interface Matcher<T> extends SelfDescribing {
boolean matches(Object item);
default void describeMismatch(Object item, Description mismatchDescription) {
mismatchDescription.appendDescriptionOf(this).appendValue(item);
}
#Deprecated
void _dont_implement_Matcher___instead_extend_BaseMatcher_();
}
For jUnit 4.12, the following dependency combination fixed my issue.
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>