最新消息:天气越来越冷,记得加一件厚衣裳

Maven集成 – Maven Invoker

Java w3sun 4850浏览 0评论

简介

Maven Invoker可以避免用户因使用Maven插件而造成的系统环境污染,同时支持在当前$ {user.dir}以外的工作目录进行项目构建。Maven Invoker不会将Maven嵌入到用户的应用程序中, 同时也不会有太多依赖,因此与Maven Embedder相比显得非常轻量级。当多个构建过程同时执行时,Maven Invoker支持用户中断其指定的某一个构建过程。

Maven Invoker API被调用时会在一个新的JVM进程中启动Maven构建,可以捕获退出码和构建过程中抛出的异常。用户可以通过使用InputStream和InvocationOutputHandler自定义输入/输出。

依赖

<dependency>
   <groupId>org.apache.maven.shared</groupId>
   <artifactId>maven-invoker</artifactId>
   <version>2.2</version>
</dependency>

用法

  • 基本用法

下面将介绍Maven调用API的基本用法。用户可以同时构建invoker 和request ,通过调用invoker.execute(request)来实现构建过程。本例中,我们暂时先不关心构建结果是否成功:

package com.w3sun.runner;

import java.io.File;
import java.util.Collections;

import org.apache.maven.shared.invoker.DefaultInvocationRequest;
import org.apache.maven.shared.invoker.DefaultInvoker;
import org.apache.maven.shared.invoker.InvocationRequest;
import org.apache.maven.shared.invoker.Invoker;
import org.apache.maven.shared.invoker.MavenInvocationException;


/**
 * @author: w3sun
 * @date: 2018/12/18 19:51
 * @description:
 */
public class Application {
  public static void main(String[] args) {
    InvocationRequest request = new DefaultInvocationRequest();
    request.setPomFile(new File("/Users/neters/Users/neters/yidian/it-inte/pom.xml"));
    request.setGoals(Collections.singletonList("package"));
    Invoker invoker = new DefaultInvoker();
    try {
      invoker.execute(request);
    } catch (MavenInvocationException e) {
      e.printStackTrace();
    }
  }
}

运行上述代码可以看到jar包已经打好:

  • 利用退出码判断构建结果

此外,如果还可以通过退出码来判断构建结果是否成功,退出码为“0”表示构建成功,退出码为“1”则表示构建失败:

InvocationRequest request = new DefaultInvocationRequest();
    request.setPomFile(new File("/Users/neters/Users/neters/yidian/it-inte/pom.xml"));
    request.setGoals(Collections.singletonList("package"));
    Invoker invoker = new DefaultInvoker();
    try {
      InvocationResult result = invoker.execute(request);
      int exitCode = result.getExitCode();
      System.out.println("======/========/=========/=========/=====");
      if (0==exitCode){
        System.out.println("build process succeeds!");
      }else{
        System.out.println("build process fails!");
      }
    } catch (MavenInvocationException e) {
      e.printStackTrace();
    }

构建成功会终端打印”build process succeeds!”:

  • Invoker单实例配置复用

用户可以通过Invoker配置为Maven API调用指定全局选项,配置单个Invoker实例并在多个方法调用从而实现复用。

package com.w3sun.it.maven;

import java.io.File;
import java.util.Arrays;
import java.util.List;

import org.apache.maven.shared.invoker.DefaultInvocationRequest;
import org.apache.maven.shared.invoker.DefaultInvoker;
import org.apache.maven.shared.invoker.InvocationRequest;
import org.apache.maven.shared.invoker.InvocationResult;
import org.apache.maven.shared.invoker.Invoker;
import org.apache.maven.shared.invoker.MavenInvocationException;

/**
 * @author: w3sun
 * @date: 2018/12/18 20:44
 * @description:
 */
public class MavenInvokerBuilder {
  private static final List<String> GOALS = Arrays.asList("clean", "package", "-DskipTests");

  /**
   * define a field for the Invoker instance.
   **/
  private final Invoker invoker;

  /**
   * now, instantiate the invoker in the class constructor
   **/
  public MavenInvokerBuilder(File localRepositoryDir) {
    this.invoker = new DefaultInvoker();
    this.invoker.setLocalRepositoryDirectory(localRepositoryDir);
  }

  /**
   * this method will be called repeatedly, and fire off new builds...
   */
  public void build() throws MavenInvocationException {
    InvocationRequest request = new DefaultInvocationRequest();
    request.setInteractive(false);
    request.setGoals(GOALS);
    InvocationResult result = invoker.execute(request);

    if (result.getExitCode() != 0) {
      if (result.getExecutionException() != null) {
        throw new MavenInvocationException("Verify the pom.xml error!",
            result.getExecutionException());
      }
    }
  }
}

测试:

package com.w3sun.it.maven;

import java.nio.file.Paths;

import org.apache.maven.shared.invoker.MavenInvocationException;
import org.junit.Test;

/**
 * @author: w3sun
 * @date: 2018/12/18 20:45
 * @description:
 */
public class MavenInvokerBuilderTest {
  @Test
  public void build() throws MavenInvocationException {
    MavenInvokerBuilder mavenInvokerBuilder = new MavenInvokerBuilder(Paths.get(".").toFile());
    mavenInvokerBuilder.build();
  }
}

  • 结合InvocationOutputHandler捕获构建输出

如果用户想要获取构建过程详情,可以利用InvocationOutputHandler进行捕获。InvocationOutputHandler可以通过invoker 或者request进行设置。

package com.w3sun.it.maven;

import java.io.File;
import java.util.Arrays;
import java.util.List;

import org.apache.maven.shared.invoker.DefaultInvocationRequest;
import org.apache.maven.shared.invoker.DefaultInvoker;
import org.apache.maven.shared.invoker.InvocationOutputHandler;
import org.apache.maven.shared.invoker.InvocationRequest;
import org.apache.maven.shared.invoker.InvocationResult;
import org.apache.maven.shared.invoker.Invoker;
import org.apache.maven.shared.invoker.MavenInvocationException;

/**
 * @author: w3sun
 * @date: 2018/12/18 20:44
 * @description:
 */
public class MavenInvokerBuilder {
  private static final List<String> PUBLISH_GOALS = Arrays.asList("clean", "package",
      "-DskipTests");
  private StringBuilder output = new StringBuilder();
  ;
  /**
   * define a field for the Invoker instance.
   **/
  private final Invoker invoker;

  /**
   * now, instantiate the invoker in the class constructor
   **/
  public MavenInvokerBuilder(File localRepositoryDir) {
    this.invoker = new DefaultInvoker();
    this.invoker.setLocalRepositoryDirectory(localRepositoryDir);
  }

  /**
   * this method will be called repeatedly, and fire off new builds...
   */
  public void build() throws MavenInvocationException {
    InvocationRequest request = new DefaultInvocationRequest();
    request.setInteractive(false);
    request.setGoals(PUBLISH_GOALS);
    setOutput(request);
    InvocationResult result = this.invoker.execute(request);
    if (result.getExitCode() != 0) {
      if (result.getExecutionException() != null) {
        throw new MavenInvocationException("Verify the pom.xml error!",
            result.getExecutionException());
      }
    }
  }

  /**
   * Set output handler by InvocationRequest.
   *
   * @param request InvocationRequest
   */
  private void setOutput(InvocationRequest request) {
    request.setOutputHandler(new InvocationOutputHandler() {
      @Override
      public void consumeLine(String line) {
        output.append(line)
            .append(System.lineSeparator());
      }
    });
  }

  /**
   * Set output handler  by Invoker.
   *
   * @param invoker Invoker
   */
  private void setOutput(Invoker invoker) {
    invoker.setOutputHandler(new InvocationOutputHandler() {
      @Override
      public void consumeLine(String line) {
        output.append(line)
            .append(System.lineSeparator());
      }
    });
  }

  public String getOutput() {
    return output.toString();
  }
}

测试:

package com.w3sun.it.maven;

import java.nio.file.Paths;

import org.apache.maven.shared.invoker.MavenInvocationException;
import org.junit.Test;

/**
 * @author: w3sun
 * @date: 2018/12/18 20:45
 * @description:
 */
public class MavenInvokerBuilderTest {
  @Test
  public void build() throws MavenInvocationException {
    MavenInvokerBuilder mavenInvokerBuilder = new MavenInvokerBuilder(Paths.get(".").toFile());
    mavenInvokerBuilder.build();
    String output = mavenInvokerBuilder.getOutput().toString();
    System.out.println("---------------------------------");
    System.out.println("---------------------------------");
    System.out.println("---------out----------put--------");
    System.out.println("---------------------------------");
    System.out.println("---------------------------------");
    System.out.println(output);
  }
}

注意事项

  • 用户可以使用Invoker.setMavenHome()方法来指定Maven可执行文件位置。 如果用户没有设置该值,则Invoker将使用系统属性maven.home或环境变量M2_HOME的值作为其默认值。
  • 如果在Maven Surefire插件运行的单元测试中进行了API调用,则需要Surefire将系统属性maven.home传递给测试用例:
<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.12.4</version> <!-- see surefire-page for available versions -->
        <configuration>
          <systemPropertyVariables>
            <maven.home>${maven.home}</maven.home>
          </systemPropertyVariables>
        </configuration>
      </plugin>
    </plugins>
    ...
  </build>
  ...
</project>

参考资料

https://github.com/apache/maven-invoker

https://maven.apache.org/shared/maven-invoker/index.html

转载请注明:雪后西塘 » Maven集成 – Maven Invoker

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址