在Eclipse中作为Maven项目,JMH无法工作 - 没有可运行的基准测试。

7
我想开始学习 JMH,但由于一些原因无法运行基准测试。让我解释一下我的尝试过程:
  1. 在 Eclipse 中设置一个 Maven 项目
  2. 定义 pom.xml 如下: enter image description here

  3. 下载一些官方的 JMH 示例。例如,我选择了一个相当简单且很好入门的示例: http://hg.openjdk.java.net/code-tools/jmh/file/0c58dc4fcf17/jmh-samples/src/main/java/org/openjdk/jmh/samples/JMHSample_01_HelloWorld.java

  4. 右键点击 > Run As > Java Application

然而这会产生以下输出:

Exception in thread "main" No benchmarks to run; check the include/exclude regexps.
at org.openjdk.jmh.runner.Runner.run(Runner.java:155)
at org.openjdk.jmh.samples.JMHSample_01_HelloWorld.main(JMHSample_01_HelloWorld.java:90)

我已经谷歌搜索过,看起来上面的示例应该可以工作,但对我来说并非如此。 我也尝试通过阅读来解决问题,但似乎对我无效:

  • "No matching benchmarks" when running JMH from main in eclipse
  • I tried to move the generated class manually to /META-INF/MicroBenchmarks however this produces following error:

    Exception in thread "main" java.lang.IllegalStateException: Mismatched format for the line: JMHSample_01_HelloWorld.class
    at org.openjdk.jmh.runner.BenchmarkRecord.<init>(BenchmarkRecord.java:92)
    at org.openjdk.jmh.runner.MicroBenchmarkList.find(MicroBenchmarkList.java:133)
    at org.openjdk.jmh.runner.Runner.run(Runner.java:150)
    at JMHSample_01_HelloWorld.main(JMHSample_01_HelloWorld.java:80)
    

看起来JMH应该在/META-INF/MicroBenchmarks文件夹中生成一些有效的行 - 意味着在这个文件夹中不应该有生成的java类文件,对吗?

可以有人帮我找到错误吗?谢谢。


3
你错过了一个步骤,即未将JMH注解处理器应用于你的基准测试。最好从使用JMH主页上给出的示例命令生成新项目开始。请注意,不要改变原文的意思。 - Oleg Estekhin
2
jmh-dev中的这篇文章提供了有关在post-0.5 JMH中使用注释处理器的额外信息。 - Oleg Estekhin
非常感谢!注解处理器丢失了!:-)。我所做的就是: 1)使用Eclipse>文件>新建Maven项目创建新的Maven项目 2)使用默认的工作区位置 3)搜索组ID“org.openjdk.jmh” 4)选择“jmh-java-benchmark-archetype” 5)输入您的组ID和Artifact ID(例如jmh-test) 6)通过右键单击项目>运行为>Maven Clean清理Maven 7)通过右键单击项目>运行为>Maven Install安装Maven 8)从JMH网站导入示例 9)转到JMHSample_01_HelloWorld并将其作为Java应用程序运行希望这能帮助其他人... - pitschr
@OlegEstekhin能否提供答案并标记为“Answer”,然后pitschr接受它呢?否则,该问题在搜索列表中会感觉未被回答 :) 谢谢。 - Aleksey Shipilev
@OlegEstekhin 如果有更好的文档说明就好了。有时候你可能不想创建一个新的Maven项目,但是要让这个黑魔法正常工作却很棘手。 - Has QUIT--Anony-Mousse
我认为需要使用Maven原型方法是不幸的,特别是自从升级到jmh 0.x版本以来,至少第一次升级变得非常困难。而且许多/大多数教程仍在使用版本0.2或0.4。至少需要特定依赖项(由此处的顶部答案提供,谢谢!)也应该被jmh文档记录下来。 - StaxMan
4个回答

14

这个基准的“源代码”,除了像往常一样编译之外,还需要通过JMH注解处理器进行处理。在JMH 0.5之前,注解处理器是主要JMH工件的一部分,因此只需要一个jmh-core的依赖即可。在JMH 0.5中,注解处理功能被提取到单独的工件中,以便支持其他语言。

为了使旧的基于Java的JMH项目重新获得注解处理器,应声明对处理器工件的额外依赖:

<dependency>
    <groupId>org.openjdk.jmh</groupId>
    <artifactId>jmh-generator-annprocess</artifactId>
    <version>${jmh.version}</version>
    <!-- 
    the processor artifact is required only during compilation and 
    does not need to be transitive, hence provided scope
    -->
    <scope>provided</scope> 
</dependency>

对于新的JMH项目,最简单的方法是使用适当的语言特定原型(除了Java,还有Scala、Groovy和Kotlin archetypes),如JMH主页上所述,生成一个新项目。

mvn archetype:generate \
      -DinteractiveMode=false \
      -DarchetypeGroupId=org.openjdk.jmh \
      -DarchetypeArtifactId=jmh-java-benchmark-archetype \
      -DgroupId=my.benchmark.group \
      -DartifactId=MyBenchMarkArtifact \
      -Dversion=1.0

1
在我的jmh+maven+eclipse项目中,尽管已经安装了所有必需的依赖项和插件,但我在eclipse控制台中遇到了相同的错误。
尝试从终端运行mvn clean install而不是使用eclipse中的嵌入式maven,结果出现以下错误。
ERROR: org.openjdk.jmh.runner.RunnerException: ERROR: Unable to acquire the JMH lock (/tmp/jmh.lock): already taken by another JMH instance, exiting. Use -Djmh.ignoreLock=true to forcefully continue.
    at org.openjdk.jmh.runner.Runner.run(Runner.java:202)
    at org.openjdk.jmh.Main.main(Main.java:71)

如上建议,在eclipse的Java应用程序启动器中添加-Djmh.ignoreLock=true作为VM参数,它起作用了


0

如果您重构了包含@Benchmark的类的名称,则可能会遇到此错误。

您还需要在主函数中更改名称。

OptionsBuilder opts = new OptionsBuilder();
opts.include("<new_class_name>");

0

我遇到了同样的错误,因为我在之前运行后更改了包含我的@Benchmark类的包名称。进行“清理和构建”就足以让它再次正常工作。


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