Jetty

Support running jetty:run-war goal without assembling the WAR of the current module (after specifying existing WAR with webApp)

Details

  • Type: Improvement Improvement
  • Status: Resolved Resolved
  • Priority: Major Major
  • Resolution: Fixed
  • Affects Version/s: None
  • Fix Version/s: 6.1.15.pre0
  • Component/s: Maven
  • Labels:
    None
  • Number of attachments :
    1

Description

According to http://jetty.mortbay.org/jetty/maven-plugin/run-war-mojo.html one can specify any WAR file to be deployed in Jetty using the webApp parameter to the run-war goal.

However, it also states:

"This goal is used to assemble your webapp into a war and automatically deploy it to Jetty."

It seems that there's currently no way to prevent it from forking a build lifecycle that tries to make the WAR out of the current artifact.

There are situations where this is undesirable.

For example, suppose we have a HTTP client application and we want to unit test it against a real life webapp deployed on a real server.

Similarly to the integration testing scenario, described on http://docs.codehaus.org/display/JETTY/Maven+Jetty+Plugin, we could use jetty-maven-plugin for this task, by binding execution of the "run-war" goal e.g. to the "process-test-classes" phase and the "stop" goal to "test" phase (it should run after the actual tests). Jetty would run in daemon mode using a prebuild WAR file (e.g. placed in the testResources directory).

The problem is that currently Jetty invokes a forked build of the current artifact (intended to assemble a WAR), and that build runs the unit tests, and Jetty run-war only starts afterwards, when the tests (requiring Jetty) have already failed.

It should be possible to completely prevent forking that WAR assembling build. Maybe an optional goal parameter, like "assembleWar", defaulting to "true".

Activity

Hide
Aleksander Adamowski added a comment -

OK, I've checked that this seems to be impossible without creating a separate goal, as the forked lifecycles are hardcoded in generated plugin.xml (the <executePhase> element, generated from the "@execute phase=PHASE_NAME" annotation on the corresponding Mojo class).

The Jetty6RunWar class (http://www.mortbay.org/jetty/jetty-7/xref/org/mortbay/jetty/plugin/Jetty6RunWar.html) has @execute phase="package".

So I've made a simple test by making a copy of the whole class, named Jetty6RunWarNoFork, with only slightly changed annotations and building jetty-maven-plugin:

Show
Aleksander Adamowski added a comment - OK, I've checked that this seems to be impossible without creating a separate goal, as the forked lifecycles are hardcoded in generated plugin.xml (the <executePhase> element, generated from the "@execute phase=PHASE_NAME" annotation on the corresponding Mojo class). The Jetty6RunWar class (http://www.mortbay.org/jetty/jetty-7/xref/org/mortbay/jetty/plugin/Jetty6RunWar.html) has @execute phase="package". So I've made a simple test by making a copy of the whole class, named Jetty6RunWarNoFork, with only slightly changed annotations and building jetty-maven-plugin:
Hide
Aleksander Adamowski added a comment -

Ooops, submitted comment prematurely by mistake. Continuing previous comment:

original Jetty6RunWar.java:

...

  • @goal run-war
  • @requiresDependencyResolution runtime
  • @execute phase="package"
  • @description Runs jetty6 on a war file
    *
    */
    public class Jetty6RunWar extends AbstractJetty6Mojo
    {
    ...

New Jetty6RunWarNoFork.java (note the changed goal name and execute phase):

...
/**

  • <p>
  • This goal is used to run Jetty with an already assembled war.
  • </p>
  • @goal run-war-nofork
  • @requiresDependencyResolution runtime
  • @execute phase="validate"
  • @description Runs jetty6 on a war file
    *
    */
    public class Jetty6RunWarNoFork extends AbstractJetty6Mojo
    ...

With that new goal, my project's integration tests run fine - Jetty is started before the tests and closed shortly after they finish. The execution configuration of jetty-maven-plugin is:

<executions>

<execution>
<id>start-jetty</id>
<phase>test-compile</phase>
<goals>
<goal>run-war-nofork</goal>
</goals>
<configuration>
<scanIntervalSeconds>0</scanIntervalSeconds>
<daemon>true</daemon>
<reload>manual</reload>
</configuration>
</execution>

<execution>
<id>stop-jetty</id>
<phase>test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>

</executions>

I think this improvement deserves integrating into official jetty-maven-plugin release.

However, making a copy of the whole class's code seems unreasonable and messy.

Maybe inheritance from Jetty6RunWar mojo?

Does the parent mojo class have to be abstract or can we make "public class Jetty6RunWarNoFork extends Jetty6RunWar"?

Show
Aleksander Adamowski added a comment - Ooops, submitted comment prematurely by mistake. Continuing previous comment: original Jetty6RunWar.java: ...
  • @goal run-war
  • @requiresDependencyResolution runtime
  • @execute phase="package"
  • @description Runs jetty6 on a war file * */ public class Jetty6RunWar extends AbstractJetty6Mojo { ...
New Jetty6RunWarNoFork.java (note the changed goal name and execute phase): ... /**
  • <p>
  • This goal is used to run Jetty with an already assembled war.
  • </p>
  • @goal run-war-nofork
  • @requiresDependencyResolution runtime
  • @execute phase="validate"
  • @description Runs jetty6 on a war file * */ public class Jetty6RunWarNoFork extends AbstractJetty6Mojo ...
With that new goal, my project's integration tests run fine - Jetty is started before the tests and closed shortly after they finish. The execution configuration of jetty-maven-plugin is: <executions> <execution> <id>start-jetty</id> <phase>test-compile</phase> <goals> <goal>run-war-nofork</goal> </goals> <configuration> <scanIntervalSeconds>0</scanIntervalSeconds> <daemon>true</daemon> <reload>manual</reload> </configuration> </execution> <execution> <id>stop-jetty</id> <phase>test</phase> <goals> <goal>stop</goal> </goals> </execution> </executions> I think this improvement deserves integrating into official jetty-maven-plugin release. However, making a copy of the whole class's code seems unreasonable and messy. Maybe inheritance from Jetty6RunWar mojo? Does the parent mojo class have to be abstract or can we make "public class Jetty6RunWarNoFork extends Jetty6RunWar"?
Hide
Aleksander Adamowski added a comment -

Proposed patch - using inheritance from Jetty6RunWar.

Implements the run-war-nofork goal.

I tested it on my machine and it seems to work properly.

Show
Aleksander Adamowski added a comment - Proposed patch - using inheritance from Jetty6RunWar. Implements the run-war-nofork goal. I tested it on my machine and it seems to work properly.
Hide
David Yu added a comment -

This will be added ... but with a different name(Jetty6DeployWar) and goal (deploy-war).

Show
David Yu added a comment - This will be added ... but with a different name(Jetty6DeployWar) and goal (deploy-war).
Hide
David Yu added a comment -

Available for jetty6&7. (See org.mortbay.jetty.plugin.Jetty6DeployWar)

Show
David Yu added a comment - Available for jetty6&7. (See org.mortbay.jetty.plugin.Jetty6DeployWar)

People

Vote (0)
Watch (1)

Dates

  • Created:
    Updated:
    Resolved: