diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/AbstractJettyMojo.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/AbstractJettyMojo.java index 5b95c269622..df6a4788b3b 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/AbstractJettyMojo.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/AbstractJettyMojo.java @@ -211,21 +211,7 @@ public abstract class AbstractJettyMojo extends AbstractMojo */ protected boolean dumpOnStart; - /** - *
- * Determines whether or not the server blocks when started. The default - * behavior (daemon = false) will cause the server to pause other processes - * while it continues to handle web requests. This is useful when starting the - * server with the intent to work with it interactively. - *
- * Often, it is desirable to let the server start and continue running subsequent - * processes in an automated build environment. This can be facilitated by setting - * daemon to true. - *
- * - * @parameter expression="${jetty.daemon}" default-value="false" - */ - protected boolean daemon; + /** @@ -319,9 +305,20 @@ public abstract class AbstractJettyMojo extends AbstractMojo protected Thread consoleScanner; - - - + /** + *+ * Determines whether or not the server blocks when started. The default + * behavior (false) will cause the server to pause other processes + * while it continues to handle web requests. This is useful when starting the + * server with the intent to work with it interactively. This is the + * behaviour of the jetty:run, jetty:run-war, jetty:run-war-exploded goals. + *
+ * If true, the server will not block the execution of subsequent code. This + * is the behaviour of the jetty:start and default behaviour of the jetty:deploy goals. + *
+ */ + protected boolean nonblocking = false; + public abstract void restartWebApp(boolean reconfigureScanner) throws Exception; @@ -472,14 +469,8 @@ public abstract class AbstractJettyMojo extends AbstractMojo try { getLog().debug("Starting Jetty Server ..."); - - if(stopPort>0 && stopKey!=null) - { - ShutdownMonitor monitor = ShutdownMonitor.getInstance(); - monitor.setPort(stopPort); - monitor.setKey(stopKey); - monitor.setExitVm(!daemon); - } + + configureMonitor(); printSystemProperties(); @@ -558,7 +549,7 @@ public abstract class AbstractJettyMojo extends AbstractMojo startConsoleScanner(); // keep the thread going if not in daemon mode - if (!daemon ) + if (!nonblocking ) { server.join(); } @@ -569,7 +560,7 @@ public abstract class AbstractJettyMojo extends AbstractMojo } finally { - if (!daemon ) + if (!nonblocking ) { getLog().info("Jetty server exiting."); } @@ -577,6 +568,16 @@ public abstract class AbstractJettyMojo extends AbstractMojo } + public void configureMonitor() + { + if(stopPort>0 && stopKey!=null) + { + ShutdownMonitor monitor = ShutdownMonitor.getInstance(); + monitor.setPort(stopPort); + monitor.setKey(stopKey); + monitor.setExitVm(!nonblocking); + } + } /** diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyDeployWar.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyDeployWar.java index ff94f32d2d7..e4f6181c9bc 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyDeployWar.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyDeployWar.java @@ -18,6 +18,11 @@ package org.eclipse.jetty.maven.plugin; +import java.io.File; + +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; + /** ** This goal is used to run Jetty with a pre-assembled war. @@ -27,7 +32,7 @@ package org.eclipse.jetty.maven.plugin; * However, it doesn't assume that the current artifact is a * webapp and doesn't try to assemble it into a war before its execution. * So using it makes sense only when used in conjunction with the - * webApp configuration parameter pointing to a pre-built WAR. + * war configuration parameter pointing to a pre-built WAR. *
** This goal is useful e.g. for launching a web app in Jetty as a target for unit-tested @@ -42,4 +47,34 @@ package org.eclipse.jetty.maven.plugin; */ public class JettyDeployWar extends JettyRunWarMojo { + + + /** + * If true, the plugin should continue and not block. Otherwise the + * plugin will block further execution and you will need to use + * cntrl-c to stop it. + * + * + * @parameter default-value="true" + */ + protected boolean daemon = true; + + + @Override + public void execute() throws MojoExecutionException, MojoFailureException + { + nonblocking = daemon; + super.execute(); + } + + + + @Override + public void finishConfigurationBeforeStart() throws Exception + { + //only stop the server at shutdown if we are blocking + server.setStopAtShutdown(!nonblocking); + super.finishConfigurationBeforeStart(); + } + } diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunMojo.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunMojo.java index 130dd52504a..16185ab7908 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunMojo.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunMojo.java @@ -290,6 +290,16 @@ public class JettyRunMojo extends AbstractJettyMojo + @Override + public void finishConfigurationBeforeStart() throws Exception + { + server.setStopAtShutdown(true); //as we will normally be stopped with a cntrl-c, ensure server stopped + super.finishConfigurationBeforeStart(); + } + + + + /** * @see org.eclipse.jetty.maven.plugin.AbstractJettyMojo#configureWebApplication() */ diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunWarExplodedMojo.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunWarExplodedMojo.java index c5f2eb88a9e..2a055e3656f 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunWarExplodedMojo.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunWarExplodedMojo.java @@ -32,17 +32,13 @@ import org.eclipse.jetty.util.Scanner; * This goal is used to assemble your webapp into an exploded war and automatically deploy it to Jetty. *
*- * Once invoked, the plugin can be configured to run continuously, scanning for changes in the pom.xml and + * Once invoked, the plugin runs continuously, and can be configured to scan for changes in the pom.xml and * to WEB-INF/web.xml, WEB-INF/classes or WEB-INF/lib and hot redeploy when a change is detected. *
** You may also specify the location of a jetty.xml file whose contents will be applied before any plugin configuration. * This can be used, for example, to deploy a static webapp that is not part of your maven build. *
- *- * There is a reference guide to the configuration parameters for this plugin, and more detailed information - * with examples in the Configuration Guide. - *
* *@goal run-exploded *@requiresDependencyResolution compile+runtime @@ -56,7 +52,7 @@ public class JettyRunWarExplodedMojo extends AbstractJettyMojo /** * The location of the war file. * - * @parameter alias="webApp" expression="${project.build.directory}/${project.build.finalName}" + * @parameter expression="${project.build.directory}/${project.build.finalName}" * @required */ private File war; @@ -74,7 +70,14 @@ public class JettyRunWarExplodedMojo extends AbstractJettyMojo } - + + @Override + public void finishConfigurationBeforeStart() throws Exception + { + server.setStopAtShutdown(true); //as we will normally be stopped with a cntrl-c, ensure server stopped + super.finishConfigurationBeforeStart(); + } + /** * diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunWarMojo.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunWarMojo.java index 7fe9e71a03d..09881ab33d8 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunWarMojo.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunWarMojo.java @@ -31,18 +31,13 @@ import org.eclipse.jetty.util.Scanner; * This goal is used to assemble your webapp into a war and automatically deploy it to Jetty. * *- * Once invoked, the plugin can be configured to run continuously, scanning for changes in the project and to the - * war file and automatically performing a - * hot redeploy when necessary. + * Once invoked, the plugin runs continuously and can be configured to scan for changes in the project and to the + * war file and automatically perform a hot redeploy when necessary. *
** You may also specify the location of a jetty.xml file whose contents will be applied before any plugin configuration. * This can be used, for example, to deploy a static webapp that is not part of your maven build. *
- *- * There is a reference guide to the configuration parameters for this plugin, and more detailed information - * with examples in the Configuration Guide. - *
* * @goal run-war * @requiresDependencyResolution compile+runtime @@ -70,6 +65,13 @@ public class JettyRunWarMojo extends AbstractJettyMojo } + @Override + public void finishConfigurationBeforeStart() throws Exception + { + server.setStopAtShutdown(true); //as we will normally be stopped with a cntrl-c, ensure server stopped + super.finishConfigurationBeforeStart(); + } + public void configureWebApplication () throws Exception diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyServer.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyServer.java index 3e60e1008b3..cd7b3c3cae3 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyServer.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyServer.java @@ -43,9 +43,7 @@ import org.eclipse.jetty.xml.XmlConfiguration; * */ public class JettyServer extends org.eclipse.jetty.server.Server -{ - public static final JettyServer __instance = new JettyServer(); - +{ private RequestLog requestLog; private ContextHandlerCollection contexts; @@ -57,7 +55,6 @@ public class JettyServer extends org.eclipse.jetty.server.Server public JettyServer() { super(); - setStopAtShutdown(true); //make sure Jetty does not use URLConnection caches with the plugin Resource.setDefaultUseCaches(false); } diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyStartMojo.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyStartMojo.java index 42e9c74f102..8189d4616c4 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyStartMojo.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyStartMojo.java @@ -18,6 +18,9 @@ package org.eclipse.jetty.maven.plugin; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; + /** *
@@ -37,4 +40,20 @@ package org.eclipse.jetty.maven.plugin;
*/
public class JettyStartMojo extends JettyRunMojo
{
+
+ @Override
+ public void execute() throws MojoExecutionException, MojoFailureException
+ {
+ nonblocking = true; //ensure that starting jetty won't hold up the thread
+ super.execute();
+ }
+
+
+ @Override
+ public void finishConfigurationBeforeStart() throws Exception
+ {
+ super.finishConfigurationBeforeStart();
+ server.setStopAtShutdown(false); //as we will normally be stopped with a cntrl-c, ensure server stopped
+ }
+
}
diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyStopMojo.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyStopMojo.java
index 80c530cf2fc..a5890b48f96 100644
--- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyStopMojo.java
+++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyStopMojo.java
@@ -63,6 +63,10 @@ public class JettyStopMojo extends AbstractMojo
*/
protected int stopWait;
+
+
+
+
public void execute() throws MojoExecutionException, MojoFailureException
{
@@ -71,13 +75,17 @@ public class JettyStopMojo extends AbstractMojo
if (stopKey == null)
throw new MojoExecutionException("Please specify a valid stopKey");
+ //Ensure jetty Server instance stops. Whether or not the remote process
+ //also stops depends whether or not it was started with ShutdownMonitor.exitVm=true
+ String command = "forcestop";
+
try
{
Socket s=new Socket(InetAddress.getByName("127.0.0.1"),stopPort);
s.setSoLinger(false, 0);
OutputStream out=s.getOutputStream();
- out.write((stopKey+"\r\nstop\r\n").getBytes());
+ out.write((stopKey+"\r\n"+command+"\r\n").getBytes());
out.flush();
if (stopWait > 0)
diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/Starter.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/Starter.java
index 574259a882c..63e49c97342 100644
--- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/Starter.java
+++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/Starter.java
@@ -178,7 +178,6 @@ public class Starter
this.server.addWebApplication(webApp);
- System.err.println("STOP PORT="+stopPort+", STOP KEY="+stopKey);
if(stopPort>0 && stopKey!=null)
{
ShutdownMonitor monitor = ShutdownMonitor.getInstance();
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java
index ce4bdd9097c..38cea332fba 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java
@@ -18,7 +18,6 @@
package org.eclipse.jetty.server;
-import java.awt.geom.PathIterator;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.net.InetAddress;
@@ -54,7 +53,6 @@ import org.eclipse.jetty.util.AttributesMap;
import org.eclipse.jetty.util.Jetty;
import org.eclipse.jetty.util.MultiException;
import org.eclipse.jetty.util.URIUtil;
-import org.eclipse.jetty.util.UrlEncoded;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.annotation.Name;
@@ -145,7 +143,8 @@ public class Server extends HandlerWrapper implements Attributes
{
return _stopAtShutdown;
}
-
+
+
/* ------------------------------------------------------------ */
/**
* Set a graceful stop time.
@@ -313,11 +312,16 @@ public class Server extends HandlerWrapper implements Attributes
@Override
protected void doStart() throws Exception
{
+ //If the Server should be stopped when the jvm exits, register
+ //with the shutdown handler thread.
if (getStopAtShutdown())
- {
ShutdownThread.register(this);
- }
+ //Register the Server with the handler thread for receiving
+ //remote stop commands
+ ShutdownMonitor.register(this);
+
+ //Start a thread waiting to receive "stop" commands.
ShutdownMonitor.getInstance().start(); // initialize
LOG.info("jetty-" + getVersion());
@@ -455,6 +459,11 @@ public class Server extends HandlerWrapper implements Attributes
if (getStopAtShutdown())
ShutdownThread.deregister(this);
+
+ //Unregister the Server with the handler thread for receiving
+ //remote stop commands as we are stopped already
+ ShutdownMonitor.deregister(this);
+
mex.ifExceptionThrow();
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ShutdownMonitor.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ShutdownMonitor.java
index 38b866574da..861c0198888 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/ShutdownMonitor.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ShutdownMonitor.java
@@ -26,8 +26,15 @@ import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.List;
import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.CopyOnWriteArraySet;
+import org.eclipse.jetty.util.component.Destroyable;
+import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.util.thread.ShutdownThread;
/**
@@ -42,6 +49,8 @@ import org.eclipse.jetty.util.thread.ShutdownThread;
*/
public class ShutdownMonitor
{
+ private final Set