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



