JMH 无法找到资源:/META-INF/BenchmarkList

57
我无法在eclipse中运行简单的JMH基准测试。 Maven依赖项:
            <dependency>
                <groupId>org.openjdk.jmh</groupId>
                <artifactId>jmh-core</artifactId>
                <version>1.12</version>
            </dependency>
            <dependency>
                <groupId>org.openjdk.jmh</groupId>
                <artifactId>jmh-generator-annprocess</artifactId>
                <version>1.12</version>
            </dependency>

Java代码:

    public class BTest {
        @Benchmark
        public void test() {
            // todo
        }
    
        public static void main(String[] args) throws RunnerException {
            Options opt = new OptionsBuilder()
                     .include(BTest.class.getSimpleName())
                      .build();
    
            new Runner(opt).run();
        }
    }

运行结果:

> Exception in thread "main" java.lang.RuntimeException: ERROR: Unable
> to find the resource: /META-INF/BenchmarkList     at
> org.openjdk.jmh.runner.AbstractResourceReader.getReaders(AbstractResourceReader.java:96)
>   at org.openjdk.jmh.runner.BenchmarkList.find(BenchmarkList.java:104)
>   at org.openjdk.jmh.runner.Runner.internalRun(Runner.java:256)   at
> org.openjdk.jmh.runner.Runner.run(Runner.java:206)    at
> com.test.BTest.main(BTest.java:24)

也许问题在于我是从eclipse中运行它。

你试过不在Eclipse中运行它吗?既然你提到了它,尝试一下也是有道理的。 - Will Barnwell
@WillBarnwell 还没有... - riva
这里可能是Idea的答案:https://github.com/artyushov/idea-jmh-plugin/issues/13#issuecomment-95628473 - NanoNova
@NanoNova 不起作用。 - Hariom Yadav
10个回答

23
如果有人正在使用Gradle,请将jmh-gradle-plugin添加到您的插件块中。
plugins {
    id 'java'
    id 'me.champeau.jmh' version '0.6.8'
}

然后在你的依赖块中添加以下所有内容(请在Maven上检查JMH的最新版本这里):

dependencies {
    jmh 'org.openjdk.jmh:jmh-core:1.36'
    jmh 'org.openjdk.jmh:jmh-generator-annprocess:1.36'

    // this is the line that solves the missing /META-INF/BenchmarkList error
    jmhAnnotationProcessor 'org.openjdk.jmh:jmh-generator-annprocess:1.36'
}

然后只需使用以下代码通过Gradle运行您的基准测试:

./gradlew jmh

在IDE中运行

如果你想要在IDE中运行基准测试而不是通过Gradle,可以选择以下任意一种方式:

选项 1 - main 方法

只需使用没有其他配置的 main 方法,你的 IDE 将会遵循你的注解配置:

@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
@Fork(value = 1)
@Warmup(iterations = 5, timeUnit = TimeUnit.MILLISECONDS, time = 5000)
@Measurement(iterations = 5, timeUnit = TimeUnit.MILLISECONDS, time = 5000)
public class MyBenchmark {

    public static void main(String[] args) throws RunnerException {
        Options options = new OptionsBuilder()
            .include(MyBenchmark.class.getSimpleName())
            .build();
        new Runner(options).run();
    }

    // benchmarks omitted
}

选项2-安装JMH插件

如果你正在使用IntelliJ,请在“首选项>插件”部分安装JMH Java Microharness基准测试插件,然后您可以完全省略main方法,IntelliJ将在类名称旁边提供一个运行按钮:

IntelliJ中的JMH基准测试


为什么插件不直接为您设置这些东西呢? - Chad
jmhAnnotationProcessor 不是必需的。实际上,除非您想更改版本,否则不需要在 dependencies 块中显示的任何内容。 - Abhijit Sarkar
1
与之前的评论相反,如果没有这些依赖项,IntelliJ的JMH插件会产生问题列表中列出的错误。 - undefined

16

终于找到了原因。缺少exec-maven-plugin插件。

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <executions>
        <execution>
            <id>run-benchmarks</id>
            <phase>integration-test</phase>
            <goals>
                <goal>exec</goal>
            </goals>
            <configuration>
                <classpathScope>test</classpathScope>
                <executable>java</executable>
                <arguments>
                    <argument>-classpath</argument>
                    <classpath />
                    <argument>org.openjdk.jmh.Main</argument>
                    <argument>.*</argument>
                </arguments>
            </configuration>
        </execution>
    </executions>
</plugin>

1
奇怪的是,对于Scala + Maven,我甚至不得不添加这个才能获得你上面提到的错误...:https://github.com/bbarker/scala-maven-jmh-bench-demo/tree/89481477d6d051c038eabbb16ce6c14212844b8d - bbarker

9

pom.xml文件必须包含以下依赖项和配置,才能使用Java微基准测试Harness(JMH)框架。

<properties>
    <jmh.version>1.21</jmh.version>
</properties>
<dependencies>
<dependency>
    <groupId>org.openjdk.jmh</groupId>
    <artifactId>jmh-core</artifactId>
    <version>${jmh.version}</version>
</dependency>
<dependency>
    <groupId>org.openjdk.jmh</groupId>
    <artifactId>jmh-generator-annprocess</artifactId>
    <version>${jmh.version}</version>
</dependency>
<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.11</version>
  <scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>java-jmh</finalName>
<plugins>
    <plugin>    
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
            <source>1.8</source>
            <target>1.8</target>
            <annotationProcessorPaths>
                <path>
                    <groupId>org.openjdk.jmh</groupId>
                    <artifactId>jmh-generator-annprocess</artifactId>
                    <version>${jmh.version}</version>
                </path>
            </annotationProcessorPaths>
        </configuration>
    </plugin>
    <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>exec-maven-plugin</artifactId>
        <executions>
            <execution>
                <id>run-benchmarks</id>
                <phase>integration-test</phase>
                <goals>
                    <goal>exec</goal>
                </goals>
                <configuration>
                    <classpathScope>test</classpathScope>
                    <executable>java</executable>
                    <arguments>
                        <argument>-classpath</argument>
                        <classpath />
                        <argument>org.openjdk.jmh.Main</argument>
                        <argument>.*</argument>
                    </arguments>
                </configuration>
            </execution>
        </executions>
    </plugin>
</plugins>

在此之后,打开命令行并运行命令 $mvn clean install


5

4

4

我曾经遇到相同的错误,使用Maven或Intellij运行测试也无法解决。后来我意识到问题是我用Kotlin编写了基准测试代码。将代码改为Java后问题得到解决。


2
我在Kotlin中尝试编写@Benchmark,但是却花了几个小时一直遇到错误。最终我转而使用Java,问题迎刃而解。 - Technetium

0

如果你在使用Intelij Idea的JMH Java微基准插件时遇到此错误,并且你也在使用Gradle,请尝试将默认运行任务从Gradle更改为Intelij Idea。做法如下:

设置 -> 构建、执行、部署 -> 构建工具 -> Gradle

构建和运行使用更改为Intelij IDEA


0

这是我需要添加到pom.xml文件中的所有内容来修复我的问题。
这段代码最终与Ishaq's answer非常接近,只是少了一些额外的内容和特定名称。
我希望这是一个更干净、更易于使用的答案。

  <properties>
    <jmh.version>1.36</jmh.version>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.openjdk.jmh</groupId>
      <artifactId>jmh-core</artifactId>
      <version>${jmh.version}</version>
    </dependency>
    <dependency>
      <groupId>org.openjdk.jmh</groupId>
      <artifactId>jmh-generator-annprocess</artifactId>
      <version>${jmh.version}</version>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>3.2.0</version>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>shade</goal>
            </goals>
            <configuration>
              <finalName>benchmarks</finalName>
              <transformers>
                <transformer
                        implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                  <mainClass>org.openjdk.jmh.Main</mainClass>
                </transformer>
              </transformers>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

0

加上版本号,这个对我有效

        <groupId>org.codehaus.mojo</groupId>
        <artifactId>exec-maven-plugin</artifactId>
        <version>3.0.0</version>

0

我尝试了上述所有解决方案。最终我使用了jmh-maven-plugin:

<plugin>
    <groupId>pw.krejci</groupId>
    <artifactId>jmh-maven-plugin</artifactId>
    <version>0.2.2</version>
</plugin>

然后我使用以下命令运行它:

mvn clean install jmh:benchmark

看起来似乎不需要exec-maven-plugin,maven-compiler-plugin或maven-shade-plugin。

注意基准测试必须在测试包中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接