Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multi-module Maven project and jetty:run

I'm trying to split a Maven WAR project into two modules, so that I can build a separate JAR file with command line tools. The result has the following structure:

  • pom.xml (packaging pom, has two modules)
  • project-jar/
    • pom.xml (packaging jar)
  • project-war/
    • pom.xml (packaging war, depends on project-jar)

If I run mvn commands from the root, everything works fine. I'd like to keep using mvn jetty:run, but for that I need to execute the command in the WAR subproject. If I do that, fails to find the project-jar subproject, so it won't run. Even mvn jetty:run-war with a completely assembled WAR file in the target directory fails, because it first tries to "build" the project. I've only managed to make it work by installing project-jar into the local Maven repository, which isn't very nice.

Is there a way to use the Jetty plugin in a multi-module Maven configuration?

like image 644
Lukáš Lalinský Avatar asked Sep 03 '10 14:09

Lukáš Lalinský


People also ask

What does Mvn jetty run do?

Jetty continues to run until you stop it. While it runs, it periodically scans for changes to your project files, so if you save changes and recompile your class files, Jetty redeploys your webapp, and you can instantly test the changes you just made.

What is the use of multi-module project in maven?

A multi-module project is built from an aggregator POM that manages a group of submodules. In most cases, the aggregator is located in the project's root directory and must have packaging of type pom. The submodules are regular Maven projects, and they can be built separately or through the aggregator POM.

What is the difference between maven module and maven project?

a maven module is like a maven "sub-project". a maven project includes 1 or more modules. more info here. Typically, a module generates a single artifact (jar, war, zip, etc), although this is not always true.


2 Answers

Create a profile inside the war module (project-war). Within this profile, configure jetty to attach to a lifecycle phase and execute the run goal explicitly. Now when maven runs from the toplevel project with that profile enabled, it will invoke jetty:run and have sister module dependency resolution (as is normal when executing maven commands from the toplevel project).

The example configuration, when placed in the pom.xml of the web module (project-war), arranges for jetty:run to execute during the test phase. (You may choose another phase, but make sure it's after compile.)

Run from toplevel: mvn test -Pjetty-run or mvn test -DskipTests=true -Pjetty-run. This will compile dependencies as required and make them available but invoke jetty:run within the correct module.

<profiles>   ...   <!-- With this profile, jetty will run during the "test" phase -->   <profile>     <id>jetty-run</id>     <build>       <plugins>         <plugin>           <groupId>org.mortbay.jetty</groupId>           <artifactId>jetty-maven-plugin</artifactId>           <version>7.1.6.v20100715</version>           <configuration>             ...             <webAppSourceDirectory>               ${project.build.directory}/${project.build.finalName}             </webAppSourceDirectory>             ...           </configuration>           <executions>             <execution>               <id>jetty-run</id>               <phase>test</phase>               <goals>                 <goal>run</goal>               </goals>             </execution>           </executions>         </plugin>       </plugins>     </build>   </profile> ... </profiles> 
like image 78
Patrick Avatar answered Oct 05 '22 13:10

Patrick


There is no magical solution and the only one I know is a bit hacky and rely on the extraClasspath element that you can use to declare extra class directories, relatively. Like this (from JETTY-662):

<plugin>   <groupId>org.mortbay.jetty</groupId>   <artifactId>jetty-maven-plugin</artifactId>   <version>7.0.1.v20091125</version>   <configuration>     <scanIntervalSeconds>10</scanIntervalSeconds>     <webAppConfig>       <contextPath>/my-context</contextPath>       <extraClasspath>target/classes;../my-jar-dependency/target/classes</extraClasspath>     </webAppConfig>     <scanTargets>       <scanTarget>../my-jar-dependency/target/classes</scanTarget>     </scanTargets>   </configuration> </plugin> 
like image 42
Pascal Thivent Avatar answered Oct 05 '22 14:10

Pascal Thivent