Maven:在一个阶段运行插件两次,与另一个插件交错

时间:2016-05-25 10:16:17

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

对于我们的end-2-end测试,我们需要执行以下逻辑流程:

  1. 在数据库(pre-integration-test
  2. 中创建并设置e2e架构(用户)
  3. 运行Liquibase以初始填充架构(pre-integration-test
  4. 将特定于e2e的测试数据添加到数据库表(pre-integration-test
  5. 启动Tomcat(pre-integration-test
  6. 使用Protractor
  7. 在Tomcat(integration-test)中运行Web应用程序
  8. 关闭Tomcat(post-integration-test
  9. 清理数据库:删除架构(post-integration-test
  10. 对于运行SQL,使用sql-maven-plugin,但此流程不适合常规POM布局:

    • SQL插件必须在pre-integration-test期间运行两次,之前之后 liquibase-maven-plugin
    • SQL插件必须在pre-integration-test期间运行之前 Tomcat插件,但必须在post-integration-test期间>之后运行,以便数据库Tomcat关闭后,架构将被删除。

    据我所知Maven docs,POM中插件的顺序定义了同一阶段的执行顺序,并且插件在同一个POM中不能被提及两次。

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

    P.S。发现了一个类似的unanswered question

1 个答案:

答案 0 :(得分:3)

鉴于下面的样本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继承配置。

这些选项都不会对我们有所帮助。在这种情况下,我们需要在merge元素上使用一种execution属性,或者默认情况下具有不同的行为(即,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!

但在这种情况下:

  • 我们不参与任何阶段
  • 我们通过命令行直接调用特定的执行(及其配置)(并且只有Maven 3.3.1
  • 才能使用新的feature

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