【问题标题】:Maven: run plugin twice during a phase, interleaved with another pluginMaven:在一个阶段运行插件两次,与另一个插件交错
【发布时间】:2016-09-22 21:06:04
【问题描述】:

对于我们的端到端测试,我们需要执行以下逻辑流程:

  1. 在数据库中创建和设置 e2e 模式(用户) (pre-integration-test)
  2. 运行 Liquibase 以初始填充架构 (pre-integration-test)
  3. 将 e2e 特定的测试数据添加到 DB 表 (pre-integration-test)
  4. 启动 Tomcat (pre-integration-test)
  5. 使用 Protractor 在 Tomcat (integration-test) 中运行 Web 应用程序
  6. 关闭 Tomcat (post-integration-test)
  7. 清理数据库:删除架构 (post-integration-test)

为了运行 SQL,使用了sql-maven-plugin,但是这个流程不适合常规的 POM 布局:

  • SQL 插件必须在pre-integration-test 期间运行两次,之前之后 liquibase-maven-plugin
  • SQL 插件必须在 pre-integration-test 期间运行 before Tomcat 插件,但是它必须在 post-integration-test 期间运行 after,以便在之后删除 DB 架构Tomcat 已关闭。

据我从Maven docs 得出的结论,POM 中插件的顺序定义了同一阶段的执行顺序,一个插件不能在同一个 POM 中被提及两次。

问题:除了编写一个会多次调用 Maven 的 shell 脚本之外,还有什么方法可以实现这一点?

附:找到了一个类似的unanswered question

【问题讨论】:

  • 作为解决方法,我建议从第 3 步向下使用 exec-maven-plugin 作为 maven cli
  • 不可能,即使在 pom 中两次声明同一个插件(按照您想要的顺序,由另一个插件交错)将​​导致其执行合并,因此最终顺序不会受到影响(首先执行第一个声明的插件的同一阶段的目标,然后是交错的)。从 cli 或通过 exec maven 插件列出所有这些目标确实是一种解决方案,但不是可选的(它们将在阶段之外运行)。功能请求可能是一个更好的主意。
  • 是的,这也是我观察到的,两次提到一个插件确实会导致一些意想不到的行为。我认为编写外部控制脚本确实是最好的解决方案,尽管它依赖于平台。

标签: java maven tomcat liquibase sql-maven-plugin


【解决方案1】:

鉴于下面的示例 POM:

<project>
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.sample</groupId>
    <artifactId>sample-project</artifactId>
    <version>0.0.2-SNAPSHOT</version>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-antrun-plugin</artifactId>
                <version>1.5</version>
                <executions>
                    <execution>
                        <id>print-hello</id>
                        <phase>validate</phase>
                        <goals>
                            <goal>run</goal>
                        </goals>
                        <configuration>
                            <target>
                                <echo message="hello there!" />
                            </target>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.5.0</version>
                <executions>
                    <execution>
                        <id>exec-echo</id>
                        <phase>validate</phase>
                        <configuration>
                            <executable>cmd</executable>
                            <arguments>
                                <argument>/C</argument>
                                <argument>echo</argument>
                                <argument>hello-from-exec</argument>
                            </arguments>
                        </configuration>
                        <goals>
                            <goal>exec</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <artifactId>maven-antrun-plugin</artifactId>
                <version>1.5</version>
                <executions>
                    <execution>
                        <id>print-hello-2</id>
                        <phase>validate</phase>
                        <goals>
                            <goal>run</goal>
                        </goals>
                        <configuration>
                            <target>
                                <echo message="hello there 2!" />
                            </target>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

我们实际上是在配置:

  • maven-antrun-plugin 打印 hello there! 消息
  • exec-maven-plugin 打印hello-from-exec 消息
  • maven-antrun-plugin 打印hello there 2! 消息

目标执行都附加到同一阶段validate,我们希望以相同的定义顺序执行。

但是,在调用时(-q 选项用于准确且只有它们的输出):

mvn validate -q

我们会有输出:

main:
     [echo] hello there!

main:
     [echo] hello there 2!
hello-from-exec

也就是说,对于同一阶段,Maven 执行了定义的插件,但是合并了相同插件的所有定义的执行(即使定义为不同的plugin 部分),然后按照合并定义的顺序执行它们。

很遗憾,没有机制可以避免这种合并。我们用于配置插件执行行为的唯一选项是:

  • inherited 配置条目:

    truefalse,此插件配置是否应适用于继承自此的 POM。默认值为true

  • combine.childrencombine.self

    通过向配置元素的子元素添加属性来控制子 POM 如何从父 POM 继承配置。

这些选项都对我们没有帮助。在这种情况下,我们需要在 execution 元素上添加一种 merge 属性,或者在默认情况下具有不同的行为(即,Maven 应该遵守定义顺序)。


从命令行调用单个执行如下:

mvn antrun:run@print-hello exec:exec@exec-echo antrun:run@print-hello-2 -q

我们会得到想要的输出:

main:
     [echo] hello there!
hello-from-exec

main:
     [echo] hello there 2!

但在这种情况下:

  • 我们不依附于任何阶段
  • 我们正在通过命令行直接调用特定的执行(及其配置)(以及通过新的feature 仅在 Maven 3.3.1 之后可用

您可以通过脚本或通过 exec-maven-plugin 调用 maven 本身来实现完全相同的效果,但同样适用:不应用阶段,只应用执行序列。

【讨论】:

  • @yktoo 你最终解决了这个问题吗?您没有接受答案,也没有分享其他反馈。只是检查:)
  • 我也很感兴趣 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-02-27
  • 2019-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多