Maven Invoker:非法状态异常

12

我有一个多模块的Maven项目(https://github.com/veniltonjr/msplearning)。

我的其中一个模块需要以编程方式运行Maven构建中的“clean install”命令,但当我调用执行这些目标时,会出现以下错误:

java.lang.IllegalStateException: Maven应用程序目录未指定,并且系统属性中未提供${maven.home}。请至少指定其中之一。

Maven Invoker文档中指出,必须存在 M2_HOME 环境变量。

我已经在我的操作系统中设置了此变量。这不足以使 invoke 方法工作吗?以下是我运行该方法的代码片段:

Invoker invoker = new DefaultInvoker();
invoker.setLocalRepositoryDirectory(new File("C:\\git\\msplearning"));

InvocationRequest request = new DefaultInvocationRequest();
request.setGoals(Arrays.asList("clean", "install"));
InvocationResult result = invoker.execute(request); // Exception occours here...

已经好了,谢谢!

编辑(解决方案)

我需要设置POM并设置Maven Home,在我的情况下是在M3_HOME环境变量中:

InvocationRequest request = new DefaultInvocationRequest();
request.setPomFile(new File("C:\\git\\msplearning\\pom.xml"));
request.setGoals(Collections.singletonList("verify"));

Invoker invoker = new DefaultInvoker();
invoker.setMavenHome(new File(System.getenv("M3_HOME")));
InvocationResult result = invoker.execute(request);

感谢 @RobertScholte 和 @khmarbaise!


1
为什么需要运行这样的命令?在根目录下执行 mvn install 不可以吗? - khmarbaise
感谢您的评论@khmarbaise。当我在根级别运行mvn install时,构建成功完成。但是我需要以编程方式运行此命令,因为我需要在RESTful服务中提供输出工件。 - falvojr
1
@veniltonjr 要执行上述代码,您需要在计算机上安装Maven还是只需要一些jar文件就足够了? - Lucy
嗨@Lucy!具体来说,此解决方案使用在服务器上配置的MV3_HOME环境变量。因此需要安装Maven。 - falvojr
2个回答

2

要让Invoker知道从哪个目录或文件执行Apache Maven,请设置request.pomFilerequest.baseDirectory


谢谢您的回复@RobertScholte!但是这些选项都没有起作用。您对此问题有更多的建议吗?在我的父项目([msplearning](https://github.com/veniltonjr/msplearning))的一个模块中,执行服务[ProductRESTfulServer](https://github.com/veniltonjr/msplearning/blob/master/restful-app/src/main/java/com/msplearning/restful/app/ProductRESTfulServer.java)上的方法“invoke”。 - falvojr
我认为Karl-Heinz问了正确的问题。你想要构建什么?哪个pom.xml文件? - Robert Scholte
我真的想构建父项目的pom:msplearning/pom.xml - falvojr
1
你难道不是把编译时间和运行时间混淆了吗?我不明白为什么你需要在运行时重新构建项目。我试图构建你的项目,但我缺少ANDROID_HOME。几点备注:你的项目只能使用M3.0.x版本进行构建,而不能使用M3.1.x+(尽管这可能不是问题)。在开发过程中,版本必须始终以“-SNAPSHOT”结尾。 - Robert Scholte
1
这意味着您需要该项目的源代码。要么将其检出到TMP_android-app目录中的源代码(例如),要么包含http://maven.apache.org/plugins/maven-assembly-plugin/descriptor-refs.html#project并将其解压缩到TMP_android-app中。现在将request.baseDir设置为TMP_android-app并运行`verify`(不是'clean install',过度繁琐)。 - Robert Scholte
显示剩余2条评论

1

如果您正在运行 Maven-Surefire 单元测试,则最好请求 Surefire 将 maven.home 系统属性传递给其子进程。根据 https://maven.apache.org/shared/maven-invoker/usage.html,您可以通过添加以下配置段来实现:

<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>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接