melix / jmh-gradle-plugin

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

0.5.0 jmhJar Fails if you depend on another sub-project #159

Open Emilio-Pega opened 4 years ago

Emilio-Pega commented 4 years ago

Using 0.4.8 the jmhRuntime configuration could include basic *.class files, but that not longer appears to be the case on the 0.5.0 plugin due to this commit https://github.com/melix/jmh-gradle-plugin/commit/6482f72a459ff7bfc54b767bc33226bb3831e5af#diff-e026bd8196ff0ae749272ee78a2cb4ff

This logic assumes that all files on the runtime configuration are either Jars (zipTree) or directories.

If you are in a multi-project build, and you include a sub-project as a dependency, gradle will add the class files to the configuration (not a jar) causing the jmhJar task to take an exception similar to this one:

Caused by: org.gradle.api.GradleException: Could not expand ZIP '/home/git/sub-project-1/environment/Environment.class'.
        at org.gradle.api.internal.file.archive.ZipFileTree.visit(ZipFileTree.java:104)
        at org.gradle.api.internal.file.collections.FileTreeAdapter.visit(FileTreeAdapter.java:118)
Decat-SimonA commented 4 years ago

Is there a work-around for this ?

graemerocher commented 4 years ago

Seems to somehow also impact dependencies of subprojects as for me the error manifests as:

> Could not expand ZIP '/Users/graemerocher/.gradle/caches/modules-2/files-2.1/javax.persistence/javax.persistence-api/2.2/25665ac8c0b62f50e6488173233239120fc52c96/javax.persistence-api-2.2.ja
melix commented 4 years ago

The configuration setup in this plugin is just a big mess, it should never have been wired like that. I think the problem is that the JMH runtime classpath configuration doesn't declare any attribute like it should, I'll try something and keep you posted.

In the meantime, can anyone provide a reproducer?

melix commented 4 years ago

I'm not able to reproduce with a simple test project dependency like:

plugins {
   id 'java'
   id 'me.champeau.gradle.jmh'
}

repositories {
    jcenter()
}

dependencies {
   jmh project(":core")
}

So if you're facing this please give me a simple reproducer so that I can work on a fix, thank you!

graemerocher commented 4 years ago

Yeah it doesn't seem to be every project that fails. You can reproduce with:

git clone git@github.com:micronaut-projects/micronaut-data.git
cd micronaut-data
./gradlew benchmarks:benchmark-micronaut-data-jpa:jmh
melix commented 4 years ago

Alright, I understand what's going on now: the dependency it tries to unzip is not available yet. That's a problem with how the spec is setup...

melix commented 4 years ago

@graemerocher by running with --stacktrace I figured out that your issue is that the same jar is included multiple times. Just add this to your build file and the error goes away:

jmh {
   duplicateClassesStrategy = DuplicatesStrategy.EXCLUDE
}
graemerocher commented 4 years ago

Great! thanks for the workaround!

jbrinegar commented 4 years ago

@melix it looks like this might apply more broadly. I have config files on my classpath, which I put there intentionally with compileOnly, and jmhRun wants to unzip them :). If I remove the config files, or just use 0.4.8, I don't experience the problem.

Config files on the classpath are used in several open source projects.

sandorfr commented 4 years ago

I had a similar error due to a very different cause. Jackson jar seems pretty heavy and required me to use zip64:

jmh {
    zip64 true
}
zhangyzzz commented 4 years ago

In my case, the workaround is to apply shadow plugin instead of relying on the default JMH standard Jar to build fatJar. https://plugins.gradle.org/plugin/com.github.johnrengelman.shadow.

Simply apply the shadow plugin before jmh plugin in your benchmark build.gradle. No other configurations needed.