Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maven jetty plugin - automatic reload using a multi-module project

I am developing a Java web application, using a multi-module maven project. The project setup is the following:

  • pom.xml Main maven project, that includes the following modules:
    • persistence: Entity classes and DAOs
    • business: Service definition and implementation
    • webapp: Apache wicket web application

The dependency hierarchy is the following: webapp depends on business, which depends on persistence.

I am also using the Jetty Maven Plugin to run the web application locally using mvn -pl webapp jetty:run inside the directory with the main pom.xml. When developing the application, When making code changes, I want the jetty server to restart and reload the modified code files automatically. This works fine when I am modifying files inside the webapp module, but does not work when I am modifying a file inside another module, such persistence or business.

The Maven Jetty Plugin is configured inside webapp/pom.xml as follows:

<plugin>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-maven-plugin</artifactId>
    <version>9.2.2.v20140723</version>
    <configuration>
        <reload>automatic</reload>
        <scanIntervalSeconds>1</scanIntervalSeconds>
        <webApp>
            <extraClasspath>../business/target/classes/;../persistence/target/classes/</extraClasspath>
        </webApp>
        <scanTargets>
            <scanTarget>../business/target/classes</scanTarget>
            <scanTarget>../persistence/target/classes</scanTarget>
        </scanTargets>
</plugin>

I followed the instructions of this answer. The <scanTarget> tags work fine, since jetty gets restarted when I modify a file inside business or persistence. However, the <extraClasspath> does not work since the modified files are not loaded by jetty. The linked answer uses the <webAppConfig> tag. However, I am using the <webApp> tag as specified in the documentation of the plugin (I also tried the old <webAppConfig> tag, which lead to the same results).

My question is: How to configure the Jetty Maven Plugin for a multi-module project, such that it reloads modified files from other modules?

like image 327
Gaste Avatar asked Sep 08 '14 13:09

Gaste


3 Answers

To force the reload anytime a submodule is changed you can use the following options

1 - Static module names and scan targets

You can define as scan targets the target directory for each module

<plugin>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-maven-plugin</artifactId>
    <version>${jetty.plugin.version}</version>
    <configuration>
        <scanIntervalSeconds>${jetty.scanInterval}</scanIntervalSeconds>
        <scanTargets>
            <scanTarget>module-name/target/classes</scanTarget>
            <scanTarget>module-name2/target/classes</scanTarget>
        </scanTargets>
    </configuration>
</plugin>

2 - Dinamic module names and scan targets (recommended) This uses RegEx to find the compilation target for other modules, on the following example, we are reloading the application everytime a class is compiled on any module

<plugin>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-maven-plugin</artifactId>
    <version>${jetty.plugin.version}</version>
    <configuration>
        <scanIntervalSeconds>${jetty.scanInterval}</scanIntervalSeconds>
        <scanTargetPatterns>
            <scanTargetPattern>
                <directory>${project.basedir}</directory>
                <includes>
                    <include>**/target/classes/**/*.class</include>
                </includes>
            </scanTargetPattern>
        </scanTargetPatterns>
    </configuration>
</plugin>
like image 154
Valdo Raya Avatar answered Nov 09 '22 14:11

Valdo Raya


Using trial and error, I found a solution. The problem is that jetty is executed using from the parent pom using

mvn -pl webapp jetty:run

The command is called from the directory of the main pom, thus jetty cannot resolve the relative paths inside the extraClasspath correctly. When executing the jetty:run goal inside the webapp directory, all modified classes are loaded correctly.


I assume the scanTargets are working correctly even when using mvn -pl webapp jetty:run, because the relative paths get resolved during the execution of the plugin (with the correct working directory). Jetty outputs the scan targets on startup:

[INFO] Added extra scan target:C:\PathToProject\business\target\classes
[INFO] Added extra scan target:C:\PathToProject\persistence\target\classes

However, the <extraClasspath>property is part of the <webApp> property, which is an instance of the org.eclipse.jetty.webapp.WebAppContext class. I assume that this instance is passed to jetty directly and that the extraClasspath property is accessed by jetty when it is already started.

like image 43
Gaste Avatar answered Nov 09 '22 16:11

Gaste


The following configuration works for me

    <!-- To launch embded jetty server -->
<plugin>
    <groupId>org.mortbay.jetty</groupId>
    <artifactId>jetty-maven-plugin</artifactId>
    <version>7.4.2.v20110526</version>


    <configuration>
        <scanIntervalSeconds>3</scanIntervalSeconds>
        <webAppConfig>
            <contextPath>/${project.name}</contextPath>
            <extraClasspath>target/classes;../services/target/classes;../util/target/classes</extraClasspath>
        </webAppConfig>
        <scanTargets>
            <scanTarget>target/classes</scanTarget>
            <scanTarget>../services/target/classes</scanTarget>
            <scanTarget>../util/target/classes</scanTarget>
        </scanTargets>
    </configuration>

</plugin>
like image 3
Skizzo Avatar answered Nov 09 '22 15:11

Skizzo