Multi-module Maven project and jetty:run

15,300

Solution 1

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>

Solution 2

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>

Solution 3

Using extraClasspath in jetty configuration works... but for some reason, if dependant jars (from other modules) are outdated some things won't work correctly.

Solution 4

Add jetty plugin to the root pom and configure a contextHandler pointing to the desired war. This works for me in a project with multiple jar modules and two overlay wars.

<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.3.0.M2</version>
<configuration>
        <scanIntervalSeconds>10</scanIntervalSeconds>
        <contextHandlers>
            <contextHandler
                implementation="org.eclipse.jetty.maven.plugin.JettyWebAppContext">
                <war>${project.basedir}/project-war/target/project-war-${project.version}.war</war>
                <contextPath>/</contextPath>
            </contextHandler>
        </contextHandlers>
    </configuration>
</plugin>

http://eclipse.org/jetty/documentation/current/jetty-maven-plugin.html#running-more-than-one-webapp

Share:
15,300
Lukáš Lalinský
Author by

Lukáš Lalinský

I'm programming since I was a little kid and I still love every aspect of it. I was always fascinated by music and liked messing with audio programming, which started when I got access to C64 for the first time. A few years back I created the AcoustID audio recognition service and I worked on many music-related open source projects (MusicBrainz, TagLib, etc.).

Updated on June 15, 2022

Comments

  • Lukáš Lalinský
    Lukáš Lalinský about 2 years

    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?

  • Lukáš Lalinský
    Lukáš Lalinský almost 14 years
    Hm, this doesn't actually help me, because it fails with a BUILD error "Failed to resolve artifact." (the sibling JAR project) before the Jetty plugin even gets executed. So it seems I need a general solution for Maven in the first place. :(
  • Devanshu Mevada
    Devanshu Mevada almost 14 years
    @Lukáš Maven uses the local repository to resolve dependencies so they must be installed (i.e. you need to install all modules first by running a reactor build on the parent at least once). Then the above will work, even if the installed JARs are "outdated".
  • Lukáš Lalinský
    Lukáš Lalinský almost 14 years
    Ah, I was hoping to avoid that. One alternative I found out was setting the jetty plugin on the parent and pointing it to the right war file (and then use jetty:run-war), but I'll probably need to run install anyway to make NetBeans happy.
  • Patrick Cornelissen
    Patrick Cornelissen almost 13 years
    can you write how you managed to tell jetty where the modules war file resides?