diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/Module.java b/jetty-start/src/main/java/org/eclipse/jetty/start/Module.java new file mode 100644 index 00000000000..776bce8e91e --- /dev/null +++ b/jetty-start/src/main/java/org/eclipse/jetty/start/Module.java @@ -0,0 +1,260 @@ +// +// ======================================================================== +// Copyright (c) 1995-2013 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 java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.text.CollationKey; +import java.text.Collator; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Set; +import java.util.regex.Pattern; + +/** + * Represents a Module metadata, as defined in Jetty. + */ +public class Module +{ + public static class DepthComparator implements Comparator + { + private Collator collator = Collator.getInstance(); + + @Override + public int compare(Module o1, Module o2) + { + // order by depth first. + int diff = o1.depth - o2.depth; + if (diff != 0) + { + return diff; + } + // then by name (not really needed, but makes for predictable test cases) + CollationKey k1 = collator.getCollationKey(o1.name); + CollationKey k2 = collator.getCollationKey(o2.name); + return k1.compareTo(k2); + } + } + + public static Module fromFile(File file) throws IOException + { + String name = file.getName(); + + // Strip .ini + name = Pattern.compile(".mod$",Pattern.CASE_INSENSITIVE).matcher(name).replaceFirst(""); + + // XML Pattern + Pattern xmlPattern = Pattern.compile(".xml$",Pattern.CASE_INSENSITIVE); + + Set parents = new HashSet<>(); + List xmls = new ArrayList<>(); + List libs = new ArrayList<>(); + try (FileReader reader = new FileReader(file)) + { + try (BufferedReader buf = new BufferedReader(reader)) + { + String line; + while ((line = buf.readLine()) != null) + { + line = line.trim(); + if (line.length() <= 0) + { + continue; // skip empty lines + } + if (line.charAt(0) == '#') + { + continue; // skip lines with comments + } + + // has assignment + int idx = line.indexOf('='); + if (idx >= 0) + { + String key = line.substring(0,idx); + String value = line.substring(idx + 1); + + boolean handled = false; + switch (key.toUpperCase(Locale.ENGLISH)) + { + case "DEPEND": + parents.add(value); + handled = true; + break; + case "LIB": + libs.add(value); + handled = true; + break; + } + if (handled) + { + continue; // no further processing of line needed + } + } + + // Is it an XML line? + if (xmlPattern.matcher(line).find()) + { + xmls.add(line); + continue; // legit xml + } + + throw new IllegalArgumentException("Unrecognized Module Metadata line [" + line + "] in Module file [" + file + "]"); + } + } + } + + return new Module(name,parents,xmls,libs); + } + + /** The name of this Module */ + private final String name; + /** List of Modules, by name, that this Module depends on */ + private final Set parentNames; + /** The Edges to parent modules */ + private final Set parentEdges; + /** The Edges to child modules */ + private final Set childEdges; + /** The depth of the module in the tree */ + private int depth = 0; + /** List of xml configurations for this Module */ + private final List xmls; + /** List of library options for this Module */ + private final List libs; + + /** Is this Module enabled via start.jar command line, start.ini, or start.d/*.ini ? */ + private boolean enabled = false; + + public Module(String name, Set parentNames, List xmls, List libs) + { + this.name = name; + this.parentNames = parentNames; + this.xmls = xmls; + this.libs = libs; + + // initialize edge collections, will be filled out by Modules#buildGraph() later */ + this.parentEdges = new HashSet<>(); + this.childEdges = new HashSet<>(); + } + + public void addChildEdge(Module child) + { + this.childEdges.add(child); + } + + public void addParentEdge(Module parent) + { + this.parentEdges.add(parent); + } + + public Set getChildEdges() + { + return childEdges; + } + + public int getDepth() + { + return depth; + } + + public List getLibs() + { + return libs; + } + + public String getName() + { + return name; + } + + public Set getParentEdges() + { + return parentEdges; + } + + public Set getParentNames() + { + return parentNames; + } + + public List getXmls() + { + return xmls; + } + + public boolean isEnabled() + { + return enabled; + } + + @Override + public int hashCode() + { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null)?0:name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Module other = (Module)obj; + if (name == null) + { + if (other.name != null) + return false; + } + else if (!name.equals(other.name)) + return false; + return true; + } + + public void setDepth(int depth) + { + this.depth = depth; + } + + public void setEnabled(boolean enabled) + { + this.enabled = enabled; + } + + public String toString() + { + StringBuilder str = new StringBuilder(); + str.append("Module[").append(name); + if (enabled) + { + str.append(",enabled"); + } + str.append(']'); + return str.toString(); + } +} diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/Modules.java b/jetty-start/src/main/java/org/eclipse/jetty/start/Modules.java new file mode 100644 index 00000000000..3d57279d1df --- /dev/null +++ b/jetty-start/src/main/java/org/eclipse/jetty/start/Modules.java @@ -0,0 +1,235 @@ +// +// ======================================================================== +// Copyright (c) 1995-2013 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 java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Access for all modules declared, as well as what is enabled. + */ +public class Modules implements Iterable +{ + private Map modules = new HashMap<>(); + + public void register(Module module) + { + modules.put(module.getName(),module); + } + + private void bfsCalculateDepth(final Module module, final int depthNow) + { + int depth = depthNow + 1; + + // Set depth on every child first + for (Module child : module.getChildEdges()) + { + child.setDepth(Math.max(depth,child.getDepth())); + } + + // Dive down + for (Module child : module.getChildEdges()) + { + bfsCalculateDepth(child,depth); + } + } + + /** + * Using the provided dependenies, build the module graph + */ + public void buildGraph() + { + // TODO: Validate / Enforce Directed Acyclic Graph + + // Connect edges + for (Module module : modules.values()) + { + for (String parentName : module.getParentNames()) + { + Module parent = get(parentName); + if (parent != null) + { + module.addParentEdge(parent); + parent.addChildEdge(module); + } + } + } + + // Calculate depth of all modules for sorting later + for (Module module : modules.values()) + { + if (module.getParentEdges().isEmpty()) + { + bfsCalculateDepth(module,0); + } + } + } + + public Integer count() + { + return modules.size(); + } + + public void enable(String name) + { + Module module = modules.get(name); + if (module == null) + { + System.err.printf("WARNING: Cannot enable requested module [%s]: not a valid module name.%n",name); + return; + } + module.setEnabled(true); + } + + private void findParents(Module module, Set active) + { + active.add(module); + for (Module parent : module.getParentEdges()) + { + active.add(parent); + findParents(parent,active); + } + } + + public void dump() + { + List ordered = new ArrayList<>(); + ordered.addAll(modules.values()); + Collections.sort(ordered,Collections.reverseOrder(new Module.DepthComparator())); + + for (Module module : ordered) + { + System.out.printf("Module: %s%n",module.getName()); + System.out.printf(" depth: %d%n",module.getDepth()); + System.out.printf(" parents: [%s]%n",join(module.getParentNames(),',')); + for (String xml : module.getXmls()) + { + System.out.printf(" xml: %s%n",xml); + } + } + } + + private String join(Collection objs, char delim) + { + StringBuilder str = new StringBuilder(); + boolean needDelim = false; + for (Object obj : objs) + { + if (needDelim) + { + str.append(delim); + } + str.append(obj); + needDelim = true; + } + return str.toString(); + } + + public Module get(String name) + { + Module module = modules.get(name); + if (module == null) + { + System.err.printf("WARNING: module not found [%s]%n",name); + } + return module; + } + + @Override + public Iterator iterator() + { + return modules.values().iterator(); + } + + /** + * Resolve the execution order of the enabled modules, and all dependant modules, based on depth first transitive reduction. + * + * @return the list of active modules (plus dependant modules), in execution order. + */ + public List resolveEnabled() + { + Set active = new HashSet(); + + for (Module module : modules.values()) + { + if (module.isEnabled()) + { + findParents(module,active); + } + } + + List ordered = new ArrayList<>(); + ordered.addAll(active); + Collections.sort(ordered,new Module.DepthComparator()); + return ordered; + } + + // TODO: Resolve LIB names to actual java.io.File references via HomeBase + // TODO: Handle ${jetty.version} references here + // TODO: Handle *.jar filesystem glob style here + public List normalizeLibs(List active) + { + List libs = new ArrayList<>(); + for (Module module : active) + { + for (String lib : module.getLibs()) + { + if (!libs.contains(lib)) + { + libs.add(lib); + } + } + } + return libs; + } + + // TODO: Resolve XML names to actual java.io.File references via HomeBase + public List normalizeXmls(List active) + { + List xmls = new ArrayList<>(); + for (Module module : active) + { + for (String xml : module.getXmls()) + { + if (!xmls.contains(xml)) + { + xmls.add(xml); + } + } + } + return xmls; + } + + public void registerAll(BaseHome basehome) throws IOException + { + for (File file : basehome.listFiles("modules",new FS.FilenameRegexFilter("^.*\\.mod$"))) + { + register(Module.fromFile(file)); + } + } +} diff --git a/jetty-start/src/test/java/org/eclipse/jetty/start/ModuleTest.java b/jetty-start/src/test/java/org/eclipse/jetty/start/ModuleTest.java new file mode 100644 index 00000000000..d283ba1befe --- /dev/null +++ b/jetty-start/src/test/java/org/eclipse/jetty/start/ModuleTest.java @@ -0,0 +1,51 @@ +// +// ======================================================================== +// Copyright (c) 1995-2013 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 java.io.File; +import java.io.IOException; + +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.junit.Assert; +import org.junit.Test; + +public class ModuleTest +{ + private Module loadTestHomeModule(String moduleFileName) throws IOException + { + File file = MavenTestingUtils.getTestResourceFile("usecases/home/modules/" + moduleFileName); + return Module.fromFile(file); + } + + @Test + public void testLoadWebSocket() throws IOException + { + Module Module = loadTestHomeModule("websocket.mod"); + + Assert.assertThat("Module Name",Module.getName(),is("websocket")); + Assert.assertThat("Module Parents Size",Module.getParentNames().size(),is(2)); + Assert.assertThat("Module Parents",Module.getParentNames(),containsInAnyOrder("annotations","server")); + Assert.assertThat("Module Xmls Size",Module.getXmls().size(),is(1)); + Assert.assertThat("Module Xmls",Module.getXmls(),contains("etc/jetty-websocket.xml")); + Assert.assertThat("Module Options Size",Module.getLibs().size(),is(1)); + Assert.assertThat("Module Options",Module.getLibs(),contains("lib/websockets/*.jar")); + } +} diff --git a/jetty-start/src/test/java/org/eclipse/jetty/start/ModulesTest.java b/jetty-start/src/test/java/org/eclipse/jetty/start/ModulesTest.java new file mode 100644 index 00000000000..101e128646d --- /dev/null +++ b/jetty-start/src/test/java/org/eclipse/jetty/start/ModulesTest.java @@ -0,0 +1,163 @@ +// +// ======================================================================== +// Copyright (c) 1995-2013 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 java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.junit.Assert; +import org.junit.Test; + +public class ModulesTest +{ + @Test + public void testLoadAllModules() throws IOException + { + File homeDir = MavenTestingUtils.getTestResourceDir("usecases/home"); + BaseHome basehome = new BaseHome(homeDir,homeDir); + + Modules modules = new Modules(); + modules.registerAll(basehome); + Assert.assertThat("Module count",modules.count(),is(11)); + } + + @Test + public void testResolve_ServerHttp() throws IOException + { + File homeDir = MavenTestingUtils.getTestResourceDir("usecases/home"); + BaseHome basehome = new BaseHome(homeDir,homeDir); + + // Register modules + Modules modules = new Modules(); + modules.registerAll(basehome); + modules.buildGraph(); + + // Enable 2 modules + modules.enable("server"); + modules.enable("http"); + + // Collect active module list + List active = modules.resolveEnabled(); + + // Assert names are correct, and in the right order + List expectedNames = new ArrayList<>(); + expectedNames.add("base"); + expectedNames.add("server"); + expectedNames.add("http"); + + List actualNames = new ArrayList<>(); + for (Module actual : active) + { + actualNames.add(actual.getName()); + } + + Assert.assertThat("Resolved Names: " + actualNames,actualNames,contains(expectedNames.toArray())); + + // Assert Library List + List expectedLibs = new ArrayList<>(); + expectedLibs.add("lib/jetty-util-${jetty.version}.jar"); + expectedLibs.add("lib/jetty-io-${jetty.version}.jar"); + expectedLibs.add("lib/servlet-api-3.1.jar"); + expectedLibs.add("lib/jetty-schemas-3.1.jar"); + expectedLibs.add("lib/jetty-http-${jetty.version}.jar"); + expectedLibs.add("lib/jetty-continuation-${jetty.version}.jar"); + expectedLibs.add("lib/jetty-server-${jetty.version}.jar"); + + List actualLibs = modules.normalizeLibs(active); + Assert.assertThat("Resolved Libs: " + actualLibs,actualLibs,contains(expectedLibs.toArray())); + + // Assert XML List + List expectedXmls = new ArrayList<>(); + expectedXmls.add("etc/jetty.xml"); + expectedXmls.add("etc/jetty-http.xml"); + + List actualXmls = modules.normalizeXmls(active); + Assert.assertThat("Resolved XMLs: " + actualXmls,actualXmls,contains(expectedXmls.toArray())); + } + + @Test + public void testResolve_WebSocket() throws IOException + { + File homeDir = MavenTestingUtils.getTestResourceDir("usecases/home"); + BaseHome basehome = new BaseHome(homeDir,homeDir); + + // Register modules + Modules modules = new Modules(); + modules.registerAll(basehome); + modules.buildGraph(); + // modules.dump(); + + // Enable 2 modules + modules.enable("websocket"); + modules.enable("http"); + + // Collect active module list + List active = modules.resolveEnabled(); + + // Assert names are correct, and in the right order + List expectedNames = new ArrayList<>(); + expectedNames.add("base"); + expectedNames.add("server"); + expectedNames.add("http"); + expectedNames.add("plus"); + expectedNames.add("annotations"); + expectedNames.add("websocket"); + + List actualNames = new ArrayList<>(); + for (Module actual : active) + { + actualNames.add(actual.getName()); + } + + Assert.assertThat("Resolved Names: " + actualNames,actualNames,contains(expectedNames.toArray())); + + // Assert Library List + List expectedLibs = new ArrayList<>(); + expectedLibs.add("lib/jetty-util-${jetty.version}.jar"); + expectedLibs.add("lib/jetty-io-${jetty.version}.jar"); + expectedLibs.add("lib/servlet-api-3.1.jar"); + expectedLibs.add("lib/jetty-schemas-3.1.jar"); + expectedLibs.add("lib/jetty-http-${jetty.version}.jar"); + expectedLibs.add("lib/jetty-continuation-${jetty.version}.jar"); + expectedLibs.add("lib/jetty-server-${jetty.version}.jar"); + expectedLibs.add("lib/jetty-plus-${jetty.version}.xml"); + expectedLibs.add("lib/jetty-annotations-${jetty.version}.jar"); + expectedLibs.add("lib/annotations/*.jar"); + expectedLibs.add("lib/websockets/*.jar"); + + List actualLibs = modules.normalizeLibs(active); + Assert.assertThat("Resolved Libs: " + actualLibs,actualLibs,contains(expectedLibs.toArray())); + + // Assert XML List + List expectedXmls = new ArrayList<>(); + expectedXmls.add("etc/jetty.xml"); + expectedXmls.add("etc/jetty-http.xml"); + expectedXmls.add("etc/jetty-plus.xml"); + expectedXmls.add("etc/jetty-annotations.xml"); + expectedXmls.add("etc/jetty-websocket.xml"); + + List actualXmls = modules.normalizeXmls(active); + Assert.assertThat("Resolved XMLs: " + actualXmls,actualXmls,contains(expectedXmls.toArray())); + } +} diff --git a/jetty-start/src/test/resources/usecases/base.barebones/start.ini b/jetty-start/src/test/resources/usecases/base.barebones/start.ini new file mode 100644 index 00000000000..b2f200b6cac --- /dev/null +++ b/jetty-start/src/test/resources/usecases/base.barebones/start.ini @@ -0,0 +1,4 @@ + +MODULES=server,http + +jetty.port=9090 diff --git a/jetty-start/src/test/resources/usecases/home/modules/annotations.mod b/jetty-start/src/test/resources/usecases/home/modules/annotations.mod new file mode 100644 index 00000000000..3470bf75c79 --- /dev/null +++ b/jetty-start/src/test/resources/usecases/home/modules/annotations.mod @@ -0,0 +1,14 @@ +# +# Jetty Annotation Scanning Module +# + +# Annotations needs plus, and jndi features +DEPEND=plus + +# Annotations needs jetty annotation jars +LIB=lib/jetty-annotations-${jetty.version}.jar +# Need annotation processing jars too +LIB=lib/annotations/*.jar + +# Enable annotation scanning webapp configurations +etc/jetty-annotations.xml diff --git a/jetty-start/src/test/resources/usecases/home/modules/base.mod b/jetty-start/src/test/resources/usecases/home/modules/base.mod new file mode 100644 index 00000000000..f85269aa64c --- /dev/null +++ b/jetty-start/src/test/resources/usecases/home/modules/base.mod @@ -0,0 +1,6 @@ +# +# Base Module +# + +LIB=lib/jetty-util-${jetty.version}.jar +LIB=lib/jetty-io-${jetty.version}.jar diff --git a/jetty-start/src/test/resources/usecases/home/modules/http.mod b/jetty-start/src/test/resources/usecases/home/modules/http.mod new file mode 100644 index 00000000000..b8d4045eb8d --- /dev/null +++ b/jetty-start/src/test/resources/usecases/home/modules/http.mod @@ -0,0 +1,4 @@ + +DEPEND=server + +etc/jetty-http.xml diff --git a/jetty-start/src/test/resources/usecases/home/modules/https.mod b/jetty-start/src/test/resources/usecases/home/modules/https.mod new file mode 100644 index 00000000000..69784924390 --- /dev/null +++ b/jetty-start/src/test/resources/usecases/home/modules/https.mod @@ -0,0 +1,5 @@ + +DEPEND=server + +etc/jetty-ssl.xml +etc/jetty-https.xml diff --git a/jetty-start/src/test/resources/usecases/home/modules/jmx.mod b/jetty-start/src/test/resources/usecases/home/modules/jmx.mod new file mode 100644 index 00000000000..2a7922690e9 --- /dev/null +++ b/jetty-start/src/test/resources/usecases/home/modules/jmx.mod @@ -0,0 +1,9 @@ +# +# JMX Feature +# + +# JMX jars (as defined in start.config) +LIB=lib/jetty-jmx-${jetty.version}.jar + +# JMX configuration +etc/jetty-jmx.xml diff --git a/jetty-start/src/test/resources/usecases/home/modules/jndi.mod b/jetty-start/src/test/resources/usecases/home/modules/jndi.mod new file mode 100644 index 00000000000..de3087bd26f --- /dev/null +++ b/jetty-start/src/test/resources/usecases/home/modules/jndi.mod @@ -0,0 +1,12 @@ +# +# JNDI Support +# + +DEPEND=server +DEPEND=plus + +LIB=lib/jetty-jndi-${jetty.version}.jar +LIB=lib/jndi/*.jar + +# Annotations needs annotations configuration +etc/jetty-server.xml diff --git a/jetty-start/src/test/resources/usecases/home/modules/plus.mod b/jetty-start/src/test/resources/usecases/home/modules/plus.mod new file mode 100644 index 00000000000..bc2b1af55a9 --- /dev/null +++ b/jetty-start/src/test/resources/usecases/home/modules/plus.mod @@ -0,0 +1,9 @@ +# +# Jetty Plus Module +# + +DEPEND=server + +LIB=lib/jetty-plus-${jetty.version}.xml + +etc/jetty-plus.xml diff --git a/jetty-start/src/test/resources/usecases/home/modules/server.mod b/jetty-start/src/test/resources/usecases/home/modules/server.mod new file mode 100644 index 00000000000..06bf6772f5b --- /dev/null +++ b/jetty-start/src/test/resources/usecases/home/modules/server.mod @@ -0,0 +1,14 @@ +# +# Base server +# + +DEPEND=base + +LIB=lib/servlet-api-3.1.jar +LIB=lib/jetty-schemas-3.1.jar +LIB=lib/jetty-http-${jetty.version}.jar +LIB=lib/jetty-continuation-${jetty.version}.jar +LIB=lib/jetty-server-${jetty.version}.jar + +# Annotations needs annotations configuration +etc/jetty.xml diff --git a/jetty-start/src/test/resources/usecases/home/modules/spdy.mod b/jetty-start/src/test/resources/usecases/home/modules/spdy.mod new file mode 100644 index 00000000000..4a70136f556 --- /dev/null +++ b/jetty-start/src/test/resources/usecases/home/modules/spdy.mod @@ -0,0 +1,5 @@ + +DEPEND=server + +etc/jetty-ssl.xml +etc/jetty-spdy.xml diff --git a/jetty-start/src/test/resources/usecases/home/modules/websocket.mod b/jetty-start/src/test/resources/usecases/home/modules/websocket.mod new file mode 100644 index 00000000000..1984482f809 --- /dev/null +++ b/jetty-start/src/test/resources/usecases/home/modules/websocket.mod @@ -0,0 +1,14 @@ +# +# WebSocket Feature +# + +# WebSocket needs Annotations feature +DEPEND=server +DEPEND=annotations + +# WebSocket needs websocket jars (as defined in start.config) +LIB=lib/websockets/*.jar + +# WebSocket needs websocket configuration +etc/jetty-websocket.xml + diff --git a/jetty-start/src/test/resources/usecases/home/modules/xml.mod b/jetty-start/src/test/resources/usecases/home/modules/xml.mod new file mode 100644 index 00000000000..949e2057117 --- /dev/null +++ b/jetty-start/src/test/resources/usecases/home/modules/xml.mod @@ -0,0 +1,8 @@ +# +# Jetty XML Configuration +# + +DEPEND=base + +LIB=lib/jetty-xml-${jetty.version}.jar + diff --git a/jetty-start/src/test/resources/usecases/home/start.ini b/jetty-start/src/test/resources/usecases/home/start.ini new file mode 100644 index 00000000000..920774011d6 --- /dev/null +++ b/jetty-start/src/test/resources/usecases/home/start.ini @@ -0,0 +1,2 @@ + +MODULES=server,http,jmx,annotations,websocket