melix / jmh-gradle-plugin

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

Consider switching the default DuplicatesStrategy to warn #259

Open madhead opened 7 months ago

madhead commented 7 months ago

Some of the dependencies in my project have identically named files at the same paths. Like LICENSEs and module-infos:

(a screenshot where I already raised the duplicatesStrategy to WARN) image

When the plugin tried to create a JMH JAR without the shadow plugin, i.e. by using the createStandardJmhJar method, the task (jmhJar) just silently did nothing. It didn't fail, but it also didn't produce a JAR. It's hard to tell why, because a regular JAR task at least leaves the JAR, but in my case the resulting JAR was absent.

This is a big deal, because JMH doesn't give you a sane error report in this case. Here is what I get, for example:

java.lang.IllegalArgumentException: Benchmark does not match a class
        at org.openjdk.jmh.util.ClassUtils.loadClass(ClassUtils.java:94)
        at org.openjdk.jmh.runner.BenchmarkHandler.<init>(BenchmarkHandler.java:72)
        at org.openjdk.jmh.runner.BaseRunner.runBenchmark(BaseRunner.java:232)
        at org.openjdk.jmh.runner.BaseRunner.doSingle(BaseRunner.java:138)
        at org.openjdk.jmh.runner.BaseRunner.runBenchmarksForked(BaseRunner.java:75)
        at org.openjdk.jmh.runner.ForkedRunner.run(ForkedRunner.java:72)
        at org.openjdk.jmh.runner.ForkedMain.main(ForkedMain.java:86)
Caused by: java.lang.ClassNotFoundException: me.madhead.tempa.jmh_generated.PredicatesBenchmark_companion_jmhTest
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
        at java.base/java.lang.Class.forName0(Native Method)
        at java.base/java.lang.Class.forName(Class.java:315)
        at org.openjdk.jmh.util.ClassUtils.loadClass(ClassUtils.java:73)
        ... 6 more

image

While the classes were clearly there, note the lib directory is empty! Again, I am not sure why, and this is not the behavior of the JAR task. It either fails with a stacktrace or produces a JAR. But I suspect it's due to those dups, because when I changed the strategy to DuplicatesStrategy.EXCLUDE it began to work. image

This issue is really hard to understand.

If the duplicateClassesStrategy would not be set to any default or if it would be set to WARN the user would at least see some clues in the logs in this case.