Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用exec:java而不是exec:exec在Maven中运行JMH基准测试?_Java_Maven_Jmh - Fatal编程技术网

如何使用exec:java而不是exec:exec在Maven中运行JMH基准测试?

如何使用exec:java而不是exec:exec在Maven中运行JMH基准测试?,java,maven,jmh,Java,Maven,Jmh,这显示了如何通过键入mvn exec:exec在Maven中运行基准测试。在Maven中运行JMH非常方便,因为您可以从Eclipse运行配置甚至在Maven阶段轻松地运行它 但是,此设置存在两个问题: 当您杀死Maven时,JMH将继续在后台运行,因为exec:exec在一个单独的VM中启动它 通常,JMH会启动另一个VM来运行基准测试,因此最终至少会有3个VM同时运行 幸运的是,还有第二个目标,exec:java,它直接在VM-Maven运行中执行一个主类。但是,当我试图使用exec:jav

这显示了如何通过键入
mvn exec:exec
在Maven中运行基准测试。在Maven中运行JMH非常方便,因为您可以从Eclipse运行配置甚至在Maven阶段轻松地运行它

但是,此设置存在两个问题:

  • 当您杀死Maven时,JMH将继续在后台运行,因为
    exec:exec
    在一个单独的VM中启动它

  • 通常,JMH会启动另一个VM来运行基准测试,因此最终至少会有3个VM同时运行

  • 幸运的是,还有第二个目标,
    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>
    
    下面是我如何从
    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的项目依赖项。但是处理这个问题的首选方法是什么?

    解决这个问题的一种方法是在从我的主方法调用JMH之前,从
    my.Benchmark
    类的类加载器中提取“有效”类路径:

    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());
    

    这似乎是可行的,但感觉很像是一个不必要的黑客…

    虽然我之前的答案要求修改基准程序,但这里有一个仅POM的解决方案,它在以下帮助下将
    java.class.path
    系统属性设置为
    运行时
    类路径:

    
    maven依赖插件
    构建类路径
    构建类路径
    运行时
    类路径
    org.codehaus.mojo
    execmaven插件
    我的.基准
    java.class.path
    ${project.build.outputDirectory}${path.separator}${depClasspath}
    
    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());
    
    <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>