一、前言
最近笔者在学习JMH,去Maven仓库复制JMH相关的依赖,在IDEA运行项目的时候发现报错:ERROR: Unable to find the resource: /META-INF/BenchmarkList
,是什么原因导致的呢?
本文由 @大白有点菜 原创,请勿盗用,转载请说明出处!如果觉得文章还不错,请点点赞,加关注,谢谢!
二、问题解决
1、Maven仓库复制的JMH的依赖
<!-- https://mvnrepository.com/artifact/org.openjdk.jmh/jmh-core -->
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>1.36</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.openjdk.jmh/jmh-generator-annprocess -->
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>1.36</version>
<scope>test</scope>
</dependency>
2、运行测试项目
【样例代码】
package cn.zhuangyt.javabase.jmh;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import java.util.concurrent.TimeUnit;
/**
* JMH测试7:BenchmarkMode中的Throughput模式
* @author 大白有点菜
*/
public class JmhTestApp7_Mode_Throughput {
/**
* Mode.Throughput, as stated in its Javadoc, measures the raw throughput by
* continuously calling the benchmark method in a time-bound iteration, and
* counting how many times we executed the method.
*
* Mode.Throughput,如其Javadoc中所述,通过在有时间限制的迭代中连续调用基准方法,并计算我们执行该方法的次数,来测量原始吞吐量。
*
* We are using the special annotation to select the units to measure in,
* although you can use the default.
*
* 我们使用特殊注释来选择要测量的单位,尽管您可以使用默认值。
*/
@Benchmark
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
public void measureThroughput() throws InterruptedException {
TimeUnit.MILLISECONDS.sleep(10);
}
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(JmhTestApp7_Mode_Throughput.class.getSimpleName())
.forks(1)
.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:98)
at org.openjdk.jmh.runner.BenchmarkList.find(BenchmarkList.java:124)
at org.openjdk.jmh.runner.Runner.internalRun(Runner.java:253)
at org.openjdk.jmh.runner.Runner.run(Runner.java:209)
at cn.zhuangyt.javabase.jmh.JmhTestApp7_Mode_Throughput.main(JmhTestApp7_Mode_Throughput.java:45)
为什么会报错:ERROR: Unable to find the resource: /META-INF/BenchmarkList
呢?经过排查,原来从Maven仓库复制来的 jmh-generator-annprocess
包依赖包含 <scope>test</scope> ,代表只用于测试阶段,将其注释或删除即可,生产环境再加上。
<!-- https://mvnrepository.com/artifact/org.openjdk.jmh/jmh-generator-annprocess -->
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>1.36</version>
<!--<scope>test</scope> -->
</dependency>
修改后再次运行项目,这次不报错了。
# JMH version: 1.36
# VM version: JDK 1.8.0_281, Java HotSpot(TM) 64-Bit Server VM, 25.281-b09
# VM invoker: D:\Develop\JDK\jdk1.8.0_281\jre\bin\java.exe
# VM options: -javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2021.1.3\lib\idea_rt.jar=13716:C:\Program Files\JetBrains\IntelliJ IDEA 2021.1.3\bin -Dfile.encoding=UTF-8
# Blackhole mode: full + dont-inline hint (auto-detected, use -Djmh.blackhole.autoDetect=false to disable)
# Warmup: 5 iterations, 10 s each
# Measurement: 5 iterations, 10 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Throughput, ops/time
# Benchmark: cn.zhuangyt.javabase.jmh.JmhTestApp7_Mode_Throughput.measureThroughput
# Run progress: 0.00% complete, ETA 00:01:40
# Fork: 1 of 1
# Warmup Iteration 1: 64.168 ops/s
# Warmup Iteration 2: 64.311 ops/s
# Warmup Iteration 3: 64.512 ops/s
# Warmup Iteration 4: 64.409 ops/s
# Warmup Iteration 5: 64.377 ops/s
Iteration 1: 64.340 ops/s
Iteration 2: 64.536 ops/s
Iteration 3: 64.311 ops/s
Iteration 4: 64.539 ops/s
Iteration 5: 64.401 ops/s
Result "cn.zhuangyt.javabase.jmh.JmhTestApp7_Mode_Throughput.measureThroughput":
64.425 ±(99.9%) 0.413 ops/s [Average]
(min, avg, max) = (64.311, 64.425, 64.539), stdev = 0.107
CI (99.9%): [64.012, 64.839] (assumes normal distribution)
# Run complete. Total time: 00:01:41
REMEMBER: The numbers below are just data. To gain reusable insights, you need to follow up on
why the numbers are the way they are. Use profilers (see -prof, -lprof), design factorial
experiments, perform baseline and negative tests that provide experimental control, make sure
the benchmarking environment is safe on JVM/OS/HW level, ask for reviews from the domain experts.
Do not assume the numbers tell you what you want them to tell.
Benchmark Mode Cnt Score Error Units
JmhTestApp7_Mode_Throughput.measureThroughput thrpt 5 64.425 ± 0.413 ops/s