Running external Ant file from a parent pom

2019-08-12 01:55发布

问题:

I would like to run an Ant build.xml build from a parent POM.

This may look like this:

<project>
    <groupId>my.group</groupId>
    <artifactId>my-parent</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-antrun-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>initialize</phase>
                        <configuration>
                            <tasks>
                                <ant antfile="build.xml"/>
                            </tasks>
                        </configuration>
                        <goals>
                            <goal>run</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

This works just fine unless I use this module as a parent POM. The problem is in this line <ant antfile="build.xml"/>. While this POM is running as a parent POM there is no build.xml file available to the plugin.

How can I run an Ant script from a file (located in the parent POM) during all child build?

PS I tried to package the build.xml under some classifier to make it available to the children builds. But I have no idea, how can I extract my packaged build.xml prior to the antrun:run.

PPS

The project structure:

<root>
  + Parent POM
  | +- pom.xml
  | +- build.xml
  |
  + Component1
  | + Child1
  | | +- src/main/java
  | | +- ...
  | | +- pom.xml
  | |
  | + Child2
  |   +- src/main/java
  |   +-...
  |   +- pom.xml
  |
  + Component2
    + Child3
    | +- src/main/java
    | +- ...
    | +- pom.xml
    |
    + Child4
      +- src/main/java
      +-...
      +- pom.xml

As a bonus: I also would like to know the answer for the situations, where the parent POM get built and deployed independently (not knowing own child) and children get built having only access to the parent deployed artifacts (not the source code).

回答1:

To avoid the FileNotFoundException you could use a configured property as prefix of the ant build file. Such a property would be empty on the parent pom while would have the right prefix (i.e. relative path to parent folder) in the required modules.

For instance, in your parent POM your configuration would look like:

<properties>
    <ant.build.dir.prefix></ant.build.dir.prefix>
</properties>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-antrun-plugin</artifactId>
            <executions>
                <execution>
                    <phase>initialize</phase>
                    <configuration>
                        <tasks>
                            <ant antfile="${ant.build.dir.prefix}build.xml" />
                        </tasks>
                    </configuration>
                    <goals>
                        <goal>run</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

Note the ${ant.build.dir.prefix} prefix added to the ant invocation. By default it will be empty, which means file would be supposed to be located in the same directory as the pom.

However, in modules you would just need to override the value of the property, as following:

<properties>
    <ant.build.dir.prefix>..\</ant.build.dir.prefix>
</properties>

Or any other relative path in the folders hierarchy.

At runtime, the value will be replaced and as such the path to the ant file will dynamically change, enforcing a common and centralized configuration of the ant run (in the parent pom) and a specific path configuration in modules (via a property prefix).

I just tested both cases (your configuration and the prefixed one) in a sample project with an echo ant task, being able to reproduce your issue and to fix it as suggested above.