diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/AbstractForker.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/AbstractForker.java
index 09313e7e3a9..28d1e4ebb64 100644
--- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/AbstractForker.java
+++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/AbstractForker.java
@@ -64,7 +64,9 @@ public abstract class AbstractForker extends AbstractLifeCycle
protected File workDir;
-
+ protected abstract ProcessBuilder createCommand();
+ protected abstract void redeployWebApp() throws Exception;
+
public File getWorkDir()
{
return workDir;
@@ -204,8 +206,6 @@ public abstract class AbstractForker extends AbstractLifeCycle
{
this.tokenFile = tokenFile;
}
-
- public abstract ProcessBuilder createCommand();
public void doStart ()
diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/AbstractWebAppMojo.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/AbstractWebAppMojo.java
index 8fa21e1b4a7..84617a0722c 100644
--- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/AbstractWebAppMojo.java
+++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/AbstractWebAppMojo.java
@@ -274,7 +274,7 @@ public abstract class AbstractWebAppMojo extends AbstractMojo
*
*
*/
- @Parameter (property="jetty.runType", defaultValue="INPROCESS")
+ @Parameter (property="jetty.runType", defaultValue="EMBED")
protected RunTypes runType;
@@ -462,7 +462,7 @@ public abstract class AbstractWebAppMojo extends AbstractMojo
}
- public void startJetty()
+ protected void startJetty()
throws MojoExecutionException, MojoFailureException
{
try
@@ -498,15 +498,15 @@ public abstract class AbstractWebAppMojo extends AbstractMojo
}
- public abstract void startJettyEmbedded() throws MojoExecutionException;
+ protected abstract void startJettyEmbedded() throws MojoExecutionException;
- public abstract void startJettyForked() throws MojoExecutionException;
+ protected abstract void startJettyForked() throws MojoExecutionException;
- public abstract void startJettyDistro() throws MojoExecutionException;
+ protected abstract void startJettyDistro() throws MojoExecutionException;
- public JettyEmbedder newJettyEmbedder()
+ protected JettyEmbedder newJettyEmbedder()
throws Exception
{
JettyEmbedder jetty = new JettyEmbedder();
@@ -531,8 +531,8 @@ public abstract class AbstractWebAppMojo extends AbstractMojo
- public JettyForker newJettyForker()
- throws Exception
+ protected JettyForker newJettyForker()
+ throws Exception
{
JettyForker jetty = new JettyForker();
@@ -564,7 +564,7 @@ public abstract class AbstractWebAppMojo extends AbstractMojo
}
- public JettyDistroForker newJettyDistroForker()
+ protected JettyDistroForker newJettyDistroForker()
throws Exception
{
JettyDistroForker jetty = new JettyDistroForker();
@@ -605,10 +605,10 @@ public abstract class AbstractWebAppMojo extends AbstractMojo
jetty.setLibExtJarFiles(libExtJars);
}
- jetty.setWebApp(webApp);
+ jetty.setWebApp(webApp);
jetty.setContextXmlFile(new File(contextXml));
- if (jettyHome == null)
+ if (jettyHome == null)
jetty.setJettyDistro(resolve(JETTY_HOME_GROUPID, JETTY_HOME_ARTIFACTID, plugin.getVersion(), "zip"));
jetty.setJettyHome(jettyHome);
@@ -658,7 +658,7 @@ public abstract class AbstractWebAppMojo extends AbstractMojo
/**
* @return
*/
- public List getProjectDependencyFiles()
+ private List getProjectDependencyFiles()
{
List dependencyFiles = new ArrayList<>();
for ( Iterator iter = projectArtifacts.iterator(); iter.hasNext(); )
@@ -693,7 +693,7 @@ public abstract class AbstractWebAppMojo extends AbstractMojo
}
- public MavenProject getProjectReferences( Artifact artifact, MavenProject project )
+ private MavenProject getProjectReferences( Artifact artifact, MavenProject project )
{
if ( project.getProjectReferences() == null || project.getProjectReferences().isEmpty() )
{
@@ -710,7 +710,7 @@ public abstract class AbstractWebAppMojo extends AbstractMojo
return null;
}
- public List getOverlays()
+ protected List getOverlays()
throws Exception
{
//get copy of a list of war artifacts
@@ -756,7 +756,7 @@ public abstract class AbstractWebAppMojo extends AbstractMojo
}
- public void unpackOverlays (List overlays)
+ private void unpackOverlays (List overlays)
throws Exception
{
if (overlays == null || overlays.isEmpty())
@@ -795,7 +795,7 @@ public abstract class AbstractWebAppMojo extends AbstractMojo
- public Resource unpackOverlay (Overlay overlay)
+ private Resource unpackOverlay (Overlay overlay)
throws IOException
{
if (overlay.getResource() == null)
@@ -834,7 +834,7 @@ public abstract class AbstractWebAppMojo extends AbstractMojo
/**
* @return
*/
- public List getWarArtifacts ()
+ protected List getWarArtifacts ()
{
if (warArtifacts != null)
return warArtifacts;
@@ -859,7 +859,7 @@ public abstract class AbstractWebAppMojo extends AbstractMojo
return warArtifacts;
}
- protected Artifact getArtifactForOverlay (OverlayConfig o, List warArtifacts)
+ private Artifact getArtifactForOverlay (OverlayConfig o, List warArtifacts)
{
if (o == null || warArtifacts == null || warArtifacts.isEmpty())
return null;
@@ -881,7 +881,7 @@ public abstract class AbstractWebAppMojo extends AbstractMojo
*
*
*/
- public void verifyPomConfiguration () throws MojoExecutionException
+ protected void verifyPomConfiguration () throws MojoExecutionException
{
// check the location of the static content/jsps etc
try
@@ -930,7 +930,7 @@ public abstract class AbstractWebAppMojo extends AbstractMojo
}
- public void configureSystemProperties ()
+ protected void configureSystemProperties ()
throws MojoExecutionException
{
//Apply the file first
@@ -954,6 +954,7 @@ public abstract class AbstractWebAppMojo extends AbstractMojo
{
for (Map.Entry e:systemProperties.entrySet())
{
+ System.err.println(e.getKey() + " " + e.getValue());
System.setProperty(e.getKey(), e.getValue());
}
}
@@ -965,7 +966,7 @@ public abstract class AbstractWebAppMojo extends AbstractMojo
*
* @throws MojoExecutionException
*/
- public void augmentPluginClasspath() throws MojoExecutionException
+ protected void augmentPluginClasspath() throws MojoExecutionException
{
//Filter out ones that will clash with jars that are plugin dependencies, then
//create a new classloader that we setup in the parent chain.
@@ -990,7 +991,7 @@ public abstract class AbstractWebAppMojo extends AbstractMojo
}
}
- public List getProvidedJars() throws MojoExecutionException
+ protected List getProvidedJars() throws MojoExecutionException
{
//if we are configured to include the provided dependencies on the plugin's classpath
//(which mimics being on jetty's classpath vs being on the webapp's classpath), we first
@@ -1011,7 +1012,7 @@ public abstract class AbstractWebAppMojo extends AbstractMojo
return null;
}
- public String getContainerClassPath() throws Exception
+ protected String getContainerClassPath() throws Exception
{
//Add in all the plugin artifacts
StringBuilder classPath = new StringBuilder();
@@ -1053,7 +1054,7 @@ public abstract class AbstractWebAppMojo extends AbstractMojo
* @param artifact to check
* @return true if it is a plugin dependency, false otherwise
*/
- public boolean isPluginArtifact(Artifact artifact)
+ protected boolean isPluginArtifact(Artifact artifact)
{
if (pluginArtifacts == null || pluginArtifacts.isEmpty())
return false;
@@ -1076,7 +1077,7 @@ public abstract class AbstractWebAppMojo extends AbstractMojo
* @param goal the goal to check
* @return true if the goal is excluded, false otherwise
*/
- public boolean isExcludedGoal (String goal)
+ protected boolean isExcludedGoal (String goal)
{
if (excludedGoals == null || goal == null)
return false;
@@ -1096,7 +1097,7 @@ public abstract class AbstractWebAppMojo extends AbstractMojo
}
- public void configureWebApp ()
+ protected void configureWebApp ()
throws Exception
{
if (webApp == null)
@@ -1207,7 +1208,7 @@ public abstract class AbstractWebAppMojo extends AbstractMojo
* @param webInfDir the web inf directory
* @return the jetty web xml file
*/
- public File findJettyWebXmlFile (File webInfDir)
+ protected File findJettyWebXmlFile (File webInfDir)
{
if (webInfDir == null)
return null;
diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/ConsoleReader.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/ConsoleReader.java
new file mode 100644
index 00000000000..d3800ebb069
--- /dev/null
+++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/ConsoleReader.java
@@ -0,0 +1,69 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+//
+
+
+package org.eclipse.jetty.maven.plugin;
+
+import java.io.Console;
+import java.util.EventListener;
+import java.util.HashSet;
+import java.util.Set;
+
+
+public class ConsoleReader implements Runnable
+{
+
+ public interface Listener extends EventListener
+ {
+ public void consoleEvent (String line);
+ }
+
+ public Set listeners = new HashSet<>();
+
+ public void addListener(ConsoleReader.Listener listener)
+ {
+ listeners.add(listener);
+ }
+
+ public void removeListener(ConsoleReader.Listener listener)
+ {
+ listeners.remove(listener);
+ }
+
+ public void run()
+ {
+ Console console = System.console();
+ if (console == null)
+ return;
+
+ String line ="";
+ while (true && line != null)
+ {
+ line = console.readLine("Hit to redeploy:");
+ if (line != null)
+ signalEvent(line);
+ }
+ }
+
+
+ public void signalEvent(String line)
+ {
+ for (ConsoleReader.Listener l:listeners)
+ l.consoleEvent(line);
+ }
+}
\ No newline at end of file
diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyDistroForker.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyDistroForker.java
index 167c85e30da..83311b7bf36 100644
--- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyDistroForker.java
+++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyDistroForker.java
@@ -45,6 +45,9 @@ import org.eclipse.jetty.util.resource.Resource;
/**
* JettyDistroForker
+ *
+ * Unpacks a jetty distribution and configures it with a base that allows it
+ * to run an unassembled webapp.
*
*/
public class JettyDistroForker extends AbstractForker
@@ -59,7 +62,6 @@ public class JettyDistroForker extends AbstractForker
*/
protected File jettyHome;
-
/**
* Zip of jetty distro
*/
@@ -68,25 +70,17 @@ public class JettyDistroForker extends AbstractForker
/**
* Location of existing jetty base directory
*/
-
protected File jettyBase;
-
-
-
-
+
protected File baseDir;
-
/**
* Optional list of other modules to
* activate.
*/
-
protected String[] modules;
-
- protected List libExtJarFiles;
-
+ protected List libExtJarFiles;
protected Path modulesPath;
protected Path etcPath;
protected Path libPath;
@@ -155,31 +149,6 @@ public class JettyDistroForker extends AbstractForker
this.jettyDistro = jettyDistro;
}
- public void configureJettyHome ()
- throws Exception
- {
- if (jettyHome == null && jettyDistro == null)
- throw new IllegalStateException ("No jettyDistro");
-
- if (baseDir == null)
- throw new IllegalStateException ("No baseDir");
-
- if (jettyHome == null)
- {
- JarResource res = (JarResource) JarResource.newJarResource(Resource.newResource(jettyDistro));
- res.copyTo(baseDir);
- //zip will unpack to target/jetty-home-
- String name = jettyDistro.getName();
- int i = name.lastIndexOf('.');
- name = (i>0?name.substring(0, i):"distro");
- jettyHome = new File (baseDir, name);
-
- System.err.println("JETTY HOME = "+jettyHome);
- }
- }
-
-
-
public JettyWebAppContext getWebApp()
{
return webApp;
@@ -204,7 +173,7 @@ public class JettyDistroForker extends AbstractForker
* @see org.eclipse.jetty.maven.plugin.AbstractForker#createCommand()
*/
@Override
- public ProcessBuilder createCommand()
+ protected ProcessBuilder createCommand()
{
List cmd = new ArrayList<>();
cmd.add("java");
@@ -288,20 +257,31 @@ public class JettyDistroForker extends AbstractForker
configureJettyBase();
//convert the webapp to properties
- WebAppPropertyConverter.toProperties(webApp, etcPath.resolve("maven.props").toFile(), contextXmlFile.getAbsolutePath());
+ generateWebAppPropertiesFile();
super.doStart();
}
-
-
-
+
+ protected void redeployWebApp()
+ throws Exception
+ {
+ generateWebAppPropertiesFile();
+ webappPath.resolve("maven.xml").toFile().setLastModified(System.currentTimeMillis());
+ }
+
+ private void generateWebAppPropertiesFile()
+ throws Exception
+ {
+ WebAppPropertyConverter.toProperties(webApp, etcPath.resolve("maven.props").toFile(), contextXmlFile.getAbsolutePath());
+ }
+
/**
* Create or configure a jetty base.
*
* @throws Exception
*/
- public void configureJettyBase() throws Exception
+ private void configureJettyBase() throws Exception
{
if (jettyBase != null && !jettyBase.exists())
throw new IllegalStateException(jettyBase.getAbsolutePath() +" does not exist");
@@ -315,7 +295,7 @@ public class JettyDistroForker extends AbstractForker
//jetty-base will be the working directory for the forked command
workDir = targetJettyBase;
-
+
//if there is an existing jetty base, copy parts of it
if (jettyBase != null)
{
@@ -413,4 +393,27 @@ public class JettyDistroForker extends AbstractForker
}
}
}
+
+ private void configureJettyHome ()
+ throws Exception
+ {
+ if (jettyHome == null && jettyDistro == null)
+ throw new IllegalStateException ("No jettyDistro");
+
+ if (baseDir == null)
+ throw new IllegalStateException ("No baseDir");
+
+ if (jettyHome == null)
+ {
+ JarResource res = (JarResource) JarResource.newJarResource(Resource.newResource(jettyDistro));
+ res.copyTo(baseDir);
+ //zip will unpack to target/jetty-home-
+ String name = jettyDistro.getName();
+ int i = name.lastIndexOf('.');
+ name = (i>0?name.substring(0, i):"distro");
+ jettyHome = new File (baseDir, name);
+
+ System.err.println("JETTY HOME = "+jettyHome);
+ }
+ }
}
diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyEmbedder.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyEmbedder.java
index 0c13cef7c35..f394af62c60 100644
--- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyEmbedder.java
+++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyEmbedder.java
@@ -82,175 +82,137 @@ public class JettyEmbedder extends AbstractLifeCycle
return contextHandlers;
}
-
public void setContextHandlers(ContextHandler[] contextHandlers)
{
this.contextHandlers = contextHandlers;
}
-
public LoginService[] getLoginServices()
{
return loginServices;
}
-
public void setLoginServices(LoginService[] loginServices)
{
this.loginServices = loginServices;
}
-
public RequestLog getRequestLog()
{
return requestLog;
}
-
public void setRequestLog(RequestLog requestLog)
{
this.requestLog = requestLog;
}
-
public MavenServerConnector getHttpConnector()
{
return httpConnector;
}
-
public void setHttpConnector(MavenServerConnector httpConnector)
{
this.httpConnector = httpConnector;
}
-
public Server getServer()
{
return server;
}
-
public void setServer(Server server)
{
this.server = server;
}
-
public JettyWebAppContext getWebApp()
{
return webApp;
}
-
public boolean isExitVm()
{
return exitVm;
}
-
public void setExitVm(boolean exitVm)
{
this.exitVm = exitVm;
}
-
public boolean isStopAtShutdown()
{
return stopAtShutdown;
}
-
public void setStopAtShutdown(boolean stopAtShutdown)
{
this.stopAtShutdown = stopAtShutdown;
}
-
public List getJettyXmlFiles()
{
return jettyXmlFiles;
}
-
public void setJettyXmlFiles(List jettyXmlFiles)
{
this.jettyXmlFiles = jettyXmlFiles;
}
-
-
-
public Map getJettyProperties()
{
return jettyProperties;
}
-
-
-
public void setJettyProperties(Map jettyProperties)
{
this.jettyProperties = jettyProperties;
}
-
-
-
public ShutdownMonitor getShutdownMonitor()
{
return shutdownMonitor;
}
-
-
-
public void setShutdownMonitor(ShutdownMonitor shutdownMonitor)
{
this.shutdownMonitor = shutdownMonitor;
}
-
-
-
public int getStopPort()
{
return stopPort;
}
-
-
-
public void setStopPort(int stopPort)
{
this.stopPort = stopPort;
}
-
-
-
public String getStopKey()
{
return stopKey;
}
-
-
-
public void setStopKey(String stopKey)
{
this.stopKey = stopKey;
}
-
-
-
public Properties getWebAppProperties()
{
return webAppProperties;
}
-
-
+
+ public void setWebApp (JettyWebAppContext app, Properties properties)
+ throws Exception
+ {
+ webApp = app;
+ webAppProperties = properties;
+ }
public void doStart()
throws Exception
@@ -266,14 +228,22 @@ public class JettyEmbedder extends AbstractLifeCycle
server.start();
}
- public void join()
+ protected void redeployWebApp()
+ throws Exception
+ {
+ webApp.stop();
+ //regenerate config properties
+ applyWebAppProperties();
+ webApp.start();
+ }
+
+ protected void join()
throws InterruptedException
{
server.join();
}
-
/**
* Configure the server and the webapp
* @throws Exception
@@ -304,14 +274,13 @@ public class JettyEmbedder extends AbstractLifeCycle
// set up security realms
ServerSupport.configureLoginServices(server, loginServices);
-
+
/* Configure the webapp */
if (webApp == null)
webApp = new JettyWebAppContext();
-
- //apply properties to the webapp if there are any
- WebAppPropertyConverter.fromProperties(webApp, webAppProperties, server, jettyProperties);
-
+
+ applyWebAppProperties();
+
//TODO- this might be duplicating WebAppPropertyConverter. make it a quickstart if the quickstart-web.xml file exists
if (webApp.getTempDirectory() != null)
{
@@ -319,22 +288,19 @@ public class JettyEmbedder extends AbstractLifeCycle
if (qs.exists() && qs.isFile())
webApp.setQuickStartWebDescriptor(Resource.newResource(qs));
}
-
+
//add the webapp to the server
ServerSupport.addWebApplication(server, webApp);
System.err.println("ADDED WEBAPP TO SERVER");
}
-
- public void setWebApp (JettyWebAppContext app, Properties properties)
- throws Exception
+ private void applyWebAppProperties () throws Exception
{
- webApp = app;
- webAppProperties = properties;
+ //apply properties to the webapp if there are any
+ WebAppPropertyConverter.fromProperties(webApp, webAppProperties, server, jettyProperties);
}
-
-
+
private void configureShutdownMonitor ()
{
if(stopPort>0 && stopKey!=null)
diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyForkedChild.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyForkedChild.java
index cce39cd9871..14fb3ac22ad 100644
--- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyForkedChild.java
+++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyForkedChild.java
@@ -21,14 +21,21 @@ package org.eclipse.jetty.maven.plugin;
import java.io.File;
import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Properties;
+import org.eclipse.jetty.util.PathWatcher;
+import org.eclipse.jetty.util.PathWatcher.PathWatchEvent;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.resource.Resource;
/**
@@ -39,8 +46,12 @@ import org.eclipse.jetty.util.resource.Resource;
*/
public class JettyForkedChild extends AbstractLifeCycle
{
+ private static final Logger LOG = Log.getLogger(JettyForkedChild.class);
+
protected JettyEmbedder jetty;
protected File tokenFile;
+ protected PathWatcher scanner;
+ protected File webAppPropsFile;
public JettyForkedChild (String[] args)
throws Exception
@@ -89,10 +100,8 @@ public class JettyForkedChild extends AbstractLifeCycle
//--webprops
if ("--webprops".equals(args[i]))
{
- File webAppPropsFile = new File(args[++i].trim());
- Properties props = new Properties();
- props.load(new FileInputStream(webAppPropsFile));
- jetty.setWebApp(null, props);
+ webAppPropsFile = new File(args[++i].trim());
+ jetty.setWebApp(null, loadWebAppProps());
System.err.println("WEBPROPS="+webAppPropsFile);
continue;
}
@@ -114,10 +123,18 @@ public class JettyForkedChild extends AbstractLifeCycle
jettyProperties.put(tmp[0], tmp[1]);
}
}
-
+
jetty.setJettyProperties(jettyProperties);
jetty.setExitVm(true);
}
+
+ private Properties loadWebAppProps () throws FileNotFoundException, IOException
+ {
+ Properties props = new Properties();
+ if (Objects.nonNull(webAppPropsFile))
+ props.load(new FileInputStream(webAppPropsFile));
+ return props;
+ }
public void doStart()
throws Exception
@@ -131,13 +148,49 @@ public class JettyForkedChild extends AbstractLifeCycle
Resource r = Resource.newResource(tokenFile);
r.getFile().createNewFile();
- //TODO start a PathWatcher for the webapp props file and/or the quickstart.xml file
- // when differences are seen, get the webapp from the jettyembedder:
- // stop webapp
- // reconfigure the properties on it
- // (name of quickstart file can't change, but contents can, but we don't need to do anything here)
- // start webapp
+ //Start a watcher on a file that will change if the
+ //webapp is regenerated; stop the webapp, apply the
+ //properties and restart it.
+ scanner = new PathWatcher();
+ scanner.setNotifyExistingOnStart(false);
+ scanner.addListener(new PathWatcher.EventListListener()
+ {
+ @Override
+ public void onPathWatchEvents(List events)
+ {
+ if (!Objects.isNull(scanner))
+ {
+ try
+ {
+ scanner.stop();
+ if (!Objects.isNull(jetty.getWebApp()))
+ {
+ //stop the webapp
+ jetty.getWebApp().stop();
+ //reload the props
+ jetty.setWebApp(jetty.getWebApp(), loadWebAppProps());
+
+ //restart the webapp
+ jetty.getWebApp().start();
+
+ //restart the scanner
+ scanner.start();
+ }
+ }
+ catch (Exception e)
+ {
+ LOG.warn("Error restarting webapp", e);
+ }
+ }
+ }
+ });
+
+ if (!Objects.isNull(webAppPropsFile))
+ scanner.watch(webAppPropsFile.toPath());
+
+
+ scanner.start();
//wait for jetty to finish
jetty.join();
diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyForker.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyForker.java
index 356c0eaf63a..ab60655fb6c 100644
--- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyForker.java
+++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyForker.java
@@ -43,6 +43,7 @@ import org.eclipse.jetty.util.thread.QueuedThreadPool;
/**
* JettyForker
*
+ * Uses quickstart to generate a webapp and forks a process to run it.
*/
public class JettyForker extends AbstractForker
{
@@ -121,20 +122,14 @@ public class JettyForker extends AbstractForker
throws Exception
{
//Run the webapp to create the quickstart file and properties file
- generateQuickStart();
+ prepareWebApp();
super.doStart();
}
- protected void generateQuickStart()
+ private void prepareWebApp()
throws Exception
{
- if (forkWebXml == null)
- throw new IllegalStateException ("No forkWebXml");
-
- if (webAppPropsFile == null)
- throw new IllegalStateException ("no webAppsPropsFile");
-
if (server == null)
server = new Server();
@@ -163,26 +158,52 @@ public class JettyForker extends AbstractForker
//add webapp to our fake server instance
ServerSupport.addWebApplication(server, webApp);
+
+ //leave everything unpacked for the forked process to use
+ webApp.setPersistTempDirectory(true);
+
+ generateQuickStart();
+ }
+
+ protected void redeployWebApp ()
+ throws Exception
+ {
+ //regenerating the quickstart will be noticed by the JettyForkedChild process
+ //which will redeploy the webapp
+ generateQuickStart();
+ }
+
+ private void generateQuickStart()
+ throws Exception
+ {
+ if (forkWebXml == null)
+ throw new IllegalStateException ("No forkWebXml");
+
+ if (webAppPropsFile == null)
+ throw new IllegalStateException ("no webAppsPropsFile");
//if our server has a thread pool associated we can do annotation scanning multithreaded,
//otherwise scanning will be single threaded
QueuedThreadPool tpool = server.getBean(QueuedThreadPool.class);
- if (tpool != null)
- tpool.start();
- else
- webApp.setAttribute(AnnotationConfiguration.MULTI_THREADED, Boolean.FALSE.toString());
- //leave everything unpacked for the forked process to use
- webApp.setPersistTempDirectory(true);
+ try
+ {
+ if (tpool != null)
+ tpool.start();
+ else
+ webApp.setAttribute(AnnotationConfiguration.MULTI_THREADED, Boolean.FALSE.toString());
- webApp.start(); //just enough to generate the quickstart
+ webApp.start(); //just enough to generate the quickstart
- //save config of the webapp BEFORE we stop
- WebAppPropertyConverter.toProperties(webApp, webAppPropsFile, webAppProperties.getProperty("context.xml"));
-
- webApp.stop();
- if (tpool != null)
- tpool.stop();
+ //save config of the webapp BEFORE we stop
+ WebAppPropertyConverter.toProperties(webApp, webAppPropsFile, webAppProperties.getProperty("context.xml"));
+ }
+ finally
+ {
+ webApp.stop();
+ if (tpool != null)
+ tpool.stop();
+ }
}
diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/NewJettyRunMojo.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/NewJettyRunMojo.java
index 0c23c8a35eb..a24ca2bdf75 100644
--- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/NewJettyRunMojo.java
+++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/NewJettyRunMojo.java
@@ -19,13 +19,9 @@
package org.eclipse.jetty.maven.plugin;
-import java.io.Console;
import java.io.File;
import java.util.Date;
-import java.util.EventListener;
-import java.util.HashSet;
import java.util.List;
-import java.util.Set;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.plugin.MojoExecutionException;
@@ -35,6 +31,7 @@ import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
+import org.eclipse.jetty.maven.plugin.ConsoleReader;
import org.eclipse.jetty.util.PathWatcher;
import org.eclipse.jetty.util.PathWatcher.PathWatchEvent;
import org.eclipse.jetty.util.resource.Resource;
@@ -59,8 +56,6 @@ import org.eclipse.jetty.webapp.WebAppContext;
@Execute (phase = LifecyclePhase.TEST_COMPILE)
public class NewJettyRunMojo extends AbstractWebAppMojo
{
-
-
//Start of parameters only valid for runType=inprocess
/**
* The interval in seconds to pause before checking if changes
@@ -75,105 +70,34 @@ public class NewJettyRunMojo extends AbstractWebAppMojo
* Scanner to check for files changes to cause redeploy
*/
protected PathWatcher scanner;
+
+ /**
+ * Only one of the following will be used, depending the mode
+ * the mojo is started in: EMBED, FORK, DISTRO
+ */
+ protected JettyEmbedder embedder;
+ protected JettyForker forker;
+ protected JettyDistroForker distroForker;
-
-
- public static class ConsoleReader implements Runnable
- {
-
- public interface Listener extends EventListener
- {
- public void consoleEvent (String line);
- }
-
- public Set listeners = new HashSet<>();
-
- public void addListener(Listener listener)
- {
- listeners.add(listener);
- }
-
- public void removeListener(Listener listener)
- {
- listeners.remove(listener);
- }
-
- public void run()
- {
- Console console = System.console();
- if (console == null)
- return;
-
- String line ="";
- while (true && line != null)
- {
- line = console.readLine("Hit to redeploy:");
- if (line != null)
- signalEvent(line);
- }
- }
-
-
- public void signalEvent(String line)
- {
- for (Listener l:listeners)
- l.consoleEvent(line);
- }
- }
-
@Override
public void execute() throws MojoExecutionException, MojoFailureException
{
super.execute();
}
-
-
-
-
@Override
public void startJettyEmbedded() throws MojoExecutionException
{
try
{
//start jetty
- JettyEmbedder jetty = newJettyEmbedder();
- jetty.setExitVm(true);
- jetty.setStopAtShutdown(true);
- jetty.start();
-
- // start scanning for changes, or wait for linefeed on stdin
- if (scan > 0)
- {
- scanner = new PathWatcher();
- configureScanner ();
- scanner.setNotifyExistingOnStart(false);
- scanner.start();
- }
- else
- {
- ConsoleReader creader = new ConsoleReader();
- creader.addListener(new ConsoleReader.Listener()
- {
- @Override
- public void consoleEvent(String line)
- {
- try
- {
- restartWebApp(false);
- }
- catch (Exception e)
- {
- getLog().debug(e);
- }
- }
- });
- Thread cthread = new Thread(creader, "ConsoleReader");
- cthread.setDaemon(true);
- cthread.start();
- }
- jetty.join();
+ embedder = newJettyEmbedder();
+ embedder.setExitVm(true);
+ embedder.setStopAtShutdown(true);
+ embedder.start();
+ startScanner();
+ embedder.join();
}
catch (Exception e)
{
@@ -181,20 +105,19 @@ public class NewJettyRunMojo extends AbstractWebAppMojo
}
}
-
-
-
-
-
-
@Override
public void startJettyForked() throws MojoExecutionException
{
try
{
- JettyForker jetty = newJettyForker();
- jetty.setWaitForChild(true); //we run at the command line, echo child output and wait for it
- jetty.start(); //forks jetty instance
+ forker = newJettyForker();
+ forker.setWaitForChild(true); //we run at the command line, echo child output and wait for it
+
+ startScanner();
+
+ //TODO is it ok to start the scanner before we start jetty?
+
+ forker.start(); //forks jetty instance
}
catch (Exception e)
@@ -203,18 +126,17 @@ public class NewJettyRunMojo extends AbstractWebAppMojo
}
}
-
-
-
-
@Override
public void startJettyDistro() throws MojoExecutionException
{
try
{
- JettyDistroForker jetty = newJettyDistroForker();
- jetty.setWaitForChild(true); //we always run at the command line, echo child output and wait for it
- jetty.start(); //forks a jetty distro
+ distroForker = newJettyDistroForker();
+ distroForker.setWaitForChild(true); //we always run at the command line, echo child output and wait for it
+ startScanner();
+ distroForker.start(); //forks a jetty distro
+
+ //TODO is it ok to start the scanner before we start jetty?
}
catch (Exception e)
{
@@ -222,9 +144,42 @@ public class NewJettyRunMojo extends AbstractWebAppMojo
}
}
+ private void startScanner ()
+ throws Exception
+ {
+ // start scanning for changes, or wait for linefeed on stdin
+ if (scan > 0)
+ {
+ scanner = new PathWatcher();
+ configureScanner ();
+ scanner.setNotifyExistingOnStart(false);
+ scanner.start();
+ }
+ else
+ {
+ ConsoleReader creader = new ConsoleReader();
+ creader.addListener(new ConsoleReader.Listener()
+ {
+ @Override
+ public void consoleEvent(String line)
+ {
+ try
+ {
+ restartWebApp(false);
+ }
+ catch (Exception e)
+ {
+ getLog().debug(e);
+ }
+ }
+ });
+ Thread cthread = new Thread(creader, "ConsoleReader");
+ cthread.setDaemon(true);
+ cthread.start();
+ }
+ }
-
- public void configureScanner ()
+ protected void configureScanner ()
throws MojoExecutionException
{
try
@@ -238,7 +193,6 @@ public class NewJettyRunMojo extends AbstractWebAppMojo
scanner.addListener(new PathWatcher.EventListListener()
{
-
@Override
public void onPathWatchEvents(List events)
{
@@ -382,7 +336,7 @@ public class NewJettyRunMojo extends AbstractWebAppMojo
/**
* @see org.eclipse.jetty.maven.plugin.AbstractJettyMojo#restartWebApp(boolean)
*/
- public void restartWebApp(boolean reconfigureScanner) throws Exception
+ public void restartWebApp(boolean reconfigure) throws Exception
{
getLog().info("Restarting "+webApp);
getLog().debug("Stopping webapp ...");
@@ -393,15 +347,12 @@ public class NewJettyRunMojo extends AbstractWebAppMojo
{
case EMBED:
{
- webApp.stop();
-
getLog().debug("Reconfiguring webapp ...");
verifyPomConfiguration();
- configureWebApp();
// check if we need to reconfigure the scanner,
// which is if the pom changes
- if (reconfigureScanner)
+ if (reconfigure)
{
getLog().info("Reconfiguring scanner after change to pom.xml ...");
scanner.reset();
@@ -409,28 +360,27 @@ public class NewJettyRunMojo extends AbstractWebAppMojo
configureScanner();
}
- webApp.start();
+ configureWebApp();
+ embedder.redeployWebApp();
scanner.start();
getLog().info("Restart completed at "+new Date().toString());
+
break;
}
case FORK:
{
verifyPomConfiguration();
-
- //TODO regenerate the webapp configuration!!!!!!
-
-
- if (reconfigureScanner)
+ if (reconfigure)
{
getLog().info("Reconfiguring scanner after change to pom.xml ...");
scanner.reset();
- warArtifacts = null;
+ warArtifacts = null; ///TODO if the pom changes for the forked case, how would we get the forked process to stop and restart?
configureScanner();
}
- //TODO signal to forked child to restart webapp (done by regenerating webapp
-
+ configureWebApp();
+ //regenerate with new config and restart the webapp
+ forker.redeployWebApp();
//restart scanner
scanner.start();
@@ -439,19 +389,17 @@ public class NewJettyRunMojo extends AbstractWebAppMojo
case DISTRO:
{
verifyPomConfiguration();
-
- //TODO regenerate the webapp configuration!!!!!!
-
- if (reconfigureScanner)
+ if (reconfigure)
{
getLog().info("Reconfiguring scanner after change to pom.xml ...");
scanner.reset();
- warArtifacts = null; //???
+ warArtifacts = null; //TODO if there are any changes to the pom, then we would have to tell the
+ //existing forked distro process to stop, then rerun the configuration and then refork - too complicated??!
configureScanner();
}
-
- //TODO signal to distro to restart webapp (done by regenerating webapp???!)
-
+ configureWebApp();
+ //regenerate the webapp and redeploy it
+ distroForker.redeployWebApp();
//restart scanner
scanner.start();
diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/NewJettyRunWarMojo.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/NewJettyRunWarMojo.java
index 7638d257f7d..7a7362f7150 100644
--- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/NewJettyRunWarMojo.java
+++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/NewJettyRunWarMojo.java
@@ -19,18 +19,15 @@
package org.eclipse.jetty.maven.plugin;
-import java.io.Console;
import java.io.File;
-import java.util.EventListener;
-import java.util.HashSet;
+import java.util.Date;
import java.util.List;
-import java.util.Set;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Execute;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
-import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.eclipse.jetty.util.PathWatcher;
import org.eclipse.jetty.util.PathWatcher.PathWatchEvent;
@@ -48,7 +45,7 @@ import org.eclipse.jetty.util.PathWatcher.PathWatchEvent;
*
* Runs jetty on a war file
*/
-@Mojo( name = "run-war", requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME)
+@Mojo( name = "newrun-war", requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME)
@Execute(phase = LifecyclePhase.PACKAGE)
public class NewJettyRunWarMojo extends AbstractWebAppMojo
{
@@ -74,52 +71,9 @@ public class NewJettyRunWarMojo extends AbstractWebAppMojo
* Scanner to check for files changes to cause redeploy
*/
protected PathWatcher scanner;
-
-
-
-
- public static class ConsoleReader implements Runnable
- {
-
- public interface Listener extends EventListener
- {
- public void consoleEvent (String line);
- }
-
- public Set listeners = new HashSet<>();
-
- public void addListener(Listener listener)
- {
- listeners.add(listener);
- }
-
- public void removeListener(Listener listener)
- {
- listeners.remove(listener);
- }
-
- public void run()
- {
- Console console = System.console();
- if (console == null)
- return;
-
- String line ="";
- while (true && line != null)
- {
- line = console.readLine("Hit to redeploy:");
- if (line != null)
- signalEvent(line);
- }
- }
-
-
- public void signalEvent(String line)
- {
- for (Listener l:listeners)
- l.consoleEvent(line);
- }
- }
+ protected JettyEmbedder embedder;
+ protected JettyForker forker;
+ protected JettyDistroForker distroForker;
/**
@@ -131,8 +85,6 @@ public class NewJettyRunWarMojo extends AbstractWebAppMojo
{
return null;
}
-
-
@Override
public void configureWebApp() throws Exception
@@ -141,9 +93,7 @@ public class NewJettyRunWarMojo extends AbstractWebAppMojo
webApp.setWar(war.getCanonicalPath());
}
-
-
- /* (non-Javadoc)
+ /**
*
*/
@Override
@@ -152,42 +102,14 @@ public class NewJettyRunWarMojo extends AbstractWebAppMojo
try
{
//start jetty
- JettyEmbedder jetty = newJettyEmbedder();
- jetty.setExitVm(true);
- jetty.setStopAtShutdown(true);
- jetty.start();
+ embedder = newJettyEmbedder();
+ embedder.setExitVm(true);
+ embedder.setStopAtShutdown(true);
+ embedder.start();
- // start scanning for changes, or wait for linefeed on stdin
- if (scan > 0)
- {
- scanner = new PathWatcher();
- configureScanner ();
- scanner.setNotifyExistingOnStart(false);
- scanner.start();
- }
- else
- {
- ConsoleReader creader = new ConsoleReader();
- creader.addListener(new ConsoleReader.Listener()
- {
- @Override
- public void consoleEvent(String line)
- {
- try
- {
- restartWebApp(false);
- }
- catch (Exception e)
- {
- getLog().debug(e);
- }
- }
- });
- Thread cthread = new Thread(creader, "ConsoleReader");
- cthread.setDaemon(true);
- cthread.start();
- }
- jetty.join();
+
+
+ embedder.join();
}
catch (Exception e)
{
@@ -195,24 +117,85 @@ public class NewJettyRunWarMojo extends AbstractWebAppMojo
}
}
- /* (non-Javadoc)
- *
+ public void startScanner()
+ throws Exception
+ {
+ // start scanning for changes, or wait for linefeed on stdin
+ if (scan > 0)
+ {
+ scanner = new PathWatcher();
+ configureScanner ();
+ scanner.setNotifyExistingOnStart(false);
+ scanner.start();
+ }
+ else
+ {
+ ConsoleReader creader = new ConsoleReader();
+ creader.addListener(new ConsoleReader.Listener()
+ {
+ @Override
+ public void consoleEvent(String line)
+ {
+ try
+ {
+ restartWebApp(false);
+ }
+ catch (Exception e)
+ {
+ getLog().debug(e);
+ }
+ }
+ });
+ Thread cthread = new Thread(creader, "ConsoleReader");
+ cthread.setDaemon(true);
+ cthread.start();
+ }
+ }
+
+ /**
+ * Fork a jetty instance to run the war
*/
@Override
public void startJettyForked() throws MojoExecutionException
{
- // TODO Auto-generated method stub
+ try
+ {
+ forker = newJettyForker();
+ forker.setWaitForChild(true); //we run at the command line, echo child output and wait for it
+ startScanner();
+
+ //TODO is it ok to start the scanner before we start jetty?
+
+ forker.start(); //forks jetty instance
+
+ }
+ catch (Exception e)
+ {
+ throw new MojoExecutionException("Error starting jetty", e);
+ }
}
- /* (non-Javadoc)
+ /**
*
*/
@Override
public void startJettyDistro() throws MojoExecutionException
{
- // TODO Auto-generated method stub
+ try
+ {
+ distroForker = newJettyDistroForker();
+ distroForker.setWaitForChild(true); //we always run at the command line, echo child output and wait for it
+ startScanner();
+ distroForker.start(); //forks a jetty distro
+
+ //TODO is it ok to start the scanner before we start jetty?
+ }
+ catch (Exception e)
+ {
+ throw new MojoExecutionException("Error starting jetty", e);
+ }
}
public void configureScanner() throws MojoExecutionException
@@ -222,7 +205,6 @@ public class NewJettyRunWarMojo extends AbstractWebAppMojo
scanner.addListener(new PathWatcher.EventListListener()
{
-
@Override
public void onPathWatchEvents(List events)
{
@@ -247,32 +229,81 @@ public class NewJettyRunWarMojo extends AbstractWebAppMojo
});
}
- public void restartWebApp(boolean reconfigureScanner) throws Exception
+ public void restartWebApp(boolean reconfigure) throws Exception
{
getLog().info("Restarting webapp ...");
- getLog().debug("Stopping webapp ...");
+ getLog().debug("Stopping scanner ...");
if (scanner != null)
scanner.stop();
- webApp.stop();
- getLog().debug("Reconfiguring webapp ...");
-
- verifyPomConfiguration();
- configureWebApp();
- // check if we need to reconfigure the scanner,
- // which is if the pom changes
- if (reconfigureScanner)
+ switch (runType)
{
- getLog().info("Reconfiguring scanner after change to pom.xml ...");
- scanner.reset();
- warArtifacts = null; //?????????? TODO
- configureScanner();
- }
+ case EMBED:
+ {
+ getLog().debug("Reconfiguring webapp ...");
+
+ verifyPomConfiguration();
+ // check if we need to reconfigure the scanner,
+ // which is if the pom changes
+ if (reconfigure)
+ {
+ getLog().info("Reconfiguring scanner after change to pom.xml ...");
+ scanner.reset();
+ warArtifacts = null;
+ configureScanner();
+ }
+
+ configureWebApp();
+ embedder.redeployWebApp();
+ scanner.start();
+ getLog().info("Restart completed at "+new Date().toString());
+
+ break;
+ }
+ case FORK:
+ {
+ verifyPomConfiguration();
+ if (reconfigure)
+ {
+ getLog().info("Reconfiguring scanner after change to pom.xml ...");
+ scanner.reset();
+ warArtifacts = null; ///TODO if the pom changes for the forked case, how would we get the forked process to stop and restart?
+ configureScanner();
+ }
+
+ configureWebApp();
+ //regenerate with new config and restart the webapp
+ forker.redeployWebApp();
+ //restart scanner
+ scanner.start();
+
+ break;
+ }
+ case DISTRO:
+ {
+ verifyPomConfiguration();
+ if (reconfigure)
+ {
+ getLog().info("Reconfiguring scanner after change to pom.xml ...");
+ scanner.reset();
+ warArtifacts = null; //TODO if there are any changes to the pom, then we would have to tell the
+ //existing forked distro process to stop, then rerun the configuration and then refork - too complicated??!
+ configureScanner();
+ }
+ configureWebApp();
+ //regenerate the webapp and redeploy it
+ distroForker.redeployWebApp();
+ //restart scanner
+ scanner.start();
- getLog().debug("Restarting webapp ...");
- webApp.start();
- scanner.start();
+ break;
+ }
+ default:
+ {
+ throw new IllegalStateException("Unrecognized run type "+runType);
+ }
+ }
getLog().info("Restart completed.");
}
-
+
}
diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/WebAppPropertyConverter.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/WebAppPropertyConverter.java
index 7753901ce16..4672fff8f03 100644
--- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/WebAppPropertyConverter.java
+++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/WebAppPropertyConverter.java
@@ -164,6 +164,9 @@ public class WebAppPropertyConverter
{
if (webApp == null)
throw new IllegalArgumentException("No webapp");
+
+ if (webAppProperties == null)
+ return;
String str = webAppProperties.getProperty("context.path");
if (!StringUtil.isBlank(str))