Signed-off-by: Jan Bartel <janb@webtide.com>
This commit is contained in:
Jan Bartel 2019-07-13 17:36:15 +02:00
parent 60d20c8808
commit 464f3d3e66
10 changed files with 509 additions and 414 deletions

View File

@ -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 ()

View File

@ -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<File> getProjectDependencyFiles()
private List<File> getProjectDependencyFiles()
{
List<File> dependencyFiles = new ArrayList<>();
for ( Iterator<Artifact> 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<Overlay> getOverlays()
protected List<Overlay> 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<Overlay> overlays)
private void unpackOverlays (List<Overlay> 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<Artifact> getWarArtifacts ()
protected List<Artifact> getWarArtifacts ()
{
if (warArtifacts != null)
return warArtifacts;
@ -859,7 +859,7 @@ public abstract class AbstractWebAppMojo extends AbstractMojo
return warArtifacts;
}
protected Artifact getArtifactForOverlay (OverlayConfig o, List<Artifact> warArtifacts)
private Artifact getArtifactForOverlay (OverlayConfig o, List<Artifact> 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<String, String> 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<File> getProvidedJars() throws MojoExecutionException
protected List<File> 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;

View File

@ -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<ConsoleReader.Listener> 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 <enter> to redeploy:");
if (line != null)
signalEvent(line);
}
}
public void signalEvent(String line)
{
for (ConsoleReader.Listener l:listeners)
l.consoleEvent(line);
}
}

View File

@ -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<File> libExtJarFiles;
protected List<File> 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-<VERSION>
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<String> 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-<VERSION>
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);
}
}
}

View File

@ -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<File> getJettyXmlFiles()
{
return jettyXmlFiles;
}
public void setJettyXmlFiles(List<File> jettyXmlFiles)
{
this.jettyXmlFiles = jettyXmlFiles;
}
public Map<String, String> getJettyProperties()
{
return jettyProperties;
}
public void setJettyProperties(Map<String, String> 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)

View File

@ -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<PathWatchEvent> 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();

View File

@ -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();
}
}

View File

@ -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<Listener> 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 <enter> 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<PathWatchEvent> 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();

View File

@ -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;
* </p>
* 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<Listener> 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 <enter> 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<PathWatchEvent> 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.");
}
}

View File

@ -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))