Can Maven run non-build tasks?

Joe DiNottra :

I moved from Ant to Maven and I miss one thing: the ability to execute an arbitrary task. I wanted to get rid of Ant's build.xml but I still need it just for this.

Occasionally I need to run some stats for XML processing and PDF processing. They are not part of the build but I need to automate them anyway. In Ant I used to just compile and run a java class in the code to using the java Ant task, e.g.:

<target name="gen-stats">
  <java classname="com.utl.StatsGen" classpath="build" />
</target>

<target name="compute-complexity">
  <java classname="com.utl.PDFComplexity" classpath="lib/pdf-cpx.jar" />
</target>

Trying to wrap my brain around it. Maybe Maven wasn't designed to do help with any automation, but only addresses "build oriented" tasks. Is it?

Ariel Carrera :

Basically, Maven define Phases, Goals, Plugins and Lifecycles.

Phase: A stage during a defined build Lifecycle.
Each Phase is a sequence of goals.

Goal: A Goal is responsible for a specific task.

Plugin: A Plugin is a group of Goals (Goals aren't necessarily all bound to the same phase).

Lifecycle: A Lifecycle is a sequence of Phases.

Having said that, there is a default set of Maven's Lifecycles.

  • default (main lifecycle responsible for handle project deployment -build and deploy your project-)
  • clean (lifecycle responsible for handle project cleaning)
  • site (lifecycle reponsible for create project's site documentation)

Default Lifecycle phases

<phases>
  <phase>validate</phase>
  <phase>initialize</phase>
  <phase>generate-sources</phase>
  <phase>process-sources</phase>
  <phase>generate-resources</phase>
  <phase>process-resources</phase>
  <phase>compile</phase>
  <phase>process-classes</phase>
  <phase>generate-test-sources</phase>
  <phase>process-test-sources</phase>
  <phase>generate-test-resources</phase>
  <phase>process-test-resources</phase>
  <phase>test-compile</phase>
  <phase>process-test-classes</phase>
  <phase>test</phase>
  <phase>prepare-package</phase>
  <phase>package</phase>
  <phase>pre-integration-test</phase>
  <phase>integration-test</phase>
  <phase>post-integration-test</phase>
  <phase>verify</phase>
  <phase>install</phase>
  <phase>deploy</phase>
</phases>

Clean Lifecycle phases

<phases>
  <phase>pre-clean</phase>
  <phase>clean</phase>
  <phase>post-clean</phase>
</phases>
<default-phases>
  <clean>
    org.apache.maven.plugins:maven-clean-plugin:2.5:clean
  </clean>
</default-phases>

Site Lifecycle phases

<phases>
  <phase>pre-site</phase>
  <phase>site</phase>
  <phase>post-site</phase>
  <phase>site-deploy</phase>
</phases>
<default-phases>
  <site>
    org.apache.maven.plugins:maven-site-plugin:3.3:site
  </site>
  <site-deploy>
    org.apache.maven.plugins:maven-site-plugin:3.3:deploy
  </site-deploy>
</default-phases>

See you that in default lifecycle there is not default-phases defined. It's because default phases to be executed in this lifecycle are specific defined for each packaging (ear, jar, war, rar, pom, etc). See default lifecycle bindings.

So, if you run 'mvn PHASE' eg. 'mvn install' you will execute default lifecycle INSTALL phase and all the preceding phases as well (this will execute all phases except those after the one defined 'install','deploy' will not be executed).

When you run 'mvn PLUGIN:GOAL' executes the defined plugin goal eg. 'mvn compiler:compile'. It will run all phases up to the defined phase (and all goals in those phases) including your defined goal.


There are a set of plugins that you can use to execute a OS command or a java process. Also there is a plugin to run Ant tasks that can be useful.

Mojo Exec plugin mojo exec plugin reference

Eg. Execution using command line:

mvn exec:java -Dexec.mainClass="com.example.Main" [-Dexec.args="argument1"] ...

Eg. Execution using a POM configuration:

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>exec-maven-plugin</artifactId>
        <version>1.6.0</version>
        <executions>
          <execution>
            ...
            <goals>
              <goal>java</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <mainClass>com.example.Main</mainClass>
          <arguments>
            <argument>argument1</argument>
            ...
          </arguments>
          <systemProperties>
            <systemProperty>
              <key>myproperty</key>
              <value>myvalue</value>
            </systemProperty>
            ...
          </systemProperties>
        </configuration>
      </plugin>
    </plugins>
  </build>
   ...
</project>

Maven Antrun plugin antrun plugin reference

Eg. POM configuration:

<project>
  ...
  <build>
    <!-- To define the plugin version in your parent POM -->
    <pluginManagement>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-antrun-plugin</artifactId>
          <version>1.8</version>
        </plugin>
        ...
      </plugins>
    </pluginManagement>
    <!-- To use the plugin goals in your POM or parent POM -->
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-antrun-plugin</artifactId>
        <version>1.8</version>
      </plugin>
      ...
    </plugins>
  </build>
  ...
</project>

The maven-antrun-plugin has only one goal, run.

Eg. command line execution:

mvn antrun:run

More about usage and how to define your Ant targets in pom.xml: usage

Antrun usage example

1 - Add plugin definition like this:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-antrun-plugin</artifactId>
    <version>1.8</version>
    <executions>
         <execution>
            <id>my-gen-stats-task</id>
            <phase>pre-site</phase>
            <goals>
                <goal>run</goal>
            </goals>
            <configuration>
                <target>
                    <ant antfile="${basedir}/build.xml">
                        <target name="gen-stats"/>
                    </ant>
                </target>
            </configuration>
        </execution>
    </executions>
    <dependencies>
        <dependency>
            <groupId>commons-net</groupId>
            <artifactId>commons-net</artifactId>
            <version>1.4.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.ant</groupId>
            <artifactId>ant-commons-net</artifactId>
            <version>1.8.1</version>
        </dependency>
    </dependencies>
</plugin>

2 - Execute your defined maven phase:

mvn pre-site

You can play with SITE lifecycle... Try this example and see how if you run 'mvn pre-site' only your ant tasks defined in 'pre-site' phase are executed. Try running 'mvn site' and see how 'pre-site' and 'site' tasks are executed:

Eg.

<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-antrun-plugin</artifactId>
                <version>1.8</version>
                <executions>
                    <execution>
                        <id>my-pre-site</id>
                        <phase>pre-site</phase>
                        <goals>
                            <goal>run</goal>
                        </goals>
                        <configuration>
                            <tasks>
                                <echo>PRE-SITE PHASE!!!</echo>
                            </tasks>
                        </configuration>
                    </execution>
                    <execution>
                        <id>my-site</id>
                        <phase>site</phase>
                        <goals>
                            <goal>run</goal>
                        </goals>
                        <configuration>
                            <tasks>
                                <echo>SITE PHASE!!!</echo>
                            </tasks>
                        </configuration>
                    </execution>
                    <execution>
                        <id>my-post-site</id>
                        <phase>post-site</phase>
                        <goals>
                            <goal>run</goal>
                        </goals>
                        <configuration>
                            <tasks>
                                <echo>POST-SITE PHASE!!!</echo>
                            </tasks>
                        </configuration>
                    </execution>
                    <execution>
                        <id>my-site-deploy</id>
                        <phase>site-deploy</phase>
                        <goals>
                            <goal>run</goal>
                        </goals>
                        <configuration>
                            <tasks>
                                <echo>SITE DEPLOY PHASE!!!</echo>
                            </tasks>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
</build>

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=139076&siteId=1