melix / jmh-gradle-plugin

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

jmhCompileGeneratedClasses task is deleting BenchmarkList file contents #89

Open Amelia-Lopez opened 7 years ago

Amelia-Lopez commented 7 years ago

I'm using version 0.3.1 of the plugin with Gradle 3.1, and I'm seeing the jmhCompileGeneratedClasses task consistently wipe out the contents of the build/jmh-generated-classes/META-INF/BenchmarkList file.

The minimal set of commands to recreate the issue are:

./gradlew clean
./gradlew jmhRunBytecodeGenerator
./gradlew jmhCompileGeneratedClasses
./gradlew clean
./gradlew jmh

Which results in the error:

No matching benchmarks. Miss-spelled regexp?

I specifically tested using this project: https://github.com/Mario-Lopez/gradle-jmh-scala

Once you run those commands, all future runs fail (despite running ./gradlew clean) until you delete the Gradle cache:

rm -fr .gradle/3.1     # at the root of the repo

If you run these commands, you can see when the issue occurs:

./gradlew clean
./gradlew jmhRunBytecodeGenerator       # BenchmarkList is correctly populated
./gradlew jmhCompileGeneratedClasses    # BenchmarkList is still populated
./gradlew clean
./gradlew jmhRunBytecodeGenerator       # BenchmarkList is correctly populated
./gradlew jmhCompileGeneratedClasses    # BenchmarkList is now empty

My educated guess is that Gradle 3 is more aggressively caching the inputs and outputs of each task, and the outputs of the jmhRunBytecodeGenerator task is being misreported by the plugin.

The jmhRunBytecodeGenerator task declares one output directory: https://github.com/melix/jmh-gradle-plugin/blob/master/src/main/groovy/me/champeau/gradle/JMHPlugin.groovy#L73

But it's actually writing to two output directories: https://github.com/melix/jmh-gradle-plugin/blob/master/src/main/groovy/me/champeau/gradle/JMHPlugin.groovy#L80

The build/jmh-generated-classes/META-INF/BenchmarkList file is being written by the jmhRunBytecodeGenerator task to the output directory of the jmhCompileGeneratedClasses task, so when the jmhCompileGeneratedClasses task gets run for the second time, I assume Gradle is using its cache of the task output which doesn't include writing out the BenchmarkList file. I'm not sure how that translates to wiping out the contents of the file but leaving the file there, though.

langera commented 7 years ago

I have the same issue. In my jar I can see two META-INF/BenchmarkList files - The second one is empty which means reading it results in an empty file. I verified that it is indeed the jmhCompileGeneratedClasses task that creates the empty file.

Is there any workaround?

Amelia-Lopez commented 7 years ago

What I've been having to do is make sure I don't run the individual tasks if I can help it (it seems to more consistently fail when I run those), and when it does fail, I delete the repo's Gradle cache.

For example, if my repository is at /home/mario/gradle-jmh-scala, I run:

cd /home/mario/gradle-jmh-scala
rm -fr .gradle/

When possible, I always run just the jmh task and not the jmhRunBytecodeGenerator and jmhCompileGeneratedClasses tasks.

RezaLabude commented 7 years ago

We are also running into this issue and therefore had to revert back to the previous version of the plugin = 0.2.0, which seems to works fine with gradle 3.0. It would be grate if you could provide some insight why this problem is occurring and how to solve it.

sergey-morenets commented 7 years ago

@RezaLabude Hi

I tried your workaround(using plugin version 0.2.0 and Gradle 3.4) however it didn't work for me. The issue still remained.