提供了一套用java方法调用来实现maven的命令执行接口,方便你通过java代码来实现项目打包发布等操作。特别是用在自动化倒闭的需求中。可以考虑使用。

1.MavenInvoker的maven依赖

  1. <dependency>
  2. <groupId>org.apache.maven.shared</groupId>
  3. <artifactId>maven-invoker</artifactId>
  4. <version>2.2</version>
  5. </dependency>

2.使用用法

  1. import java.io.File;
  2. import java.util.Collections;
  3. import org.apache.maven.shared.invoker.DefaultInvocationRequest;
  4. import org.apache.maven.shared.invoker.DefaultInvoker;
  5. import org.apache.maven.shared.invoker.InvocationRequest;
  6. import org.apache.maven.shared.invoker.Invoker;
  7. import org.apache.maven.shared.invoker.MavenInvocationException;
  8. /**
  9. * @author: fanjinlong
  10. * @date: 2018/12/18 19:51
  11. * @description:
  12. */
  13. public class Application {
  14. public static void main(String[] args) {
  15. InvocationRequest request = new DefaultInvocationRequest();
  16. request.setPomFile(new File("/Users/neters/Users/neters/yidian/it-inte/pom.xml"));
  17. request.setGoals(Collections.singletonList("package"));
  18. Invoker invoker = new DefaultInvoker();
  19. try {
  20. invoker.execute(request);
  21. } catch (MavenInvocationException e) {
  22. e.printStackTrace();
  23. }
  24. }
  25. }

jar包已经打好:

用java代码执行mave命令的MavenInvoker - 图1

  • 利用退出码判断构建结果。退出码为“0”表示构建成功,退出码为“1”则表示构建失败
  1. InvocationRequest request = new DefaultInvocationRequest();
  2. request.setPomFile(new File("/Users/neters/Users/neters/yidian/it-inte/pom.xml"));
  3. request.setGoals(Collections.singletonList("package"));
  4. Invoker invoker = new ();
  5. try {
  6. InvocationResult result = invoker.execute(request);
  7. int exitCode = result.getExitCode();
  8. System.out.println("退出码:"+exitCode);
  9. if (0==exitCode){
  10. System.out.println("构建成功");
  11. }else{
  12. System.out.println("构建失败");
  13. }
  14. } catch (MavenInvocationException e) {
  15. e.printStackTrace();
  16. }

3.Invoker单实例配置复用

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

  1. import java.io.File;
  2. import java.util.Arrays;
  3. import java.util.List;
  4. import org.apache.maven.shared.invoker.DefaultInvocationRequest;
  5. import org.apache.maven.shared.invoker.DefaultInvoker;
  6. import org.apache.maven.shared.invoker.InvocationRequest;
  7. import org.apache.maven.shared.invoker.InvocationResult;
  8. import org.apache.maven.shared.invoker.Invoker;
  9. import org.apache.maven.shared.invoker.MavenInvocationException;
  10. /**
  11. * @author: fanjinlong
  12. * @date: 2018/12/18 20:44
  13. * @description:
  14. */
  15. public class MavenInvokerBuilder{
  16. private static final List<String> GOALS = Arrays.asList("clean", "package", "-DskipTests");
  17. /**
  18. * 定义Invoker实例.
  19. **/
  20. private final Invoker invoker;
  21. /**
  22. * 在构造器中实例化Invoker
  23. **/
  24. public MavenInvokerBuilder(File localRepositoryDir) {
  25. this.invoker = new DefaultInvoker();
  26. this.invoker.setLocalRepositoryDirectory(localRepositoryDir);
  27. }
  28. /**
  29. * 此方法将被重复调用,并启动新的生成。。。
  30. */
  31. public void build() throws MavenInvocationException {
  32. InvocationRequest request = new DefaultInvocationRequest();
  33. request.setBatchMode(false);
  34. request.setGoals(GOALS);
  35. InvocationResult result = invoker.execute(request);
  36. if (result.getExitCode() != 0) {
  37. if (result.getExecutionException() != null) {
  38. throw new MavenInvocationException("验证pom.xml错误!",
  39. result.getExecutionException());
  40. }
  41. }
  42. }
  43. }

测试:

  1. import java.nio.file.Paths;
  2. import org.apache.maven.shared.invoker.MavenInvocationException;
  3. import org.junit.Test;
  4. /**
  5. * @author: fanjinlong
  6. * @date: 2018/12/18 20:45
  7. * @description:
  8. */
  9. public class MavenInvokerBuilderTest {
  10. @Test
  11. public void build() throws MavenInvocationException {
  12. = new (Paths.get(".").toFile());
  13. .build();
  14. }
  15. }

用java代码执行mave命令的MavenInvoker - 图2

4.结合InvocationOutputHandler捕获构建输出

可以利用InvocationOutputHandler进行捕获。InvocationOutputHandler可以通过invoker或者request进行设置。

  1. import java.io.File;
  2. import java.util.Arrays;
  3. import java.util.List;
  4. import org.apache.maven.shared.invoker.DefaultInvocationRequest;
  5. import org.apache.maven.shared.invoker.DefaultInvoker;
  6. import org.apache.maven.shared.invoker.InvocationOutputHandler;
  7. import org.apache.maven.shared.invoker.InvocationRequest;
  8. import org.apache.maven.shared.invoker.InvocationResult;
  9. import org.apache.maven.shared.invoker.Invoker;
  10. import org.apache.maven.shared.invoker.MavenInvocationException;
  11. /**
  12. * @author: fanjinlong
  13. * @date: 2018/12/18 20:44
  14. * @description:
  15. */
  16. public class {
  17. private static final List<String> PUBLISH_GOALS = Arrays.asList("clean", "package",
  18. "-DskipTests");
  19. private StringBuilder output = new StringBuilder();
  20. ;
  21. /**
  22. * 为调用程序实例定义一个字段。
  23. **/
  24. private final Invoker invoker;
  25. /**
  26. * 在类构造函数中实例化调用程序
  27. **/
  28. public (File localRepositoryDir) {
  29. this.invoker = new ();
  30. this.invoker.setLocalRepositoryDirectory(localRepositoryDir);
  31. }
  32. /**
  33. * 此方法将被重复调用,并启动新的生成
  34. */
  35. public void build() throws MavenInvocationException {
  36. InvocationRequest request = new DefaultInvocationRequest();
  37. request.setBatchMode(false);
  38. request.setGoals(PUBLISH_GOALS);
  39. setOutput(request);
  40. InvocationResult result = this.invoker.execute(request);
  41. if (result.getExitCode() != 0) {
  42. if (result.getExecutionException() != null) {
  43. throw new MavenInvocationException("Verify the pom.xml error!",
  44. result.getExecutionException());
  45. }
  46. }
  47. }
  48. /**
  49. * 通过调用请求设置输出处理程序。
  50. * @param request InvocationRequest
  51. */
  52. private void setOutput(InvocationRequest request) {
  53. request.setOutputHandler(new InvocationOutputHandler() {
  54. @Override
  55. public void consumeLine(String line) {
  56. output.append(line).append(System.lineSeparator());
  57. }
  58. });
  59. }
  60. /**
  61. * 通过调用程序设置输出处理程序。
  62. *
  63. */
  64. private void setOutput(Invoker invoker) {
  65. invoker.setOutputHandler(new InvocationOutputHandler() {
  66. @Override
  67. public void consumeLine(String line) {
  68. output.append(line).append(System.lineSeparator());
  69. }
  70. });
  71. }
  72. public String getOutput() {
  73. return output.toString();
  74. }
  75. }

测试

  1. import org.apache.maven.shared.invoker.MavenInvocationException;
  2. import org.junit.Test;
  3. /**
  4. * @author: fanjinlong
  5. * @date: 2018/12/18 20:45
  6. * @description:
  7. */
  8. public class MavenInvokerBuilderTest {
  9. @Test
  10. public void build() throws MavenInvocationException {
  11. = new (Paths.get(".").toFile());
  12. .build();
  13. String output = .getOutput().toString();
  14. System.out.println("---------------------------------");
  15. System.out.println("---------------------------------");
  16. System.out.println("---------out----------put--------");
  17. System.out.println("---------------------------------");
  18. System.out.println("---------------------------------");
  19. System.out.println(output);
  20. }
  21. }

用java代码执行mave命令的MavenInvoker - 图3

注意事项

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