How do I execute a program using Maven?

Maven 2Maven Plugin

Maven 2 Problem Overview


I would like to have a Maven goal trigger the execution of a java class. I'm trying to migrate over a Makefile with the lines:

neotest:
    mvn exec:java -Dexec.mainClass="org.dhappy.test.NeoTraverse"

And I would like mvn neotest to produce what make neotest does currently.

Neither the http://mojo.codehaus.org/exec-maven-plugin/usage.html">exec plugin documentation nor the http://maven.apache.org/ant-tasks/">Maven Ant tasks pages had any sort of straightforward example.

Currently, I'm at:

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>exec-maven-plugin</artifactId>
  <version>1.1</version>
  <executions><execution>
    <goals><goal>java</goal></goals>
  </execution></executions>
  <configuration>
    <mainClass>org.dhappy.test.NeoTraverse</mainClass>
  </configuration>
</plugin>

I don't know how to trigger the plugin from the command line, though.

Maven 2 Solutions


Solution 1 - Maven 2

With the global configuration that you have defined for the exec-maven-plugin:

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>exec-maven-plugin</artifactId>
  <version>1.4.0</version>
  <configuration>
    <mainClass>org.dhappy.test.NeoTraverse</mainClass>
  </configuration>
</plugin>

invoking mvn exec:java on the command line will invoke the plugin which is configured to execute the class org.dhappy.test.NeoTraverse.

So, to trigger the plugin from the command line, just run:

mvn exec:java

Now, if you want to execute the exec:java goal as part of your standard build, you'll need to bind the goal to a particular phase of the default lifecycle. To do this, declare the phase to which you want to bind the goal in the execution element:

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>exec-maven-plugin</artifactId>
  <version>1.4</version>
  <executions>
    <execution>
      <id>my-execution</id>
      <phase>package</phase>
      <goals>
        <goal>java</goal>
      </goals>
    </execution>
  </executions>
  <configuration>
    <mainClass>org.dhappy.test.NeoTraverse</mainClass>
  </configuration>
</plugin>

With this example, your class would be executed during the package phase. This is just an example, adapt it to suit your needs. Works also with plugin version 1.1.

Solution 2 - Maven 2

In order to execute multiple programs, I also needed a profiles section:

<profiles>
  <profile>
    <id>traverse</id>
    <activation>
      <property>
        <name>traverse</name>
      </property>
    </activation>
    <build>
      <plugins>
        <plugin>
          <groupId>org.codehaus.mojo</groupId>
          <artifactId>exec-maven-plugin</artifactId>
          <configuration>
            <executable>java</executable>
            <arguments>
              <argument>-classpath</argument>
              <argument>org.dhappy.test.NeoTraverse</argument>
            </arguments>
          </configuration>
        </plugin>
      </plugins>
    </build>
  </profile>
</profiles>

This is then executable as:

mvn exec:exec -Ptraverse

Solution 3 - Maven 2

Better use maven-antrun-plugin. It allows to call what you want using more flexible way. If you need to get it (tool and all required dependencies) appeared in class path just add it as plugin dependencies. Such dependencies will not be picked up during final jar building (if you build it). They are added to maven.plugin.classpath for plugin execution only. I remember that we have some troubles with maven-exec plugin. It was able to find only dependencies added as dependencies for whole pom file and didn't want to use plugin's runtime dependencies (something like that). Anyway stop talking let's go through the example below:

<artifactId>maven-antrun-plugin</artifactId>
<dependencies>
	<dependency>
		<groupId>x.y.z.codegen</groupId>
		<artifactId>Generator-Project</artifactId>
		<version>${generator.project.version}</version>
	</dependency>
</dependencies>
<executions>
	<execution>
		<id>Code generation</id>
		<phase>generate-sources</phase>
		<configuration>
			<target>
				<parallel threadsPerProcessor="2">
					<java classname="x.y.z.codegen.ObjectModelCodeGenerator" fork="true" failonerror="true">
						<classpath>
							<path refid="maven.plugin.classpath"/>
						</classpath>
						<jvmarg value="-Duser.dir=${generator.root}"/>
						<arg value="arg1"/>
						<arg value="arg2"/>
						<arg value="arg3"/>
					</java>
					<java classname="x.y.z.codegen.ObjectModelCodeGenerator" fork="true" failonerror="true">
						<classpath>
							<path refid="maven.plugin.classpath"/>
						</classpath>
						<jvmarg value="-Duser.dir=${generator.root}"/>
						<arg value="arg1"/>
						<arg value="arg2"/>
						<arg value="arg3"/>
					</java>
				</parallel>
			</target>
		</configuration>
		<goals>
			<goal>run</goal>
		</goals>
	</execution>
  </executions>

P.s. You can see that I use parallel execution here. It can be done if your tool can be called in parallel. Such possibility exists for maven-antrun-plugin 1.8 but was lot for much recent versions. Means that parallel execution doesn't happen.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiondysbulicView Question on Stackoverflow
Solution 1 - Maven 2Pascal ThiventView Answer on Stackoverflow
Solution 2 - Maven 2dysbulicView Answer on Stackoverflow
Solution 3 - Maven 2Ilya RosmanView Answer on Stackoverflow