Merge remote-tracking branch 'origin/master' into jetty-http2

This commit is contained in:
Simone Bordet 2014-06-19 16:26:58 +02:00
commit 59deebeb9c
38 changed files with 526 additions and 121 deletions

View File

@ -27,6 +27,7 @@ import java.net.URL;
import java.net.URLClassLoader; import java.net.URLClassLoader;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
@ -458,28 +459,7 @@ public abstract class AbstractJettyMojo extends AbstractMojo
if (getJettyXmlFiles() == null) if (getJettyXmlFiles() == null)
return; return;
XmlConfiguration last = null; this.server.applyXmlConfigurations(getJettyXmlFiles());
for ( File xmlFile : getJettyXmlFiles() )
{
getLog().info( "Configuring Jetty from xml configuration file = " + xmlFile.getCanonicalPath() );
XmlConfiguration xmlConfiguration = new XmlConfiguration(Resource.toURL(xmlFile));
//chain ids from one config file to another
if (last == null)
xmlConfiguration.getIdMap().put("Server", this.server);
else
xmlConfiguration.getIdMap().putAll(last.getIdMap());
//Set the system properties each time in case the config file set a new one
Enumeration<?> ensysprop = System.getProperties().propertyNames();
while (ensysprop.hasMoreElements())
{
String name = (String)ensysprop.nextElement();
xmlConfiguration.getProperties().put(name,System.getProperty(name));
}
last = xmlConfiguration;
xmlConfiguration.configure();
}
} }

View File

@ -19,6 +19,12 @@
package org.eclipse.jetty.maven.plugin; package org.eclipse.jetty.maven.plugin;
import java.io.File;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.RequestLog; import org.eclipse.jetty.server.RequestLog;
import org.eclipse.jetty.server.handler.ContextHandlerCollection; import org.eclipse.jetty.server.handler.ContextHandlerCollection;
@ -27,6 +33,8 @@ import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.server.handler.RequestLogHandler; import org.eclipse.jetty.server.handler.RequestLogHandler;
import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.webapp.WebAppContext; import org.eclipse.jetty.webapp.WebAppContext;
import org.eclipse.jetty.xml.XmlConfiguration;
/** /**
* JettyServer * JettyServer
@ -109,4 +117,43 @@ public class JettyServer extends org.eclipse.jetty.server.Server
} }
} }
} }
/**
* Apply xml files to server startup, passing in ourselves as the
* "Server" instance.
*
* @param files
* @throws Exception
*/
public void applyXmlConfigurations (List<File> files)
throws Exception
{
if (files == null || files.isEmpty())
return;
Map<String,Object> lastMap = Collections.singletonMap("Server", (Object)this);
for ( File xmlFile : files )
{
if (PluginLog.getLog() != null)
PluginLog.getLog().info( "Configuring Jetty from xml configuration file = " + xmlFile.getCanonicalPath() );
XmlConfiguration xmlConfiguration = new XmlConfiguration(Resource.toURL(xmlFile));
//chain ids from one config file to another
if (lastMap != null)
xmlConfiguration.getIdMap().putAll(lastMap);
//Set the system properties each time in case the config file set a new one
Enumeration<?> ensysprop = System.getProperties().propertyNames();
while (ensysprop.hasMoreElements())
{
String name = (String)ensysprop.nextElement();
xmlConfiguration.getProperties().put(name,System.getProperty(name));
}
xmlConfiguration.configure();
lastMap = xmlConfiguration.getIdMap();
}
}
} }

View File

@ -23,6 +23,7 @@ import java.io.FileInputStream;
import java.io.InputStream; import java.io.InputStream;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
@ -415,19 +416,14 @@ public class Starter
/** /**
* Apply any jetty xml files given
* @throws Exception * @throws Exception
*/ */
public void applyJettyXml() throws Exception public void applyJettyXml() throws Exception
{ {
if (jettyXmls == null) if (jettyXmls == null)
return; return;
this.server.applyXmlConfigurations(jettyXmls);
for ( File xmlFile : jettyXmls )
{
LOG.info( "Configuring Jetty from xml configuration file = " + xmlFile.getCanonicalPath() );
XmlConfiguration xmlConfiguration = new XmlConfiguration(Resource.toURL(xmlFile));
xmlConfiguration.configure(this.server);
}
} }

View File

@ -51,14 +51,23 @@ import org.eclipse.jetty.util.log.Logger;
* *
* The following init parameters are used to configure this servlet: * The following init parameters are used to configure this servlet:
* <dl> * <dl>
* <dt>cgibinResourceBase</dt><dd>Path to the cgi bin directory if set or it will default to the resource base of the context.</dd> * <dt>cgibinResourceBase</dt>
* <dt>resourceBase</dt><dd>An alias for cgibinResourceBase.</dd> * <dd>Path to the cgi bin directory if set or it will default to the resource base of the context.</dd>
* <dt>cgibinResourceBaseIsRelative</dt><dd>If true then cgibinResourceBase is relative to the webapp (eg "WEB-INF/cgi")</dd> * <dt>resourceBase</dt>
* <dt>commandPrefix</dt><dd>may be used to set a prefix to all commands passed to exec. This can be used on systems that need assistance to execute a * <dd>An alias for cgibinResourceBase.</dd>
* <dt>cgibinResourceBaseIsRelative</dt>
* <dd>If true then cgibinResourceBase is relative to the webapp (eg "WEB-INF/cgi")</dd>
* <dt>commandPrefix</dt>
* <dd>may be used to set a prefix to all commands passed to exec. This can be used on systems that need assistance to execute a
* particular file type. For example on windows this can be set to "perl" so that perl scripts are executed.</dd> * particular file type. For example on windows this can be set to "perl" so that perl scripts are executed.</dd>
* <dt>Path</dt><dd>passed to the exec environment as PATH.</dd> * <dt>Path</dt>
* <dt>ENV_*</dt><dd>used to set an arbitrary environment variable with the name stripped of the leading ENV_ and using the init parameter value</dd> * <dd>passed to the exec environment as PATH.</dd>
* <dt>useFullPath</dt><dd>If true, the full URI path within the context is used for the exec command, otherwise a search is done for a partial URL that matches an exec Command</dd> * <dt>ENV_*</dt>
* <dd>used to set an arbitrary environment variable with the name stripped of the leading ENV_ and using the init parameter value</dd>
* <dt>useFullPath</dt>
* <dd>If true, the full URI path within the context is used for the exec command, otherwise a search is done for a partial URL that matches an exec Command</dd>
* <dt>ignoreExitState</dt>
* <dd>If true then do not act on a non-zero exec exit status")</dd>
* </dl> * </dl>
* *
*/ */
@ -196,13 +205,9 @@ public class CGI extends HttpServlet
String info = ""; String info = "";
// Search docroot for a matching execCmd // Search docroot for a matching execCmd
while (path.endsWith("/") && path.length() >= 0) while ((path.endsWith("/") || !execCmd.exists()) && path.length() >= 0)
{ {
if(!execCmd.exists())
break;
int index = path.lastIndexOf('/'); int index = path.lastIndexOf('/');
path = path.substring(0,index); path = path.substring(0,index);
info = pathInContext.substring(index,pathInContext.length()); info = pathInContext.substring(index,pathInContext.length());
execCmd = new File(_docRoot,path); execCmd = new File(_docRoot,path);

View File

@ -389,10 +389,10 @@ public class Main
} }
boolean transitive = module.isEnabled() && (module.getSources().size() == 0); boolean transitive = module.isEnabled() && (module.getSources().size() == 0);
boolean has_ini_lines = module.getInitialise().size() > 0; boolean hasDefinedDefaults = module.getDefaultConfig().size() > 0;
// If it is not enabled or is transitive with ini template lines or toplevel and doesn't exist // If it is not enabled or is transitive with ini template lines or toplevel and doesn't exist
if (!module.isEnabled() || (transitive && has_ini_lines) || (topLevel && !FS.exists(startd_ini) && !appendStartIni)) if (!module.isEnabled() || (transitive && hasDefinedDefaults) || (topLevel && !FS.exists(startd_ini) && !appendStartIni))
{ {
// File BufferedWriter // File BufferedWriter
BufferedWriter writer = null; BufferedWriter writer = null;
@ -430,7 +430,7 @@ public class Main
out.println("--module=" + name); out.println("--module=" + name);
args.parse("--module=" + name,source); args.parse("--module=" + name,source);
modules.enable(name,Collections.singletonList(source)); modules.enable(name,Collections.singletonList(source));
for (String line : module.getInitialise()) for (String line : module.getDefaultConfig())
{ {
out.println(line); out.println(line);
args.parse(line,source); args.parse(line,source);
@ -490,10 +490,9 @@ public class Main
// Process dependencies // Process dependencies
module.expandProperties(args.getProperties()); module.expandProperties(args.getProperties());
modules.registerParentsIfMissing(baseHome,args,module); modules.registerParentsIfMissing(module);
modules.buildGraph(); modules.buildGraph();
// process new ini modules // process new ini modules
if (topLevel) if (topLevel)
{ {
@ -573,9 +572,9 @@ public class Main
// ------------------------------------------------------------ // ------------------------------------------------------------
// 3) Module Registration // 3) Module Registration
Modules modules = new Modules(); Modules modules = new Modules(baseHome,args);
StartLog.debug("Registering all modules"); StartLog.debug("Registering all modules");
modules.registerAll(baseHome, args); modules.registerAll();
// ------------------------------------------------------------ // ------------------------------------------------------------
// 4) Active Module Resolution // 4) Active Module Resolution
@ -600,6 +599,7 @@ public class Main
// 6) Resolve Extra XMLs // 6) Resolve Extra XMLs
args.resolveExtraXmls(baseHome); args.resolveExtraXmls(baseHome);
// ------------------------------------------------------------
// 9) Resolve Property Files // 9) Resolve Property Files
args.resolvePropertyFiles(baseHome); args.resolvePropertyFiles(baseHome);

View File

@ -96,7 +96,7 @@ public class Module
/** List of xml configurations for this Module */ /** List of xml configurations for this Module */
private List<String> xmls; private List<String> xmls;
/** List of ini template lines */ /** List of ini template lines */
private List<String> initialise; private List<String> defaultConfig;
/** List of library options for this Module */ /** List of library options for this Module */
private List<String> libs; private List<String> libs;
/** List of files for this Module */ /** List of files for this Module */
@ -213,9 +213,14 @@ public class Module
return fileRef; return fileRef;
} }
public List<String> getInitialise() public List<String> getDefaultConfig()
{ {
return initialise; return defaultConfig;
}
public boolean hasDefaultConfig()
{
return (defaultConfig != null) && (defaultConfig.size() > 0);
} }
public List<String> getLibs() public List<String> getLibs()
@ -274,7 +279,7 @@ public class Module
parentEdges = new HashSet<>(); parentEdges = new HashSet<>();
childEdges = new HashSet<>(); childEdges = new HashSet<>();
xmls = new ArrayList<>(); xmls = new ArrayList<>();
initialise = new ArrayList<>(); defaultConfig = new ArrayList<>();
libs = new ArrayList<>(); libs = new ArrayList<>();
files = new ArrayList<>(); files = new ArrayList<>();
jvmArgs = new ArrayList<>(); jvmArgs = new ArrayList<>();
@ -328,7 +333,7 @@ public class Module
{ {
if ("INI-TEMPLATE".equals(sectionType)) if ("INI-TEMPLATE".equals(sectionType))
{ {
initialise.add(line); defaultConfig.add(line);
} }
} }
else else
@ -344,8 +349,9 @@ public class Module
case "FILES": case "FILES":
files.add(line); files.add(line);
break; break;
case "DEFAULTS":
case "INI-TEMPLATE": case "INI-TEMPLATE":
initialise.add(line); defaultConfig.add(line);
break; break;
case "LIB": case "LIB":
libs.add(line); libs.add(line);
@ -404,4 +410,5 @@ public class Module
str.append(']'); str.append(']');
return str.toString(); return str.toString();
} }
} }

View File

@ -212,9 +212,9 @@ public class ModuleGraphWriter
} }
} }
if (!module.getInitialise().isEmpty()) if (!module.getDefaultConfig().isEmpty())
{ {
List<String> inis = module.getInitialise(); List<String> inis = module.getDefaultConfig();
writeModuleDetailHeader(out,"INI Template",inis.size()); writeModuleDetailHeader(out,"INI Template",inis.size());
} }

View File

@ -38,6 +38,9 @@ import java.util.regex.Pattern;
*/ */
public class Modules implements Iterable<Module> public class Modules implements Iterable<Module>
{ {
private final BaseHome baseHome;
private final StartArgs args;
private Map<String, Module> modules = new HashMap<>(); private Map<String, Module> modules = new HashMap<>();
/* /*
* modules that may appear in the resolved graph but are undefined in the module system * modules that may appear in the resolved graph but are undefined in the module system
@ -48,6 +51,12 @@ public class Modules implements Iterable<Module>
private int maxDepth = -1; private int maxDepth = -1;
public Modules(BaseHome basehome, StartArgs args)
{
this.baseHome = basehome;
this.args = args;
}
private Set<String> asNameSet(Set<Module> moduleSet) private Set<String> asNameSet(Set<Module> moduleSet)
{ {
Set<String> ret = new HashSet<>(); Set<String> ret = new HashSet<>();
@ -106,8 +115,10 @@ public class Modules implements Iterable<Module>
/** /**
* Using the provided dependencies, build the module graph * Using the provided dependencies, build the module graph
*/ */
public void buildGraph() public void buildGraph() throws FileNotFoundException, IOException
{ {
normalizeDependencies();
// Connect edges // Connect edges
for (Module module : modules.values()) for (Module module : modules.values())
{ {
@ -118,10 +129,14 @@ public class Modules implements Iterable<Module>
if (parent == null) if (parent == null)
{ {
if (parentName.contains("${")) if (parentName.contains("${"))
{
StartLog.debug("module not found [%s]%n",parentName); StartLog.debug("module not found [%s]%n",parentName);
}
else else
{
StartLog.warn("module not found [%s]%n",parentName); StartLog.warn("module not found [%s]%n",parentName);
} }
}
else else
{ {
module.addParentEdge(parent); module.addParentEdge(parent);
@ -250,7 +265,7 @@ public class Modules implements Iterable<Module>
} }
} }
public void enable(String name, List<String> sources) public void enable(String name, List<String> sources) throws IOException
{ {
if (name.contains("*")) if (name.contains("*"))
{ {
@ -276,14 +291,47 @@ public class Modules implements Iterable<Module>
} }
} }
private void enableModule(Module module, List<String> sources) private void enableModule(Module module, List<String> sources) throws IOException
{ {
if (module.isEnabled())
{
// already enabled, skip
return;
}
StartLog.debug("Enabling module: %s (via %s)",module.getName(),Main.join(sources,", ")); StartLog.debug("Enabling module: %s (via %s)",module.getName(),Main.join(sources,", "));
module.setEnabled(true); module.setEnabled(true);
args.parseModule(module);
module.expandProperties(args.getProperties());
if (sources != null) if (sources != null)
{ {
module.addSources(sources); module.addSources(sources);
} }
// enable any parents that haven't been enabled (yet)
for(String name: module.getParentNames())
{
Module parent = modules.get(name);
if (name == null)
{
// parent module doesn't exist, yet
Path file = baseHome.getPath("modules/" + name + ".mod");
if (FS.canReadFile(file))
{
parent = registerModule(file);
updateParentReferencesTo(parent);
}
else
{
StartLog.debug("Missing module definition: [ Mod: %s | File: %s ]",name,file);
missingModules.add(name);
}
}
if (parent != null)
{
enableModule(parent,sources);
}
}
} }
private void findChildren(Module module, Set<Module> ret) private void findChildren(Module module, Set<Module> ret)
@ -372,32 +420,35 @@ public class Modules implements Iterable<Module>
return module; return module;
} }
public void registerParentsIfMissing(BaseHome basehome, StartArgs args, Module module) throws IOException public void registerParentsIfMissing(Module module) throws IOException
{ {
Set<String> parents = new HashSet<>(module.getParentNames()); Set<String> parents = new HashSet<>(module.getParentNames());
for (String name : parents) for (String name : parents)
{ {
if (!modules.containsKey(name)) if (!modules.containsKey(name))
{ {
Path file = basehome.getPath("modules/" + name + ".mod"); Path file = baseHome.getPath("modules/" + name + ".mod");
if (FS.canReadFile(file)) if (FS.canReadFile(file))
{ {
Module parent = registerModule(basehome,args,file); Module parent = registerModule(file);
updateParentReferencesTo(parent); updateParentReferencesTo(parent);
registerParentsIfMissing(basehome, args, parent); registerParentsIfMissing(parent);
} }
} }
} }
} }
public void registerAll(BaseHome basehome, StartArgs args) throws IOException public void registerAll() throws IOException
{ {
for (Path path : basehome.getPaths("modules/*.mod")) for (Path path : baseHome.getPaths("modules/*.mod"))
{ {
registerModule(basehome,args,path); registerModule(path);
}
} }
// load missing post-expanded dependent modules // load missing post-expanded dependent modules
private void normalizeDependencies() throws FileNotFoundException, IOException
{
boolean done = false; boolean done = false;
while (!done) while (!done)
{ {
@ -419,10 +470,10 @@ public class Modules implements Iterable<Module>
for (String missingParent : missingParents) for (String missingParent : missingParents)
{ {
Path file = basehome.getPath("modules/" + missingParent + ".mod"); Path file = baseHome.getPath("modules/" + missingParent + ".mod");
if (FS.canReadFile(file)) if (FS.canReadFile(file))
{ {
Module module = registerModule(basehome,args,file); Module module = registerModule(file);
updateParentReferencesTo(module); updateParentReferencesTo(module);
} }
else else
@ -434,15 +485,14 @@ public class Modules implements Iterable<Module>
} }
} }
private Module registerModule(BaseHome basehome, StartArgs args, Path file) throws FileNotFoundException, IOException private Module registerModule(Path file) throws FileNotFoundException, IOException
{ {
if (!FS.canReadFile(file)) if (!FS.canReadFile(file))
{ {
throw new IOException("Cannot read file: " + file); throw new IOException("Cannot read file: " + file);
} }
StartLog.debug("Registering Module: %s",basehome.toShortForm(file)); StartLog.debug("Registering Module: %s",baseHome.toShortForm(file));
Module module = new Module(basehome,file); Module module = new Module(baseHome,file);
module.expandProperties(args.getProperties());
return register(module); return register(module);
} }
@ -485,7 +535,7 @@ public class Modules implements Iterable<Module>
StartLog.warn("** Unable to continue, required dependency missing. [%s]",missing); StartLog.warn("** Unable to continue, required dependency missing. [%s]",missing);
StartLog.warn("** As configured, Jetty is unable to start due to a missing enabled module dependency."); StartLog.warn("** As configured, Jetty is unable to start due to a missing enabled module dependency.");
StartLog.warn("** This may be due to a transitive dependency akin to spdy on npn, which resolves based on the JDK in use."); StartLog.warn("** This may be due to a transitive dependency akin to spdy on npn, which resolves based on the JDK in use.");
return Collections.emptyList(); throw new UsageException(UsageException.ERR_BAD_ARG, "Missing referenced dependency: " + missing);
} }
} }
} }

View File

@ -61,6 +61,22 @@ public final class Props implements Iterable<Prop>
this(key,value,origin); this(key,value,origin);
this.overrides = overrides; this.overrides = overrides;
} }
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("Prop [key=");
builder.append(key);
builder.append(", value=");
builder.append(value);
builder.append(", origin=");
builder.append(origin);
builder.append(", overrides=");
builder.append(overrides);
builder.append("]");
return builder.toString();
}
} }
public static final String ORIGIN_SYSPROP = "<system-property>"; public static final String ORIGIN_SYSPROP = "<system-property>";

View File

@ -647,6 +647,18 @@ public class StartArgs
} }
public void parse(final String rawarg, String source) public void parse(final String rawarg, String source)
{
parse(rawarg,source,true);
}
/**
* Parse a single line of argument.
*
* @param rawarg the raw argument to parse
* @param source the origin of this line of argument
* @param replaceProps true if properties in this parse replace previous ones, false to not replace.
*/
private void parse(final String rawarg, String source, boolean replaceProps)
{ {
if (rawarg == null) if (rawarg == null)
{ {
@ -810,11 +822,11 @@ public class StartArgs
{ {
case 2: case 2:
System.setProperty(assign[0],assign[1]); System.setProperty(assign[0],assign[1]);
setProperty(assign[0],assign[1],source); setProperty(assign[0],assign[1],source,replaceProps);
break; break;
case 1: case 1:
System.setProperty(assign[0],""); System.setProperty(assign[0],"");
setProperty(assign[0],"",source); setProperty(assign[0],"",source,replaceProps);
break; break;
default: default:
break; break;
@ -840,11 +852,14 @@ public class StartArgs
String key = arg.substring(0,idx); String key = arg.substring(0,idx);
String value = arg.substring(idx + 1); String value = arg.substring(idx + 1);
if (replaceProps)
{
if (propertySource.containsKey(key)) if (propertySource.containsKey(key))
{ {
StartLog.warn("Property %s in %s already set in %s",key,source,propertySource.get(key)); StartLog.warn("Property %s in %s already set in %s",key,source,propertySource.get(key));
} }
propertySource.put(key,source); propertySource.put(key,source);
}
if ("OPTION".equals(key) || "OPTIONS".equals(key)) if ("OPTION".equals(key) || "OPTIONS".equals(key))
{ {
@ -857,7 +872,7 @@ public class StartArgs
StartLog.warn(warn.toString()); StartLog.warn(warn.toString());
} }
setProperty(key,value,source); setProperty(key,value,source,replaceProps);
return; return;
} }
@ -886,6 +901,17 @@ public class StartArgs
throw new UsageException(ERR_BAD_ARG,"Unrecognized argument: \"%s\" in %s",arg,source); throw new UsageException(ERR_BAD_ARG,"Unrecognized argument: \"%s\" in %s",arg,source);
} }
public void parseModule(Module module)
{
if(module.hasDefaultConfig())
{
for(String line: module.getDefaultConfig())
{
parse(line,module.getFilesystemRef(),false);
}
}
}
public void resolveExtraXmls(BaseHome baseHome) throws IOException public void resolveExtraXmls(BaseHome baseHome) throws IOException
{ {
// Find and Expand XML files // Find and Expand XML files
@ -921,7 +947,7 @@ public class StartArgs
this.allModules = allModules; this.allModules = allModules;
} }
private void setProperty(String key, String value, String source) private void setProperty(String key, String value, String source, boolean replaceProp)
{ {
// Special / Prevent override from start.ini's // Special / Prevent override from start.ini's
if (key.equals("jetty.home")) if (key.equals("jetty.home"))
@ -938,8 +964,20 @@ public class StartArgs
} }
// Normal // Normal
if (replaceProp)
{
// always override
properties.setProperty(key,value,source); properties.setProperty(key,value,source);
} }
else
{
// only set if unset
if (!properties.containsKey(key))
{
properties.setProperty(key,value,source);
}
}
}
public void setRun(boolean run) public void setRun(boolean run)
{ {
@ -961,4 +999,5 @@ public class StartArgs
builder.append("]"); builder.append("]");
return builder.toString(); return builder.toString();
} }
} }

View File

@ -160,7 +160,7 @@ public class ConfigurationAssert
return value; return value;
} }
private static void assertContainsUnordered(String msg, Collection<String> expectedSet, Collection<String> actualSet) public static void assertContainsUnordered(String msg, Collection<String> expectedSet, Collection<String> actualSet)
{ {
// same size? // same size?
boolean mismatch = expectedSet.size() != actualSet.size(); boolean mismatch = expectedSet.size() != actualSet.size();

View File

@ -60,8 +60,8 @@ public class ModuleGraphWriterTest
StartArgs args = new StartArgs(); StartArgs args = new StartArgs();
args.parse(config); args.parse(config);
Modules modules = new Modules(); Modules modules = new Modules(basehome, args);
modules.registerAll(basehome, args); modules.registerAll();
modules.buildGraph(); modules.buildGraph();
Path outputFile = basehome.getBasePath("graph.dot"); Path outputFile = basehome.getBasePath("graph.dot");

View File

@ -19,7 +19,6 @@
package org.eclipse.jetty.start; package org.eclipse.jetty.start;
import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.is;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -66,8 +65,8 @@ public class ModulesTest
args.parse(config); args.parse(config);
// Test Modules // Test Modules
Modules modules = new Modules(); Modules modules = new Modules(basehome,args);
modules.registerAll(basehome,args); modules.registerAll();
List<String> moduleNames = new ArrayList<>(); List<String> moduleNames = new ArrayList<>();
for (Module mod : modules) for (Module mod : modules)
@ -80,11 +79,41 @@ public class ModulesTest
moduleNames.add(mod.getName()); moduleNames.add(mod.getName());
} }
String expected[] = { "jmx", "client", "stats", "spdy", "deploy", "debug", "security", "npn", "ext", "websocket", "rewrite", "ipaccess", "xinetd", List<String> expected = new ArrayList<>();
"proxy", "webapp", "jndi", "lowresources", "https", "plus", "requestlog", "jsp", "monitor", "xml", "servlet", "jaas", "http", "base", "server", expected.add("jmx");
"annotations", "resources", "loggging" }; expected.add("client");
expected.add("stats");
expected.add("spdy");
expected.add("deploy");
expected.add("debug");
expected.add("security");
expected.add("npn");
expected.add("ext");
expected.add("websocket");
expected.add("rewrite");
expected.add("ipaccess");
expected.add("xinetd");
expected.add("proxy");
expected.add("webapp");
expected.add("jndi");
expected.add("lowresources");
expected.add("https");
expected.add("plus");
expected.add("requestlog");
expected.add("jsp");
// (only present if enabled) expected.add("jsp-impl");
expected.add("monitor");
expected.add("xml");
expected.add("servlet");
expected.add("jaas");
expected.add("http");
expected.add("base");
expected.add("server");
expected.add("annotations");
expected.add("resources");
expected.add("logging");
Assert.assertThat("Module count: " + moduleNames,moduleNames.size(),is(expected.length)); ConfigurationAssert.assertContainsUnordered("All Modules",expected,moduleNames);
} }
@Test @Test
@ -93,7 +122,7 @@ public class ModulesTest
// Test Env // Test Env
File homeDir = MavenTestingUtils.getTestResourceDir("usecases/home"); File homeDir = MavenTestingUtils.getTestResourceDir("usecases/home");
File baseDir = testdir.getEmptyDir(); File baseDir = testdir.getEmptyDir();
String cmdLine[] = new String[] {"jetty.version=TEST"}; String cmdLine[] = new String[] {"jetty.version=TEST", "java.version=1.7.0_21"};
// Configuration // Configuration
CommandLineConfigSource cmdLineSource = new CommandLineConfigSource(cmdLine); CommandLineConfigSource cmdLineSource = new CommandLineConfigSource(cmdLine);
@ -109,13 +138,35 @@ public class ModulesTest
args.parse(config); args.parse(config);
// Test Modules // Test Modules
Modules modules = new Modules(); Modules modules = new Modules(basehome,args);
modules.registerAll(basehome,args); modules.registerAll();
modules.enable("[sj]{1}.*",TEST_SOURCE); modules.enable("[sj]{1}.*",TEST_SOURCE);
modules.buildGraph();
String expected[] = { "jmx", "stats", "spdy", "security", "jndi", "jsp", "servlet", "jaas", "server" }; List<String> expected = new ArrayList<>();
expected.add("jmx");
expected.add("stats");
expected.add("spdy");
expected.add("security");
expected.add("jndi");
expected.add("jsp");
expected.add("servlet");
expected.add("jaas");
expected.add("server");
// transitive
expected.add("base");
expected.add("npn");
expected.add("npn-boot");
expected.add("xml");
expected.add("jsp-impl");
Assert.assertThat("Enabled Module count",modules.resolveEnabled().size(),is(expected.length)); List<String> resolved = new ArrayList<>();
for (Module module : modules.resolveEnabled())
{
resolved.add(module.getName());
}
ConfigurationAssert.assertContainsUnordered("Enabled Modules",expected,resolved);
} }
@Test @Test
@ -140,14 +191,15 @@ public class ModulesTest
args.parse(config); args.parse(config);
// Test Modules // Test Modules
Modules modules = new Modules(); Modules modules = new Modules(basehome, args);
modules.registerAll(basehome,args); modules.registerAll();
modules.buildGraph();
// Enable 2 modules // Enable 2 modules
modules.enable("server",TEST_SOURCE); modules.enable("server",TEST_SOURCE);
modules.enable("http",TEST_SOURCE); modules.enable("http",TEST_SOURCE);
modules.buildGraph();
// Collect active module list // Collect active module list
List<Module> active = modules.resolveEnabled(); List<Module> active = modules.resolveEnabled();
@ -211,15 +263,16 @@ public class ModulesTest
args.parse(config); args.parse(config);
// Test Modules // Test Modules
Modules modules = new Modules(); Modules modules = new Modules(basehome,args);
modules.registerAll(basehome,args); modules.registerAll();
modules.buildGraph();
// modules.dump();
// Enable 2 modules // Enable 2 modules
modules.enable("websocket",TEST_SOURCE); modules.enable("websocket",TEST_SOURCE);
modules.enable("http",TEST_SOURCE); modules.enable("http",TEST_SOURCE);
modules.buildGraph();
// modules.dump();
// Collect active module list // Collect active module list
List<Module> active = modules.resolveEnabled(); List<Module> active = modules.resolveEnabled();

View File

@ -0,0 +1,85 @@
//
// ========================================================================
// Copyright (c) 1995-2014 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.start;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.junit.Test;
/**
* Test bad configuration scenarios.
*/
public class TestBadUseCases
{
private void assertBadConfig(String homeName, String baseName, String expectedErrorMessage, String... cmdLineArgs) throws Exception
{
File homeDir = MavenTestingUtils.getTestResourceDir("usecases/" + homeName);
File baseDir = MavenTestingUtils.getTestResourceDir("usecases/" + baseName);
Main main = new Main();
List<String> cmdLine = new ArrayList<>();
cmdLine.add("jetty.home=" + homeDir.getAbsolutePath());
cmdLine.add("jetty.base=" + baseDir.getAbsolutePath());
// cmdLine.add("--debug");
for (String arg : cmdLineArgs)
{
cmdLine.add(arg);
}
try
{
main.processCommandLine(cmdLine);
fail("Expected " + UsageException.class.getName());
}
catch (UsageException e)
{
assertThat("Usage error",e.getMessage(),containsString(expectedErrorMessage));
}
}
@Test
public void testBadJspCommandLine() throws Exception
{
assertBadConfig("home","base.with.jsp.default",
"Missing referenced dependency: jsp-impl/bad-jsp","jsp-impl=bad");
}
@Test
public void testBadJspImplName() throws Exception
{
assertBadConfig("home","base.with.jsp.bad",
"Missing referenced dependency: jsp-impl/bogus-jsp");
}
@Test
public void testWithSpdyBadNpnVersion() throws Exception
{
assertBadConfig("home","base.enable.spdy.bad.npn.version",
"Missing referenced dependency: npn/npn-1.7.0_01",
"java.version=1.7.0_01");
}
}

View File

@ -73,6 +73,30 @@ public class TestUseCases
assertUseCase("home","base.with.include.jetty.dirs","assert-include-jetty-dir-logging.txt"); assertUseCase("home","base.with.include.jetty.dirs","assert-include-jetty-dir-logging.txt");
} }
@Test
public void testWithJspDefault() throws Exception
{
assertUseCase("home","base.with.jsp.default","assert-jsp-apache.txt");
}
@Test
public void testWithJspApache() throws Exception
{
assertUseCase("home","base.with.jsp.apache","assert-jsp-apache.txt");
}
@Test
public void testWithJspGlassfish() throws Exception
{
assertUseCase("home","base.with.jsp.glassfish","assert-jsp-glassfish.txt");
}
@Test
public void testWithJspGlassfishCmdLine() throws Exception
{
assertUseCase("home","base.with.jsp.default","assert-jsp-glassfish.txt","jsp-impl=glassfish");
}
@Test @Test
public void testWithMissingNpnVersion() throws Exception public void testWithMissingNpnVersion() throws Exception
{ {
@ -85,12 +109,6 @@ public class TestUseCases
assertUseCase("home","base.enable.spdy","assert-enable-spdy.txt","java.version=1.7.0_21"); assertUseCase("home","base.enable.spdy","assert-enable-spdy.txt","java.version=1.7.0_21");
} }
@Test
public void testWithSpdyBadNpnVersion() throws Exception
{
assertUseCase("home","base.enable.spdy.bad.npn.version","assert-enable-spdy-bad-npn-version.txt","java.version=1.7.0_01");
}
@Test @Test
public void testWithDatabase() throws Exception public void testWithDatabase() throws Exception
{ {

View File

@ -0,0 +1,26 @@
# The XMLs we expect (order is important)
XML|${jetty.home}/etc/jetty.xml
XML|${jetty.home}/etc/jetty-http.xml
# The LIBs we expect (order is irrelevant)
LIB|${jetty.home}/lib/jetty-continuation-TEST.jar
LIB|${jetty.home}/lib/jetty-http-TEST.jar
LIB|${jetty.home}/lib/jetty-io-TEST.jar
LIB|${jetty.home}/lib/jetty-schemas-3.1.jar
LIB|${jetty.home}/lib/jetty-server-TEST.jar
LIB|${jetty.home}/lib/jetty-servlet-TEST.jar
LIB|${jetty.home}/lib/jetty-util-TEST.jar
LIB|${jetty.home}/lib/jetty-xml-TEST.jar
LIB|${jetty.home}/lib/servlet-api-3.1.jar
LIB|${jetty.home}/lib/apache-jsp/javax.servlet.jsp.javax.servlet.jsp-api-TEST.jar
LIB|${jetty.home}/lib/apache-jsp/org.eclipse.jetty.apache-jsp-TEST.jar
LIB|${jetty.home}/lib/apache-jsp/org.eclipse.jetty.orbit.org.eclipse.jdt.core-TEST.jar
LIB|${jetty.home}/lib/apache-jsp/org.mortbay.jasper.apache-el-TEST.jar
LIB|${jetty.home}/lib/apache-jsp/org.mortbay.jasper.apache-jsp-TEST.jar
# The Properties we expect (order is irrelevant)
PROP|jetty.port=9090
PROP|jsp-impl=apache
# Files / Directories to create
# FILE|lib/

View File

@ -0,0 +1,28 @@
# The XMLs we expect (order is important)
XML|${jetty.home}/etc/jetty.xml
XML|${jetty.home}/etc/jetty-http.xml
# The LIBs we expect (order is irrelevant)
LIB|${jetty.home}/lib/jetty-continuation-TEST.jar
LIB|${jetty.home}/lib/jetty-http-TEST.jar
LIB|${jetty.home}/lib/jetty-io-TEST.jar
LIB|${jetty.home}/lib/jetty-schemas-3.1.jar
LIB|${jetty.home}/lib/jetty-server-TEST.jar
LIB|${jetty.home}/lib/jetty-servlet-TEST.jar
LIB|${jetty.home}/lib/jetty-util-TEST.jar
LIB|${jetty.home}/lib/jetty-xml-TEST.jar
LIB|${jetty.home}/lib/servlet-api-3.1.jar
LIB|${jetty.home}/lib/jsp/javax.el-TEST.jar
LIB|${jetty.home}/lib/jsp/javax.servlet.jsp.jstl-TEST.jar
LIB|${jetty.home}/lib/jsp/javax.servlet.jsp-api-TEST.jar
LIB|${jetty.home}/lib/jsp/javax.servlet.jsp-TEST.jar
LIB|${jetty.home}/lib/jsp/jetty-jsp-jdt-TEST.jar
LIB|${jetty.home}/lib/jsp/org.eclipse.jdt.core-TEST.jar
LIB|${jetty.home}/lib/jsp/org.eclipse.jetty.orbit.javax.servlet.jsp.jstl-TEST.jar
# The Properties we expect (order is irrelevant)
PROP|jetty.port=9090
PROP|jsp-impl=glassfish
# Files / Directories to create
# FILE|lib/

View File

@ -0,0 +1,7 @@
--module=server
--module=http
--module=jsp
jsp-impl=apache
jetty.port=9090

View File

@ -0,0 +1,7 @@
--module=server
--module=http
--module=jsp
jsp-impl=bogus
jetty.port=9090

View File

@ -0,0 +1,6 @@
--module=server
--module=http
--module=jsp
jetty.port=9090

View File

@ -0,0 +1,7 @@
--module=server
--module=http
--module=jsp
jsp-impl=glassfish
jetty.port=9090

View File

@ -0,0 +1,10 @@
#
# Apache JSP Module
#
[name]
jsp-impl
[lib]
lib/apache-jsp/*.jar

View File

@ -0,0 +1,8 @@
#
# Glassfish JSP Module
#
[name]
jsp-impl
[lib]
lib/jsp/*.jar

View File

@ -1,10 +1,20 @@
# #
# Jetty Servlet Module # Jetty JSP Module
# #
[depend] [depend]
servlet servlet
jsp-impl/${jsp-impl}-jsp
[lib] [ini-template]
lib/jsp/*.jar # JSP Configuration
# Select JSP implementation, choices are
# glassfish : The reference implementation
# default in jetty <= 9.1
# apache : The apache version
# default jetty >= 9.2
jsp-impl=apache
# To use a non-jdk compiler for JSP compilation when using glassfish uncomment next line
# -Dorg.apache.jasper.compiler.disablejsr199=true