462346 Add pattern to jetty:run default classes and test classes scan paths

This commit is contained in:
Jan Bartel 2015-06-17 13:18:56 +10:00
parent ecdcc2e7c0
commit 1f3be625e6
7 changed files with 307 additions and 234 deletions

View File

@ -45,7 +45,7 @@ import org.eclipse.jetty.server.ShutdownMonitor;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.util.Scanner;
import org.eclipse.jetty.util.PathWatcher;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.xml.XmlConfiguration;
@ -261,20 +261,9 @@ public abstract class AbstractJettyMojo extends AbstractMojo
/**
* A scanner to check for changes to the webapp
*/
protected Scanner scanner;
protected PathWatcher scanner;
/**
* List of files and directories to scan
*/
protected ArrayList<File> scanList;
/**
* List of Listeners for the scanner
*/
protected ArrayList<Scanner.BulkListener> scannerListeners;
/**
* A scanner to check ENTER hits on the console
@ -467,16 +456,20 @@ public abstract class AbstractJettyMojo extends AbstractMojo
this.server.start();
getLog().info("Started Jetty Server");
if ( dumpOnStart )
{
getLog().info(this.server.dump());
}
// start the scanner thread (if necessary) on the main webapp
configureScanner ();
startScanner();
if (isScanningEnabled())
{
scanner = new PathWatcher();
configureScanner ();
startScanner();
}
// start the new line scanner thread if necessary
startConsoleScanner();
@ -572,33 +565,33 @@ public abstract class AbstractJettyMojo extends AbstractMojo
* files change.
*
*/
private void startScanner() throws Exception
public void startScanner() throws Exception
{
// check if scanning is enabled
if (scanIntervalSeconds <= 0) return;
// check if reload is manual. It disables file scanning
if ( "manual".equalsIgnoreCase( reload ) )
{
// issue a warning if both scanIntervalSeconds and reload
// are enabled
getLog().warn("scanIntervalSeconds is set to " + scanIntervalSeconds + " but will be IGNORED due to manual reloading");
if (!isScanningEnabled())
return;
}
scanner = new Scanner();
scanner.setReportExistingFilesOnStartup(false);
scanner.setScanInterval(scanIntervalSeconds);
scanner.setScanDirs(scanList);
scanner.setRecursive(true);
Iterator itor = (this.scannerListeners==null?null:this.scannerListeners.iterator());
while (itor!=null && itor.hasNext())
scanner.addListener((Scanner.Listener)itor.next());
getLog().info("Starting scanner at interval of " + scanIntervalSeconds + " seconds.");
scanner.setNotifyExistingOnStart(false);
scanner.start();
}
public boolean isScanningEnabled ()
{
if (scanIntervalSeconds <=0 || "manual".equalsIgnoreCase( reload ))
return false;
return true;
}
public void stopScanner() throws Exception
{
if (!isScanningEnabled())
return;
if (scanner != null)
scanner.stop();
}
/**

View File

@ -18,8 +18,6 @@
package org.eclipse.jetty.maven.plugin;
import java.io.File;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
@ -74,8 +72,7 @@ public class JettyDeployWar extends JettyRunWarMojo
{
super.finishConfigurationBeforeStart();
//only stop the server at shutdown if we are blocking
server.setStopAtShutdown(!nonblocking);
server.setStopAtShutdown(!nonblocking);
}
}

View File

@ -31,8 +31,8 @@ import java.util.Set;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.codehaus.plexus.util.FileUtils;
import org.eclipse.jetty.util.Scanner;
import org.eclipse.jetty.util.PathWatcher;
import org.eclipse.jetty.util.PathWatcher.PathWatchEvent;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.webapp.WebAppContext;
@ -94,6 +94,14 @@ public class JettyRunMojo extends AbstractJettyMojo
*/
protected File classesDirectory;
/**
* An optional pattern for includes/excludes of classes in the classesDirectory
* @parameter
*/
protected ScanPattern classesPattern;
/**
* The directory containing generated test classes.
@ -103,6 +111,13 @@ public class JettyRunMojo extends AbstractJettyMojo
*/
protected File testClassesDirectory;
/**
* An optional pattern for includes/excludes of classes in the testClassesDirectory
* @parameter
*/
protected ScanPattern testClassesPattern;
/**
* Root directory for all html/jsp etc files
@ -129,12 +144,6 @@ public class JettyRunMojo extends AbstractJettyMojo
protected ScanTargetPattern[] scanTargetPatterns;
/**
* Extra scan targets as a list
*/
protected List<File> extraScanTargets;
/**
* maven-war-plugin reference
*/
@ -226,59 +235,6 @@ public class JettyRunMojo extends AbstractJettyMojo
{
throw new MojoExecutionException("Location of classesDirectory does not exist");
}
extraScanTargets = new ArrayList<File>();
if (scanTargets != null)
{
for (int i=0; i< scanTargets.length; i++)
{
getLog().info("Added extra scan target:"+ scanTargets[i]);
extraScanTargets.add(scanTargets[i]);
}
}
if (scanTargetPatterns!=null)
{
for (int i=0;i<scanTargetPatterns.length; i++)
{
Iterator itor = scanTargetPatterns[i].getIncludes().iterator();
StringBuffer strbuff = new StringBuffer();
while (itor.hasNext())
{
strbuff.append((String)itor.next());
if (itor.hasNext())
strbuff.append(",");
}
String includes = strbuff.toString();
itor = scanTargetPatterns[i].getExcludes().iterator();
strbuff= new StringBuffer();
while (itor.hasNext())
{
strbuff.append((String)itor.next());
if (itor.hasNext())
strbuff.append(",");
}
String excludes = strbuff.toString();
try
{
List<File> files = FileUtils.getFiles(scanTargetPatterns[i].getDirectory(), includes, excludes);
itor = files.iterator();
while (itor.hasNext())
getLog().info("Adding extra scan target from pattern: "+itor.next());
List<File> currentTargets = extraScanTargets;
if(currentTargets!=null && !currentTargets.isEmpty())
currentTargets.addAll(files);
else
extraScanTargets = files;
}
catch (IOException e)
{
throw new MojoExecutionException(e.getMessage());
}
}
}
}
@ -323,9 +279,7 @@ public class JettyRunMojo extends AbstractJettyMojo
//get copy of a list of war artifacts
Set<Artifact> matchedWarArtifacts = new HashSet<Artifact>();
//make sure each of the war artifacts is added to the scanner
for (Artifact a:getWarArtifacts())
extraScanTargets.add(a.getFile());
//process any overlays and the war type artifacts
List<Overlay> overlays = new ArrayList<Overlay>();
@ -414,77 +368,36 @@ public class JettyRunMojo extends AbstractJettyMojo
public void configureScanner ()
throws MojoExecutionException
{
// start the scanner thread (if necessary) on the main webapp
scanList = new ArrayList<File>();
if (webApp.getDescriptor() != null)
try
{
try (Resource r = Resource.newResource(webApp.getDescriptor());)
{
scanList.add(r.getFile());
}
catch (IOException e)
{
throw new MojoExecutionException("Problem configuring scanner for web.xml", e);
}
gatherScannables();
}
catch (Exception e)
{
throw new MojoExecutionException("Error forming scan list", e);
}
if (webApp.getJettyEnvXml() != null)
scanner.addListener(new PathWatcher.EventListListener()
{
try (Resource r = Resource.newResource(webApp.getJettyEnvXml());)
{
scanList.add(r.getFile());
}
catch (IOException e)
{
throw new MojoExecutionException("Problem configuring scanner for jetty-env.xml", e);
}
}
if (webApp.getDefaultsDescriptor() != null)
{
try (Resource r = Resource.newResource(webApp.getDefaultsDescriptor());)
{
if (!WebAppContext.WEB_DEFAULTS_XML.equals(webApp.getDefaultsDescriptor()))
scanList.add(r.getFile());
}
catch (IOException e)
{
throw new MojoExecutionException("Problem configuring scanner for webdefaults.xml", e);
}
}
if (webApp.getOverrideDescriptor() != null)
{
try (Resource r = Resource.newResource(webApp.getOverrideDescriptor());)
{
scanList.add(r.getFile());
}
catch (IOException e)
{
throw new MojoExecutionException("Problem configuring scanner for webdefaults.xml", e);
}
}
File jettyWebXmlFile = findJettyWebXmlFile(new File(webAppSourceDirectory,"WEB-INF"));
if (jettyWebXmlFile != null)
scanList.add(jettyWebXmlFile);
scanList.addAll(extraScanTargets);
scanList.add(project.getFile());
if (webApp.getTestClasses() != null)
scanList.add(webApp.getTestClasses());
if (webApp.getClasses() != null)
scanList.add(webApp.getClasses());
scanList.addAll(webApp.getWebInfLib());
scannerListeners = new ArrayList<Scanner.BulkListener>();
scannerListeners.add(new Scanner.BulkListener()
{
public void filesChanged (List changes)
@Override
public void onPathWatchEvents(List<PathWatchEvent> events)
{
try
{
boolean reconfigure = changes.contains(project.getFile().getCanonicalPath());
boolean reconfigure = false;
if (events != null)
{
for (PathWatchEvent e:events)
{
if (e.getPath().equals(project.getFile().toPath()))
{
reconfigure = true;
break;
}
}
}
restartWebApp(reconfigure);
}
catch (Exception e)
@ -496,7 +409,115 @@ public class JettyRunMojo extends AbstractJettyMojo
}
public void gatherScannables() throws Exception
{
if (webApp.getDescriptor() != null)
{
Resource r = Resource.newResource(webApp.getDescriptor());
scanner.watch(r.getFile().toPath());
}
if (webApp.getJettyEnvXml() != null)
scanner.watch(new File(webApp.getJettyEnvXml()).toPath());
if (webApp.getDefaultsDescriptor() != null)
{
if (!WebAppContext.WEB_DEFAULTS_XML.equals(webApp.getDefaultsDescriptor()))
scanner.watch(new File(webApp.getDefaultsDescriptor()).toPath());
}
if (webApp.getOverrideDescriptor() != null)
{
scanner.watch(new File(webApp.getOverrideDescriptor()).toPath());
}
File jettyWebXmlFile = findJettyWebXmlFile(new File(webAppSourceDirectory,"WEB-INF"));
if (jettyWebXmlFile != null)
{
scanner.watch(jettyWebXmlFile.toPath());
}
//make sure each of the war artifacts is added to the scanner
for (Artifact a:getWarArtifacts())
{
scanner.watch(a.getFile().toPath());
}
//handle the explicit extra scan targets
if (scanTargets != null)
{
for (File f:scanTargets)
{
if (f.isDirectory())
{
PathWatcher.Config config = new PathWatcher.Config(f.toPath());
config.setRecurseDepth(PathWatcher.Config.UNLIMITED_DEPTH);
scanner.watch(config);
}
else
scanner.watch(f.toPath());
}
}
//handle the extra scan patterns
if (scanTargetPatterns != null)
{
for (ScanTargetPattern p:scanTargetPatterns)
{
PathWatcher.Config config = new PathWatcher.Config(p.getDirectory().toPath());
config.setRecurseDepth(PathWatcher.Config.UNLIMITED_DEPTH);
for (String pattern:p.getExcludes())
config.addExcludeGlobRelative(pattern);
for (String pattern:p.getIncludes())
config.addIncludeGlobRelative(pattern);
scanner.watch(config);
}
}
scanner.watch(project.getFile().toPath());
if (webApp.getTestClasses() != null)
{
PathWatcher.Config config = new PathWatcher.Config(webApp.getTestClasses().toPath());
config.setRecurseDepth(PathWatcher.Config.UNLIMITED_DEPTH);
if (testClassesPattern != null)
{
for (String p:testClassesPattern.getExcludes())
config.addExcludeGlobRelative(p);
for (String p:testClassesPattern.getIncludes())
config.addIncludeGlobRelative(p);
}
scanner.watch(config);
}
if (webApp.getClasses() != null)
{
PathWatcher.Config config = new PathWatcher.Config(webApp.getClasses().toPath());
config.setRecurseDepth(PathWatcher.Config.UNLIMITED_DEPTH);
if (classesPattern != null)
{
for (String p:classesPattern.getExcludes())
config.addExcludeGlobRelative(p);
for (String p:classesPattern.getIncludes())
config.addIncludeGlobRelative(p);
}
scanner.watch(config);
}
if (webApp.getWebInfLib() != null)
{
for (File f:webApp.getWebInfLib())
{
PathWatcher.Config config = new PathWatcher.Config(f.toPath());
config.setRecurseDepth(PathWatcher.Config.UNLIMITED_DEPTH);
scanner.watch(config);
}
}
}
/**
* @see org.eclipse.jetty.maven.plugin.AbstractJettyMojo#restartWebApp(boolean)
@ -505,7 +526,9 @@ public class JettyRunMojo extends AbstractJettyMojo
{
getLog().info("restarting "+webApp);
getLog().debug("Stopping webapp ...");
stopScanner();
webApp.stop();
getLog().debug("Reconfiguring webapp ...");
checkPomConfiguration();
@ -516,23 +539,14 @@ public class JettyRunMojo extends AbstractJettyMojo
if (reconfigureScanner)
{
getLog().info("Reconfiguring scanner after change to pom.xml ...");
scanList.clear();
if (webApp.getDescriptor() != null)
scanList.add(new File(webApp.getDescriptor()));
if (webApp.getJettyEnvXml() != null)
scanList.add(new File(webApp.getJettyEnvXml()));
scanList.addAll(extraScanTargets);
scanList.add(project.getFile());
if (webApp.getTestClasses() != null)
scanList.add(webApp.getTestClasses());
if (webApp.getClasses() != null)
scanList.add(webApp.getClasses());
scanList.addAll(webApp.getWebInfLib());
scanner.setScanDirs(scanList);
scanner.reset();
warArtifacts = null;
configureScanner();
}
getLog().debug("Restarting webapp ...");
webApp.start();
startScanner();
getLog().info("Restart completed at "+new Date().toString());
}
@ -582,7 +596,7 @@ public class JettyRunMojo extends AbstractJettyMojo
warArtifacts = new ArrayList<Artifact>();
for ( Iterator<Artifact> iter = projectArtifacts.iterator(); iter.hasNext(); )
{
Artifact artifact = (Artifact) iter.next();
Artifact artifact = (Artifact) iter.next();
if (artifact.getType().equals("war") || artifact.getType().equals("zip"))
{
try

View File

@ -19,12 +19,12 @@
package org.eclipse.jetty.maven.plugin;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.eclipse.jetty.util.Scanner;
import org.eclipse.jetty.util.PathWatcher;
import org.eclipse.jetty.util.PathWatcher.PathWatchEvent;
/**
*
@ -96,27 +96,41 @@ public class JettyRunWarExplodedMojo extends AbstractJettyMojo
*/
public void configureScanner() throws MojoExecutionException
{
scanList = new ArrayList<File>();
scanList.add(project.getFile());
scanner.watch(project.getFile().toPath());
File webInfDir = new File(war,"WEB-INF");
scanList.add(new File(webInfDir, "web.xml"));
scanner.watch(new File(webInfDir, "web.xml").toPath());
File jettyWebXmlFile = findJettyWebXmlFile(webInfDir);
if (jettyWebXmlFile != null)
scanList.add(jettyWebXmlFile);
scanner.watch(jettyWebXmlFile.toPath());
File jettyEnvXmlFile = new File(webInfDir, "jetty-env.xml");
if (jettyEnvXmlFile.exists())
scanList.add(jettyEnvXmlFile);
scanList.add(new File(webInfDir, "classes"));
scanList.add(new File(webInfDir, "lib"));
scanner.watch(jettyEnvXmlFile.toPath());
PathWatcher.Config classesConfig = new PathWatcher.Config(new File(webInfDir, "classes").toPath());
classesConfig.setRecurseDepth(PathWatcher.Config.UNLIMITED_DEPTH);
scanner.watch(classesConfig);
PathWatcher.Config libConfig = new PathWatcher.Config(new File(webInfDir, "lib").toPath());
libConfig.setRecurseDepth(PathWatcher.Config.UNLIMITED_DEPTH);
scanner.watch(libConfig);
scannerListeners = new ArrayList<Scanner.BulkListener>();
scannerListeners.add(new Scanner.BulkListener()
scanner.addListener(new PathWatcher.EventListListener()
{
public void filesChanged(List changes)
@Override
public void onPathWatchEvents(List<PathWatchEvent> events)
{
try
{
boolean reconfigure = changes.contains(project.getFile().getCanonicalPath());
boolean reconfigure = false;
for (PathWatchEvent e:events)
{
if (e.getPath().equals(project.getFile().toPath()))
{
reconfigure = true;
break;
}
}
restartWebApp(reconfigure);
}
catch (Exception e)
@ -137,6 +151,7 @@ public class JettyRunWarExplodedMojo extends AbstractJettyMojo
{
getLog().info("Restarting webapp");
getLog().debug("Stopping webapp ...");
stopScanner();
webApp.stop();
getLog().debug("Reconfiguring webapp ...");
@ -147,23 +162,13 @@ public class JettyRunWarExplodedMojo extends AbstractJettyMojo
if (reconfigureScanner)
{
getLog().info("Reconfiguring scanner after change to pom.xml ...");
scanList.clear();
scanList.add(project.getFile());
File webInfDir = new File(war,"WEB-INF");
scanList.add(new File(webInfDir, "web.xml"));
File jettyWebXmlFile = findJettyWebXmlFile(webInfDir);
if (jettyWebXmlFile != null)
scanList.add(jettyWebXmlFile);
File jettyEnvXmlFile = new File(webInfDir, "jetty-env.xml");
if (jettyEnvXmlFile.exists())
scanList.add(jettyEnvXmlFile);
scanList.add(new File(webInfDir, "classes"));
scanList.add(new File(webInfDir, "lib"));
scanner.setScanDirs(scanList);
scanner.reset();
configureScanner();
}
getLog().debug("Restarting webapp ...");
webApp.start();
startScanner();
getLog().info("Restart completed.");
}

View File

@ -19,12 +19,12 @@
package org.eclipse.jetty.maven.plugin;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.eclipse.jetty.util.Scanner;
import org.eclipse.jetty.util.PathWatcher;
import org.eclipse.jetty.util.PathWatcher.PathWatchEvent;
/**
* <p>
@ -100,18 +100,26 @@ public class JettyRunWarMojo extends AbstractJettyMojo
*/
public void configureScanner() throws MojoExecutionException
{
scanList = new ArrayList();
scanList.add(project.getFile());
scanList.add(war);
scannerListeners = new ArrayList();
scannerListeners.add(new Scanner.BulkListener()
scanner.watch(project.getFile().toPath());
scanner.watch(war.toPath());
scanner.addListener(new PathWatcher.EventListListener()
{
public void filesChanged(List changes)
@Override
public void onPathWatchEvents(List<PathWatchEvent> events)
{
try
{
boolean reconfigure = changes.contains(project.getFile().getCanonicalPath());
boolean reconfigure = false;
for (PathWatchEvent e:events)
{
if (e.getPath().equals(project.getFile().toPath()))
{
reconfigure = true;
break;
}
}
restartWebApp(reconfigure);
}
catch (Exception e)
@ -132,6 +140,7 @@ public class JettyRunWarMojo extends AbstractJettyMojo
{
getLog().info("Restarting webapp ...");
getLog().debug("Stopping webapp ...");
stopScanner();
webApp.stop();
getLog().debug("Reconfiguring webapp ...");
@ -142,14 +151,13 @@ public class JettyRunWarMojo extends AbstractJettyMojo
if (reconfigureScanner)
{
getLog().info("Reconfiguring scanner after change to pom.xml ...");
scanList.clear();
scanList.add(project.getFile());
scanList.add(war);
scanner.setScanDirs(scanList);
scanner.reset();
configureScanner();
}
getLog().debug("Restarting webapp ...");
webApp.start();
startScanner();
getLog().info("Restart completed.");
}

View File

@ -0,0 +1,53 @@
//
// ========================================================================
// Copyright (c) 1995-2015 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.util.Collections;
import java.util.List;
/**
* ScanPattern
*
* A pattern of includes and excludes.
*/
public class ScanPattern
{
private List<String> _includes = Collections.emptyList();
private List<String> _excludes = Collections.emptyList();
public void setIncludes (List<String> includes)
{
_includes= includes;
}
public void setExcludes(List<String> excludes)
{
_excludes = excludes;
}
public List<String> getIncludes()
{
return _includes;
}
public List<String> getExcludes()
{
return _excludes;
}
}

View File

@ -46,8 +46,7 @@ import java.util.List;
public class ScanTargetPattern
{
private File _directory;
private List _includes = Collections.EMPTY_LIST;
private List _excludes = Collections.EMPTY_LIST;
private ScanPattern _pattern;
/**
* @return the _directory
@ -65,24 +64,28 @@ public class ScanTargetPattern
this._directory = directory;
}
public void setIncludes (List includes)
public void setIncludes (List<String> includes)
{
_includes= includes;
if (_pattern == null)
_pattern = new ScanPattern();
_pattern.setIncludes(includes);
}
public void setExcludes(List excludes)
public void setExcludes(List<String> excludes)
{
_excludes = excludes;
if (_pattern == null)
_pattern = new ScanPattern();
_pattern.setExcludes(excludes);
}
public List getIncludes()
public List<String> getIncludes()
{
return _includes;
return (_pattern == null? Collections.emptyList() : _pattern.getIncludes());
}
public List getExcludes()
public List<String> getExcludes()
{
return _excludes;
return (_pattern == null? Collections.emptyList() : _pattern.getExcludes());
}
}