You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Maven基准测试配置报错:无法加载org.openjdk.jmh.runner.ForkedMain类

JMH基准测试Maven Profile执行时出现ClassNotFoundException: org.openjdk.jmh.runner.ForkedMain

问题场景

我在Maven中创建了一个Profile,期望通过mvn verify -Dbenchmark运行所有JMH基准测试,配置如下:

<profiles>
   <profile>
       <id>benchmark</id>
       <activation>
           <property>
               <name>benchmark</name>
           </property>
       </activation>
       <properties>
           <benchmark.report>false</benchmark.report>
       </properties>
       <build>
           <plugins>
               <plugin>
                   <groupId>org.codehaus.mojo</groupId>
                   <artifactId>exec-maven-plugin</artifactId>
                   <executions>
                       <execution>
                           <phase>verify</phase>
                           <goals>
                               <goal>java</goal>
                           </goals>
                       </execution>
                   </executions>
                   <configuration>
                       <mainClass>org.openjdk.jmh.Main</mainClass>
                       <arguments>.*</arguments>
                       <classpathScope>test</classpathScope>
                   </configuration>
               </plugin>
           </plugins>
       </build>
   </profile>
</profiles>

执行时抛出以下异常:

Caused by: java.lang.ClassNotFoundException: org.openjdk.jmh.runner.ForkedMain
<forked VM failed with exit code 1>
<stdout last='20 lines'>
</stdout>
<stderr last='20 lines'>
Error: Could not find or load main class org.openjdk.jmh.runner.ForkedMain
Caused by: java.lang.ClassNotFoundException: org.openjdk.jmh.runner.ForkedMain
</stderr>

单独运行基准测试无异常,设置classpathScope为test是为了找到分散的META-INF/benchmarklist文件。

原因分析

这个异常的核心问题是JMH默认会fork子进程运行基准测试,但exec-maven-plugin的配置只保证了主进程的类路径包含test依赖和JMH库,fork出来的子进程无法继承完整的类路径:

  • 当通过org.openjdk.jmh.Main启动基准测试时,JMH会自动创建子进程(ForkedMain)隔离测试环境,避免主进程的JVM参数、已有线程影响测试结果
  • exec-maven-plugin的classpathScope仅作用于主进程,子进程的类路径未被正确配置,导致找不到org.openjdk.jmh.runner.ForkedMain类
  • 单独运行时类路径完整,不存在该问题,但通过exec插件启动时,fork子进程的类路径未包含JMH核心依赖

解决方案

方案1:改用JMH官方Maven插件(推荐)

JMH官方提供的jmh-maven-plugin专门处理基准测试的类路径、fork逻辑,无需手动维护子进程的类路径:

<profiles>
    <profile>
        <id>benchmark</id>
        <activation>
            <property>
                <name>benchmark</name>
            </property>
        </activation>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.openjdk.jmh</groupId>
                    <artifactId>jmh-maven-plugin</artifactId>
                    <version>1.37</version> <!-- 替换为最新稳定版 -->
                    <executions>
                        <execution>
                            <phase>verify</phase>
                            <goals>
                                <goal>benchmark</goal>
                            </goals>
                        </execution>
                    </executions>
                    <configuration>
                        <includes>.*</includes> <!-- 匹配所有基准测试类 -->
                        <classpathScope>test</classpathScope> <!-- 加载test路径下的benchmarklist -->
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>

方案2:修改exec-maven-plugin配置,禁用JMH fork

如果坚持使用exec插件,可以通过JMH参数-f 0禁用fork子进程,让基准测试在主进程运行(注意:这种方式可能影响测试结果准确性,主进程环境可能存在干扰):

<configuration>
    <mainClass>org.openjdk.jmh.Main</mainClass>
    <arguments>-f 0 .*</arguments> <!-- 添加-f 0参数禁用fork -->
    <classpathScope>test</classpathScope>
</configuration>

内容的提问来源于stack exchange,提问作者origin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 16:55:07