即使脚本使用“开始”,使用 Maven exec 插件启动 Windows 批处理脚本也会阻止构建

Posted

技术标签:

【中文标题】即使脚本使用“开始”,使用 Maven exec 插件启动 Windows 批处理脚本也会阻止构建【英文标题】:Launching a windows batch script using Maven exec plugin blocks the build even though the script uses "start" 【发布时间】:2012-09-17 20:26:31 【问题描述】:

我正在尝试在自定义容器的顶部执行我的应用程序部署的集成测试。由于我的容器是自定义的,我无法使用 Maven Cargo 插件来设置容器。

我的容器:

必须通过适当的 bat 文件启动,该文件位于运行测试的机器的路径中。 可以手动关闭,因为我有一个包含所有集成测试的 maven 模块,即使有一天我想知道如何在测试完成后关闭进程。

我的问题是我必须在不同的进程中运行我的容器,因为它需要在执行测试时继续运行。此外,我的测试中有一个 API,可以让我等待容器准备好(一种超时查找)。

我在 pom.xml 中添加了以下几行

        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
            <version>1.1</version>
            <executions>
                <execution>
                    <phase>pre-integration-test</phase>
                    <goals>
                        <goal>exec</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <executable>scripts/start-agent.bat</executable>
            </configuration>
        </plugin>

这将调用一个脚本,其中仅包含

开始调用 gs-agent.bat

但是 mvn exec 插件卡住了,我的测试没有运行。根据How do I run a batch file from my Java Application? 中的建议,我将我的 pom.xml 修改如下:

 <configuration>
                <executable>cmd</executable>
                <arguments>
                    <argument>/C</argument>
                    <argument>start</argument>
                    <argument>gs-agent.bat</argument>
                </arguments>
            </configuration>

但这似乎并不能解决问题:

【问题讨论】:

可以看到maven被屏蔽了吗? 【参考方案1】:

exec 插件无法做到这一点,我也发现了它的问题:http://jira.codehaus.org/browse/MEXEC-87(链接现在由于 codehaus rampdown 而失效,可以从 web archive 找到)

在上面链接的jira issue中,有提及和a link of a fork for exec plugin that would have the functionality。

除此之外,我认为您暂时需要使用 antrun-plugin。

这是一个取自工作配置并使用mvn verify 运行的示例。这需要在&lt;plugins&gt; 中,而不是&lt;pluginManagement&gt; 中(exec 可以驻留在插件管理中就好了)。

<plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-antrun-plugin</artifactId>
    <version>1.6</version>
    <executions>
        <execution>
            <phase>pre-integration-test</phase>
            <configuration>
                <target>
                    <exec executable="cmd.exe"
                          spawn="true">
                        <arg value="/c"/>
                        <arg value="D:\myfolder\test.bat"/>
                    </exec>
                </target>
            </configuration>
            <goals>
                <goal>run</goal>
            </goals>
       </execution>
   </executions>      
</plugin>

请注意,spawn="true" 是此处的关键,如果您不希望执行被阻止,就像问题中指定的那样。如果您确实希望它阻止并立即查看输出,请将其设置为 false。

【讨论】:

正如我常说的:对于 80% 的构建需求,Maven。对于其他一切,Maven Antrun 插件。 :) 使用 maven verify ,使用以下目标我得到空执行 @Edmondo1984 从工作脚本中添加了直接复制粘贴,使用 mvn verify 运行良好。您确实在插件中而不是在插件管理中拥有它? 你有一个持久的bat脚本调用其他批处理脚本吗?在我的情况下,它仅在没有 spawn=true 的情况下工作,但该过程被同步调用 是的,spawn 参数用于使其异步。那么 spawn=true 会发生什么?【参考方案2】:

看到这个问题:How do I run a batch file from my Java Application?

Windows 批处理文件不可执行。它们是由cmd 可执行文件运行的脚本。

更多信息

Exec 插件source code 显示Apache Commons Executor 用于实际执行命令行。

您可以在这里阅读大量内容,即在 Apache Commons Executor 文档和他们的 JIRA issues 中,但简短的版本是:这不是“Maven”的问题,而是平台的问题- 执行exec() 命令的依赖性质。

我以前解决过这类问题,我一直设计的解决方案是将.bat 脚​​本解构为其实际命令,并直接从exec 插件启动它,而不是调用脚本。

【讨论】:

然而,这似乎并没有解决我的问题。我已经修改了我的 pom.xml,你可以在上面看到 maven exec 插件在这种情况下默认使用 cmd /c 我的脚本非常复杂。至少 200 行,还有其他更简单的解决方案吗? 我会选择@eis 提出的 antrun / fork 解决方案。祝你好运。【参考方案3】:

Fallowing Code 对我有用

<plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-antrun-plugin</artifactId>
        <version>1.3</version>
        <executions>
            <execution>
              <phase>generate-sources</phase>
                <configuration>
                    <tasks>
                        <exec dir="$project.basedir" executable="Script.bat"  failonerror="true">
                        </exec>
                    </tasks>
                </configuration>
                <goals>
                    <goal>run</goal>
                </goals>
       </execution>
   </executions>      
</plugin>

来源https://maven.apache.org/guides/mini/guide-using-ant.html

【讨论】:

这不起作用,将跳过“未定义 Ant 目标 - 跳过”的步骤 您的源代码也不包含此代码 - 也是有原因的,因为它不起作用【参考方案4】:

就我而言,我在使用 npm 和 ng.. 时遇到了问题。根本问题是 exec-maven-plugin 试图执行 sh 脚本(没有扩展名)。

重命名

C:\Users\User\AppData\Roaming\npm\ngC:\Users\User\AppData\Roaming\npm\ng.sh

C:\apps\nodejs\npmC:\apps\nodejs\npm.sh

解决了问题。

【讨论】:

【参考方案5】:

如果您想使用 exec-maven-plugin,这里有一个使用参数运行批处理脚本的示例。例如。运行类似:

.\test.bat arg1 arg2 arg3

将以下内容添加到 pom.xml:

  <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <version>1.6.0</version>
    <executions>
        <execution>
            <id>exec-test</id>
            <phase>prepare-package</phase>
            <goals>
                <goal>exec</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <executable>cmd</executable>
        <workingDirectory>./</workingDirectory>
        <arguments>
            <argument>/c</argument>
            <argument>start</argument>
            <argument>""</argument>
            <argument>exec.bat</argument>
            <argument>arg1</argument>
            <argument>arg2</argument>
            <argument>arg3</argument>
        </arguments>
    </configuration>
  </plugin>

【讨论】:

以上是关于即使脚本使用“开始”,使用 Maven exec 插件启动 Windows 批处理脚本也会阻止构建的主要内容,如果未能解决你的问题,请参考以下文章

Maven exec 插件 - 执行 python 脚本

使用 exec 插件从 Maven 3 执行脚本 - 被阻止

Maven exec插件未运行

使用带有参数的 Maven 'exec:exec'

无法在项目 mavenproject2 上执行目标 org.codehaus.mojo:exec-maven-plugin:1.3.2:exec (默认):

使用 Maven 填充数据库