melix / jmh-gradle-plugin

Integrates the JMH benchmarking framework with Gradle
Apache License 2.0
662 stars 88 forks source link

Plugin putting logback on classpath but it is already in the fat jar #186

Open greenrd opened 3 years ago

greenrd commented 3 years ago

Describe the bug The plugin puts logback on the classpath (incorrectly) even though it was already (correctly, I think) included in the fat jar. So it appears twice on the classpath and generates this warning:

SLF4J: Class path contains multiple SLF4J bindings.

This is not the same as #135 though the symptom is the same.

To Reproduce Steps to reproduce the behavior:

  1. Create a project with Gradle 6.5.1
  2. Add to the build a jmh dependency on logback, and an implementation dependency on org.apache.avro:avro:1.10.0. (This brings in slf4j as a transitive dependency.)
  3. Cause something to be logged via SLF4J.
  4. See error
prosprice commented 3 years ago

As you say, something is putting dependencies on the JMH runtime classpath in addition to those items contained in the fat JAR:

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/C:/Users/xxx/.gradle/caches/modules-2/files-2.1/org.slf4j/slf4j-nop/1.7.30/55d4c73dd343efebd236abfeb367c9ef41d55063/slf4j-nop-1.7.30.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/C:/gradleproject/build/libs/gradleproject-x.y.z-SNAPSHOT-jmh.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 [org.slf4j.helpers.NOPLoggerFactory]

I worked around it by applying the Gradle Shadow Plugin as discussed in the documentation and specifically excluding SLF4J's StaticLoggerBinder from the jmhJar task. So with this change the combined JAR is incomplete, but the unwanted duplicate "fixes" it. If the duplication on the classpath is ever fixed, I'd have to revert this change:

jmhJar {
  exclude 'org/slf4j/impl/StaticLoggerBinder.class' // to silence duplicate classpath warnings
}
reinhapa commented 3 years ago

Why does a fat jar generated anyway? In case of duplicated Java resources, this approach will not work anyway as I would see it.. Also does JMH offer the possibility to create a meta jar file in order to counter the command line length in case of long class paths...