Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maven exec:java goal on a multi-module project

I'm trying to run exec-maven-plugin's exec:java goal on a simple two-module project where one module depends on the other. So far I can't find a configuration that works. Here's a boiled-down test case:

+ exec-multi-module-test/     + pom.xml     + module1/         + pom.xml         + src/             + main/                 + java/                     + HelloPrinter.java     + module2/         + pom.xml         + src/             + main/                 + java/                     + MyMain.java 

Here's the parent pom:

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">     <modelVersion>4.0.0</modelVersion>      <groupId>com.mkscrg.sandbox</groupId>     <artifactId>exec-multi-module-test</artifactId>     <version>1.0</version>     <packaging>pom</packaging>      <modules>         <module>module1</module>         <module>module2</module>     </modules>      <build>         <plugins>             <plugin>                 <groupId>org.codehaus.mojo</groupId>                 <artifactId>exec-maven-plugin</artifactId>                 <version>1.2.1</version>             </plugin>         </plugins>     </build> </project> 

module1's pom:

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">     <modelVersion>4.0.0</modelVersion>      <parent>         <artifactId>exec-multi-module-test</artifactId>         <groupId>com.mkscrg.sandbox</groupId>         <version>1.0</version>     </parent>      <artifactId>module1</artifactId> </project> 

module2's pom: 4.0.0

    <parent>         <artifactId>exec-multi-module-test</artifactId>         <groupId>com.mkscrg.sandbox</groupId>         <version>1.0</version>     </parent>      <artifactId>module2</artifactId>      <dependencies>         <dependency>             <groupId>com.mkscrg.sandbox</groupId>             <artifactId>module1</artifactId>             <version>${project.version}</version>         </dependency>     </dependencies> </project> 

This project compiles successfully from the top, but running mvn exec:java -Dexec.mainClass=myMain fails:

[INFO] Scanning for projects... [INFO] ------------------------------------------------------------------------ [INFO] Reactor Build Order: [INFO]  [INFO] exec-multi-module-test [INFO] module1 [INFO] module2 [INFO]                                                                          [INFO] ------------------------------------------------------------------------ [INFO] Building exec-multi-module-test 1.0 [INFO] ------------------------------------------------------------------------ [INFO]  [INFO] >>> exec-maven-plugin:1.2.1:java (default-cli) @ exec-multi-module-test >>> [INFO]  [INFO] <<< exec-maven-plugin:1.2.1:java (default-cli) @ exec-multi-module-test <<< [INFO]  [INFO] --- exec-maven-plugin:1.2.1:java (default-cli) @ exec-multi-module-test --- [WARNING]  java.lang.ClassNotFoundException: MyMain         at java.net.URLClassLoader$1.run(URLClassLoader.java:202)         at java.security.AccessController.doPrivileged(Native Method)         at java.net.URLClassLoader.findClass(URLClassLoader.java:190)         at java.lang.ClassLoader.loadClass(ClassLoader.java:306)         at java.lang.ClassLoader.loadClass(ClassLoader.java:247)         at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:285)         at java.lang.Thread.run(Thread.java:680) [INFO] ------------------------------------------------------------------------ [INFO] Reactor Summary: [INFO]  [INFO] exec-multi-module-test ............................ FAILURE [0.363s] [INFO] module1 ........................................... SKIPPED [INFO] module2 ........................................... SKIPPED [INFO] ------------------------------------------------------------------------ [INFO] BUILD FAILURE [INFO] ------------------------------------------------------------------------ [INFO] Total time: 0.566s [INFO] Finished at: Mon Jun 18 14:11:54 PDT 2012 [INFO] Final Memory: 3M/81M [INFO] ------------------------------------------------------------------------ [ERROR] Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.2.1:java (default-cli) on project exec-multi-module-test: An exception occured while executing the Java class. MyMain -> [Help 1] [ERROR]  [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch. [ERROR] Re-run Maven using the -X switch to enable full debug logging. [ERROR]  [ERROR] For more information about the errors and possible solutions, please read the following articles: [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException 

What's the right way to configure this project to allow exec:java to see MyMain?

EDIT: Here's a gist if you'd like to try this yourself: https://gist.github.com/2950830

EDIT: Clarification: I know it's possible to mvn install and then either run exec:java from module2's directory or use the -pl flag from the top. However, I'd like to avoid running mvn install. It shouldn't be necessary to modify my local repository in order to run this goal in a multi-module project. Just as mvn compile "just works" with a multi-module project, so should other goals/phases.

like image 432
Mike Craig Avatar asked Jun 18 '12 21:06

Mike Craig


People also ask

What is exec Java in maven?

Maven exec plugin allows us to execute system and Java programs from the maven command. There are two goals of the maven exec plugin: exec:exec – can be used to execute any program in a separate process. exec:java – can be used to run a Java program in the same VM.

Does maven support multi project build?

Maven's Multi-Module ProjectThe submodules are regular Maven projects, and they can be built separately or through the aggregator POM. By building the project through the aggregator POM, each project that has a packaging type different from pom will result in a built archive file.


2 Answers

Goals in a multi-module project, when run from the parent, will run against all modules. I don't think that's what you want. You can try:

mvn exec:java -pl module2 -Dexec.mainClass=MyMain 

That might work? More info:

  • Running a specific Maven plugin goal from the command line in a sub-module of a multi-module reactor project

However, I think it's more intuitive to change directory to the sub-module containing the executable before running it.

like image 83
kaliatech Avatar answered Sep 19 '22 07:09

kaliatech


  • You should bind the exec-maven-plugin to a maven lifecycle goal, say verify.
  • Since you want the plugin to be executed only for module2, define the plugin configurations in the parent pom within pluginManagement. Use the same only in module 2.
  • Then run the following:

mvn verify -Dexec.mainClass=MyMain.

parent pom

<build>     <pluginManagement>         <plugins>             <plugin>                 <groupId>org.codehaus.mojo</groupId>                 <artifactId>exec-maven-plugin</artifactId>                 <version>1.2.1</version>                 <executions>                  <execution>                      <phase>verify</phase>                      <goals>                          <goal>java</goal>                      </goals>                  </execution>                 </executions>             </plugin>         </plugins>     </pluginManagement> </build> 

module 2

<build>     <plugins>         <plugin>             <groupId>org.codehaus.mojo</groupId>             <artifactId>exec-maven-plugin</artifactId>         </plugin>     </plugins> </build> 
like image 31
Raghuram Avatar answered Sep 19 '22 07:09

Raghuram