Maven: build tasks (updating/copying files etc) outside lifecycle?

840 views Asked by At

What is the popular approach to managing build tasks when using Maven? I'm currently using Maven for dependency management, but I need to define several "tasks" that can be executed anytime independent of the lifecycle similar to what Ant or Rake provides; just a simple "function" that executes a sequence of steps whenever it's called by name.

For example, one "task" would be to take a jar file from a user-provided folder, install it in a local Maven repository associated with one of my maven modules using the mvn install:install-file -DlocalRepositoryPath=repo command, and change that module's pom.xml to point to the new version of the jar. This task has nothing to do with the lifecycle, it's just a general task to do some specific thing so I don't have to do it manually, executed any time I want by typing e.g. mvn task:update-jar.

Another example would be a "task" that deletes the contents of a directory inside one of my maven modules and then copies contents from a user-provided directory into the emptied directory. Again, this task has nothing to do with Maven or dependencies, but it's nice not to do it manually all the time.

How do people write these tasks - it must be a common problem? I know maven provides the antrun plugin, but as far as I know it can only bind to Maven lifecycle phases which isn't what I want. I could use Ant besides maven with a build.xml file, but that's silly if Maven somehow can be configured to do what I want by itself. Also, requiring BOTH Maven and Ant to manage my project seems less than optimal.

2

There are 2 answers

1
Adrian Shum On BEST ANSWER

If you insist to have your build work like this, Maven is not going to be a right choice for you.

However you have other alternative if you simply want dependency management, for example

  1. Gradle
  2. Ivy + Ant

They give you direct support of dependency management using Maven repository, yet give you full control on the flow of the build script.

0
Jérôme Gloaguen On

You can use maven-antrun-plugin http://maven.apache.org/plugins/maven-antrun-plugin/

so you could use a command line like that mvn antrun:run where run is a goal define by you in the pom.xml

With this plugin you can use a mix of "maven-ant" and also call ant files in maven. Use it carefuly because your project configuration could be a real mess.

A simple example used on my project to replace properties in different files

<plugin>
    <artifactId>maven-antrun-plugin</artifactId>
    <executions>
      <!-- #1 : call antrun to merge projet with convinient conf files -->
      <execution>
        <id>replace</id>
        <phase>generate-resources</phase>
        <goals>
          <goal>run</goal>
        </goals>
        <configuration>
          <tasks>
            <ant antfile="replace.xml"/>
          </tasks>
        </configuration>
      </execution>
      <!-- #2 : call antrun to explode war created in target directory-->
      <execution>
        <id>unwar</id>
        <phase>install</phase>
        <configuration>
          <tasks>
            <!-- add conf folder (was ignored during war creation) -->
            <copy todir="./target/${project.artifactId}-${project.version}/conf">
              <fileset dir="./conf"/>
            </copy>

            <!-- rebuild war with conf folder newly added -->
            <delete>
                <fileset dir="./target">
                    <include name="${project.artifactId}-${project.version}.war"/>
                </fileset>
            </delete>
            <war basedir="./target/${project.artifactId}-${project.version}" destfile="./target/${project.artifactId}-${project.version}.war" webxml="./target/${project.artifactId}-${project.version}/WEB-INF/web.xml"/> 

            <!-- copy war and exploded webapp-->
            <copy todir="./${project.artifactId}/${project.version}/${project.artifactId}-${project.version}">
                <fileset dir="./target/${project.artifactId}-${project.version}"/>
            </copy>
            <copy file="./target/${project.artifactId}-${project.version}.war" todir="/devef/maven/repository/fr/as/galilei/${project.artifactId}/${project.version}"/>

          </tasks>
        </configuration>
        <goals>
          <goal>run</goal>
        </goals>
      </execution>
    </executions>
    <dependencies>
      <dependency>
        <groupId>ant</groupId>
        <artifactId>ant-nodeps</artifactId>
        <version>1.6.5</version>
      </dependency>
    </dependencies>
  </plugin>