目录
简介
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