此post on javapapers.com显示了如何通过键入mvn exec:exec
在Maven中运行JMH基准。在Maven中运行JMH非常方便,因为您可以从Eclipse Run Configuration甚至Maven阶段轻松运行它。
但是,此设置存在两个问题:
当你杀死Maven时,JMH将继续在后台运行,因为exec:exec
在一个单独的VM中启动它。
通常,JMH将启动另一个 VM来运行基准测试,因此您最终将同时运行至少3个VM。
幸运的是,Exec Maven Plugin附带了第二个目标exec:java
,它直接在VM Maven运行中执行主类。但是,当我尝试使用exec:java
配置Maven来运行JMH时,由于缺少类,基准测试崩溃了:
# JMH 1.11.3 (released 40 days ago)
# VM version: Error: Could not find or load main class org.openjdk.jmh.runner.VersionMain
# VM invoker: C:\Program Files\Java\jdk1.7.0\jre\bin\java.exe
[...]
# Run progress: 0.00% complete, ETA 00:02:40
# Fork: 1 of 1
Error: Could not find or load main class org.openjdk.jmh.runner.ForkedMain
<forked VM failed with exit code 1>
以下是pom.xml
的相关部分:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.4.0</version>
<configuration>
<mainClass>my.Benchmark</mainClass>
</configuration>
</plugin>
以下是我如何从my.Benchmark
运行JMH:
public static void main(String[] args) throws RunnerException {
Options options = new OptionsBuilder().include(my.Benchmark.class.getSimpleName())
.forks(1).build();
new Runner(options).run();
}
我意识到JMH使用java.class.path
系统属性来确定分叉VM的类路径,并且该属性不包含Maven的项目依赖性。但是解决这个问题的首选方法是什么?
答案 0 :(得分:5)
解决这个问题的一种方法是提取&#34;有效的&#34;在从我的main方法调用JMH之前,来自my.Benchmark
类的类加载器的classpath:
URLClassLoader classLoader = (URLClassLoader) my.Benchmark.class.getClassLoader();
StringBuilder classpath = new StringBuilder();
for(URL url : classLoader.getURLs())
classpath.append(url.getPath()).append(File.pathSeparator);
System.setProperty("java.class.path", classpath.toString());
这似乎有效,但感觉很像一个不应该是必要的黑客...
答案 1 :(得分:5)
虽然我之前的回答需要修改基准程序,但这是一个仅限POM的解决方案,它借助Dependency Plugin将java.class.path
系统属性设置为runtime
类路径:< / p>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>build-classpath</id>
<goals>
<goal>build-classpath</goal>
</goals>
<configuration>
<includeScope>runtime</includeScope>
<outputProperty>depClasspath</outputProperty>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<configuration>
<mainClass>my.Benchmark</mainClass>
<systemProperties>
<systemProperty>
<key>java.class.path</key>
<value>${project.build.outputDirectory}${path.separator}${depClasspath}</value>
</systemProperty>
</systemProperties>
</configuration>
</plugin>