How to use JMH with gradle?

醉酒当歌 提交于 2021-02-17 15:15:01

问题


I want to use JMH, an OpenJDK microbenchmark tool, with gradle. However, Im getting the NPE on compilation. On the other hand, JMH works when using from maven.

I am not posting any build.gradle as it is basic - apply java plugin and add dependency on JHM tool (org.openjdk.jmh:jmh-core:0.2).

I have tried whats written here without success.

What else I have to do? I think something with setting the agent, but I still didnt figure it out.

Exception:

:compileJava
java.lang.NullPointerException
at org.openjdk.jmh.processor.internal.GenerateMicroBenchmarkProcessor.validMethodSignature(GenerateMicroBenchmarkProcessor.java:502)

回答1:


Just finished my "masterpiece". No uber-jars, no plugins, code base separated from main & test, benchmarks compilation hooked to main, but does not run automatically in the mainstream lifecycle. Simple, explicit, and hackable, vanilla gradle.

I run it directly from IntelliJ, to run on a box you probably will need the uber-jar back :-)

Before doing it I have spent a fair amount of time trying to get that plugin work, but it's way too clunky for my taste.

Step-by-step breakdown below.

Define a new sourceSet called jmh with classpath hooked to that of the main sourceSet

sourceSets {
    jmh {
        java.srcDirs = ['src/jmh/java']
        scala.srcDirs = ['src/jmh/scala']
        resources.srcDirs = ['src/jmh/resources']
        compileClasspath += sourceSets.main.runtimeClasspath
    }
}

Define dependencies for it (at minimum JMH and its annotation processor).

dependencies {
    ...
    jmhImplementation 'org.openjdk.jmh:jmh-core:1.21'
    jmhImplementation 'org.openjdk.jmh:jmh-generator-annprocess:1.21'
}

Define a task jmh of type JavaExec

task jmh(type: JavaExec, dependsOn: jmhClasses) {
    main = 'org.openjdk.jmh.Main'
    classpath = sourceSets.jmh.compileClasspath + sourceSets.jmh.runtimeClasspath
}

Hook jmhClasses task to run after classes to make sure benchmarks are compiled with the rest of the code

classes.finalizedBy(jmhClasses)



回答2:


Currently you can just use dedicated plugin jmh-gradle-plugin

It requires minimal configuration and allows you to run JMH benchmarks as well as build benchmarks artifact




回答3:


My bad, I was trying to benchmark a method that has an argument - of course JMH will not know what to pass :) Once when I created a void method with no arguments, everything worked.

My build.gradle:

defaultTasks 'build'

apply plugin: 'java'
apply plugin: 'shadow'

buildscript {
    repositories {
        mavenCentral()
        maven {
            name 'Shadow'
            url 'http://dl.bintray.com/content/johnrengelman/gradle-plugins'
        }
    }
    dependencies {
        classpath 'org.gradle.plugins:shadow:0.7.4'
    }
}

jar {
    manifest {
        attributes 'Main-Class': 'org.openjdk.jmh.Main'
    }
}

repositories {
    mavenCentral()
}


build.doLast {
    tasks.shadow.execute()
}

shadow {
    outputFile = new File('build/libs/microbenchmarks.jar')
}

ext {
    lib = [
        ... other dependencies...
        jmh:            'org.openjdk.jmh:jmh-core:0.2'
    ]
}

dependencies {
    compile lib... other dependencies...
    compile lib.jmh
}

sourceCompatibility = 1.7

Build tests and jar:

gw clean build

and then run them with:

java -jar build/libs/microbenchmarks.jar ".*" -wi 2 -i 10 -f 2 -t 16

UPDATE

From recent versions of JMH, you would also need to add dependency to:

org.openjdk.jmh:jmh-generator-annprocess:0.5.4

and you can use shadow 0.8.




回答4:


If you're an IntelliJ user, perhaps the easiest way to make it work, without all that workarounds, is to use the IDE plugin:

https://github.com/artyushov/idea-jmh-plugin

  • Add the dependencies
  • Create your benchmark
  • be happy :)



回答5:


I made a very small example project to clone and modify as you like. It's a full working example:
https://gitlab.com/barfuin/jmh-gradle-example

It requires no shadow Jars and no plugins. The project also includes some extra Gradle tasks for printing the classpath, the JMH options, etc., stuff that may help to understand what's going on. It does not teach microbenchmarking though. 😊



来源:https://stackoverflow.com/questions/20443997/how-to-use-jmh-with-gradle

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!