2

When deploying a webapp I need to concat some files, currently this is achieved via an ant task. I'm trying to run this task in the maven build process using something like the following:

<plugin>
    <artifactId>maven-antrun-plugin</artifactId>
    <version>1.7</version>
    <executions>
        <execution>
            <phase>package</phase>
            <configuration>
                <target>
                    <move file="${project.build.directory}/${project.name}-${project.version}/WEB-INF/classes/log4j.dev.properties"
                        tofile="${project.build.directory}/${project.name}-${project.version}/WEB-INF/classes/log4j.properties" />

                    <move file="${project.build.directory}/${project.name}-${project.version}/WEB-INF/classes/hibernate.cfg.dev.xml"
                        tofile="${project.build.directory}/${project.name}-${project.version}/WEB-INF/classes/hibernate.cfg.xml" />
                    <delete>
                        <fileset dir="${project.build.directory}/${project.name}-${project.version}/WEB-INF/classes/"
                            includes="**/hibernate.cfg.*.xml" />
                        <fileset dir="${project.build.directory}/${project.name}-${project.version}/WEB-INF/classes/"
                            includes="**/log4j.*.properties" />     
                    </delete>
                </target>
            </configuration>
            <goals>
                <goal>run</goal>
            </goals>
        </execution>
    </executions>
</plugin>

The above fails because the files have not yet been copied/deleted into target directory. If I set the phase to "package" the ant task runs fine and all the files are copied/deleted, but it's no help as the .war has already been built before the ant target is run.

Basically, I need to run my ant target near the end of the prepare-package phase.

Having looked though the Lifecycle Reference I can't workout how to expose the more granular Goals to the antrun plugin.

Question: How to achieve this scenario?

A_Di-Matteo
  • 26,902
  • 7
  • 94
  • 128
Mercer
  • 9,736
  • 30
  • 105
  • 170
  • at the end of the prepare-package would mean you set prepare-package in the phase element. For the same reason, if you put package there, it will be executed after whatever comes by default. So you want to execute it before the maven-war-plugin execution, right? – A_Di-Matteo Mar 23 '16 at 15:22
  • @A.DiMatteo yes it's right – Mercer Mar 23 '16 at 15:23

1 Answers1

6

Rather then executing it at the end of the prepare-package phase, you probably want to execute it within the package phase but before the war packaging (via the Maven War Plugin).

A possible solution is as possible:

  • Disable the default Maven War Plugin
  • Add your execution within the package phase
  • Add a new Maven War Plugin execution for the package phase

Since Maven will execute plugins within the same phase by the declaration order, you would then have your ant execution first, then the war packaging.

Executing the following:

mvn help:effective-pom

You can check that by default the war packaging already configures a Maven War Plugin execution for us:

<plugin>
    <artifactId>maven-war-plugin</artifactId>
    <version>2.2</version>
    <executions>
        <execution>
            <id>default-war</id>
            <phase>package</phase>
            <goals>
                <goal>war</goal>
            </goals>
        </execution>
    </executions>
</plugin>

We could then add to our POM the following after the maven-antrun-plugin declaration:

<plugin>
    <artifactId>maven-war-plugin</artifactId>
    <version>2.2</version>
    <executions>
        <execution>
            <id>default-war</id>
            <phase>none</phase>
            <goals>
                <goal>war</goal>
            </goals>
        </execution>
        <execution>
            <id>package-war</id>
            <phase>package</phase>
            <goals>
                <goal>war</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Note: we are actually using the same default execution id and binding it to a non existing phase (none) and as such disabling it; then we are adding a new execution (the package-war id), which will be executed by Maven after your maven-antrun-plugin execution but still within the package phase.

Note that the declaration order is really important to achieve your goal, so better to also add a comment (for colleagues, if any, and for the future yourself).


Further note: it seems you are swapping dev files with prod-like files, you could probably achieve the same via Maven profiles and Maven resource filtering delegating to properties values the differences between environments and as such avoid swapping files.

Check this SO post for some hints if interested in this alternative approach.

Community
  • 1
  • 1
A_Di-Matteo
  • 26,902
  • 7
  • 94
  • 128
  • thx it's work. Yes i swapping some file, with filter you can't delete files which is not used ? – Mercer Mar 23 '16 at 15:43
  • indeed, you cannot delete, but you would only have one file, its content would have values which may change between envs (via properties, values via profiles), so that you would not need to delete files anyway. But I don't have the whole picture, so not sure it could be applicable 100% – A_Di-Matteo Mar 23 '16 at 15:45