Merge branch 'jetty-9.4.x' into jetty-10.0.x
This commit is contained in:
commit
1c4a21c9be
|
@ -13,7 +13,7 @@ session-store
|
||||||
sessions
|
sessions
|
||||||
|
|
||||||
[files]
|
[files]
|
||||||
maven://com.hazelcast/hazelcast/3.9.4|lib/hazelcast/hazelcast-3.9.4.jar
|
maven://com.hazelcast/hazelcast/3.12.6|lib/hazelcast/hazelcast-3.12.6.jar
|
||||||
|
|
||||||
[xml]
|
[xml]
|
||||||
etc/sessions/hazelcast/default.xml
|
etc/sessions/hazelcast/default.xml
|
||||||
|
|
|
@ -13,8 +13,8 @@ session-store
|
||||||
sessions
|
sessions
|
||||||
|
|
||||||
[files]
|
[files]
|
||||||
maven://com.hazelcast/hazelcast/3.9.4|lib/hazelcast/hazelcast-3.9.4.jar
|
maven://com.hazelcast/hazelcast/3.12.6|lib/hazelcast/hazelcast-3.12.6.jar
|
||||||
maven://com.hazelcast/hazelcast-client/3.9.4|lib/hazelcast/hazelcast-client-3.9.4.jar
|
maven://com.hazelcast/hazelcast-client/3.12.6|lib/hazelcast/hazelcast-client-3.12.6.jar
|
||||||
|
|
||||||
[xml]
|
[xml]
|
||||||
etc/sessions/hazelcast/remote.xml
|
etc/sessions/hazelcast/remote.xml
|
||||||
|
|
|
@ -20,7 +20,6 @@ package org.eclipse.jetty.start;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.BufferedWriter;
|
import java.io.BufferedWriter;
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
@ -154,12 +153,12 @@ public class Module implements Comparable<Module>
|
||||||
private final List<String> _license = new ArrayList<>();
|
private final List<String> _license = new ArrayList<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dependencies
|
* Dependencies from {@code [depends]} section
|
||||||
*/
|
*/
|
||||||
private final List<String> _depends = new ArrayList<>();
|
private final List<String> _depends = new ArrayList<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optional
|
* Optional dependencies from {@code [optional]} section are structural in nature.
|
||||||
*/
|
*/
|
||||||
private final Set<String> _optional = new HashSet<>();
|
private final Set<String> _optional = new HashSet<>();
|
||||||
|
|
||||||
|
@ -196,6 +195,18 @@ public class Module implements Comparable<Module>
|
||||||
process(basehome);
|
process(basehome);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isRequiredDependency(String depends)
|
||||||
|
{
|
||||||
|
return (depends != null) && (depends.charAt(0) != '?');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String normalizeModuleName(String name)
|
||||||
|
{
|
||||||
|
if (!isRequiredDependency(name))
|
||||||
|
return name.substring(1);
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
public String getName()
|
public String getName()
|
||||||
{
|
{
|
||||||
return _name;
|
return _name;
|
||||||
|
|
|
@ -247,6 +247,7 @@ public class ModuleGraphWriter
|
||||||
{
|
{
|
||||||
for (String depends : module.getDepends())
|
for (String depends : module.getDepends())
|
||||||
{
|
{
|
||||||
|
depends = Module.normalizeModuleName(depends);
|
||||||
out.printf(" \"%s\" -> \"%s\";%n", module.getName(), depends);
|
out.printf(" \"%s\" -> \"%s\";%n", module.getName(), depends);
|
||||||
}
|
}
|
||||||
for (String optional : module.getOptional())
|
for (String optional : module.getOptional())
|
||||||
|
|
|
@ -20,6 +20,7 @@ package org.eclipse.jetty.start;
|
||||||
|
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -132,7 +133,12 @@ public class Modules implements Iterable<Module>
|
||||||
label = " Depend: %s";
|
label = " Depend: %s";
|
||||||
for (String parent : module.getDepends())
|
for (String parent : module.getDepends())
|
||||||
{
|
{
|
||||||
|
parent = Module.normalizeModuleName(parent);
|
||||||
System.out.printf(label, parent);
|
System.out.printf(label, parent);
|
||||||
|
if (!Module.isRequiredDependency(parent))
|
||||||
|
{
|
||||||
|
System.out.print(" [not-required]");
|
||||||
|
}
|
||||||
label = ", %s";
|
label = ", %s";
|
||||||
}
|
}
|
||||||
System.out.println();
|
System.out.println();
|
||||||
|
@ -353,45 +359,59 @@ public class Modules implements Iterable<Module>
|
||||||
|
|
||||||
// Process module dependencies (always processed as may be dynamic)
|
// Process module dependencies (always processed as may be dynamic)
|
||||||
StartLog.debug("Enabled module %s depends on %s", module.getName(), module.getDepends());
|
StartLog.debug("Enabled module %s depends on %s", module.getName(), module.getDepends());
|
||||||
for (String dependsOn : module.getDepends())
|
for (String dependsOnRaw : module.getDepends())
|
||||||
{
|
{
|
||||||
// Look for modules that provide that dependency
|
boolean isRequired = Module.isRequiredDependency(dependsOnRaw);
|
||||||
Set<Module> providers = getAvailableProviders(dependsOn);
|
// Final to allow lambda's below to use name
|
||||||
|
final String dependentModule = Module.normalizeModuleName(dependsOnRaw);
|
||||||
|
|
||||||
StartLog.debug("Module %s depends on %s provided by %s", module, dependsOn, providers);
|
// Look for modules that provide that dependency
|
||||||
|
Set<Module> providers = getAvailableProviders(dependentModule);
|
||||||
|
|
||||||
|
StartLog.debug("Module %s depends on %s provided by %s", module, dependentModule, providers);
|
||||||
|
|
||||||
// If there are no known providers of the module
|
// If there are no known providers of the module
|
||||||
if (providers.isEmpty())
|
if (providers.isEmpty())
|
||||||
{
|
{
|
||||||
// look for a dynamic module
|
// look for a dynamic module
|
||||||
if (dependsOn.contains("/"))
|
if (dependentModule.contains("/"))
|
||||||
{
|
{
|
||||||
Path file = _baseHome.getPath("modules/" + dependsOn + ".mod");
|
Path file = _baseHome.getPath("modules/" + dependentModule + ".mod");
|
||||||
registerModule(file).expandDependencies(_args.getProperties());
|
if (isRequired || Files.exists(file))
|
||||||
providers = _provided.get(dependsOn);
|
{
|
||||||
if (providers == null || providers.isEmpty())
|
registerModule(file).expandDependencies(_args.getProperties());
|
||||||
throw new UsageException("Module %s does not provide %s", _baseHome.toShortForm(file), dependsOn);
|
providers = _provided.get(dependentModule);
|
||||||
|
if (providers == null || providers.isEmpty())
|
||||||
|
throw new UsageException("Module %s does not provide %s", _baseHome.toShortForm(file), dependentModule);
|
||||||
|
|
||||||
enable(newlyEnabled, providers.stream().findFirst().get(), "dynamic dependency of " + module.getName(), true);
|
enable(newlyEnabled, providers.stream().findFirst().get(), "dynamic dependency of " + module.getName(), true);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// is this a non-required module
|
||||||
|
if (!isRequired)
|
||||||
|
{
|
||||||
|
StartLog.debug("Skipping non-required module [%s]: doesn't exist", dependentModule);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
throw new UsageException("No module found to provide %s for %s", dependsOn, module);
|
// throw an exception (not a dynamic module and a required dependency)
|
||||||
|
throw new UsageException("No module found to provide %s for %s", dependentModule, module);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If a provider is already enabled, then add a transitive enable
|
// If a provider is already enabled, then add a transitive enable
|
||||||
if (providers.stream().filter(Module::isEnabled).count() > 0)
|
if (providers.stream().anyMatch(Module::isEnabled))
|
||||||
providers.stream().filter(m -> m.isEnabled() && !m.equals(module)).forEach(m -> enable(newlyEnabled, m, "transitive provider of " + dependsOn + " for " + module.getName(), true));
|
providers.stream().filter(m -> m.isEnabled() && !m.equals(module)).forEach(m -> enable(newlyEnabled, m, "transitive provider of " + dependentModule + " for " + module.getName(), true));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Is there an obvious default?
|
// Is there an obvious default?
|
||||||
Optional<Module> dftProvider = (providers.size() == 1)
|
Optional<Module> dftProvider = (providers.size() == 1)
|
||||||
? providers.stream().findFirst()
|
? providers.stream().findFirst()
|
||||||
: providers.stream().filter(m -> m.getName().equals(dependsOn)).findFirst();
|
: providers.stream().filter(m -> m.getName().equals(dependentModule)).findFirst();
|
||||||
|
|
||||||
if (dftProvider.isPresent())
|
if (dftProvider.isPresent())
|
||||||
enable(newlyEnabled, dftProvider.get(), "transitive provider of " + dependsOn + " for " + module.getName(), true);
|
enable(newlyEnabled, dftProvider.get(), "transitive provider of " + dependentModule + " for " + module.getName(), true);
|
||||||
else if (StartLog.isDebugEnabled())
|
else if (StartLog.isDebugEnabled())
|
||||||
StartLog.debug("Module %s requires a %s implementation from one of %s", module, dependsOn, providers);
|
StartLog.debug("Module %s requires a %s implementation from one of %s", module, dependentModule, providers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,8 @@ import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hamcrest.Matchers.contains;
|
import static org.hamcrest.Matchers.contains;
|
||||||
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.hamcrest.Matchers.nullValue;
|
||||||
|
|
||||||
@ExtendWith(WorkDirExtension.class)
|
@ExtendWith(WorkDirExtension.class)
|
||||||
public class ModulesTest
|
public class ModulesTest
|
||||||
|
@ -202,6 +204,152 @@ public class ModulesTest
|
||||||
assertThat("Resolved XMLs: " + actualXmls, actualXmls, contains(expectedXmls.toArray()));
|
assertThat("Resolved XMLs: " + actualXmls, actualXmls, contains(expectedXmls.toArray()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testResolveNotRequiredModuleNotFound() throws IOException
|
||||||
|
{
|
||||||
|
// Test Env
|
||||||
|
File homeDir = MavenTestingUtils.getTestResourceDir("non-required-deps");
|
||||||
|
File baseDir = testdir.getEmptyPathDir().toFile();
|
||||||
|
String[] cmdLine = new String[]{"bar.type=cannot-find-me"};
|
||||||
|
|
||||||
|
// Configuration
|
||||||
|
CommandLineConfigSource cmdLineSource = new CommandLineConfigSource(cmdLine);
|
||||||
|
ConfigSources config = new ConfigSources();
|
||||||
|
config.add(cmdLineSource);
|
||||||
|
config.add(new JettyHomeConfigSource(homeDir.toPath()));
|
||||||
|
config.add(new JettyBaseConfigSource(baseDir.toPath()));
|
||||||
|
|
||||||
|
// Initialize
|
||||||
|
BaseHome basehome = new BaseHome(config);
|
||||||
|
|
||||||
|
StartArgs args = new StartArgs(basehome);
|
||||||
|
args.parse(config);
|
||||||
|
|
||||||
|
// Test Modules
|
||||||
|
Modules modules = new Modules(basehome, args);
|
||||||
|
modules.registerAll();
|
||||||
|
|
||||||
|
// Enable module
|
||||||
|
modules.enable("bar", TEST_SOURCE);
|
||||||
|
|
||||||
|
// Collect active module list
|
||||||
|
List<Module> active = modules.getEnabled();
|
||||||
|
|
||||||
|
// Assert names are correct, and in the right order
|
||||||
|
List<String> expectedNames = new ArrayList<>();
|
||||||
|
expectedNames.add("foo");
|
||||||
|
expectedNames.add("bar");
|
||||||
|
|
||||||
|
List<String> actualNames = new ArrayList<>();
|
||||||
|
for (Module actual : active)
|
||||||
|
{
|
||||||
|
actualNames.add(actual.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
assertThat("Resolved Names: " + actualNames, actualNames, contains(expectedNames.toArray()));
|
||||||
|
|
||||||
|
Props props = args.getProperties();
|
||||||
|
assertThat(props.getString("bar.name"), is(nullValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testResolveNotRequiredModuleFound() throws IOException
|
||||||
|
{
|
||||||
|
// Test Env
|
||||||
|
File homeDir = MavenTestingUtils.getTestResourceDir("non-required-deps");
|
||||||
|
File baseDir = testdir.getEmptyPathDir().toFile();
|
||||||
|
String[] cmdLine = new String[]{"bar.type=dive"};
|
||||||
|
|
||||||
|
// Configuration
|
||||||
|
CommandLineConfigSource cmdLineSource = new CommandLineConfigSource(cmdLine);
|
||||||
|
ConfigSources config = new ConfigSources();
|
||||||
|
config.add(cmdLineSource);
|
||||||
|
config.add(new JettyHomeConfigSource(homeDir.toPath()));
|
||||||
|
config.add(new JettyBaseConfigSource(baseDir.toPath()));
|
||||||
|
|
||||||
|
// Initialize
|
||||||
|
BaseHome basehome = new BaseHome(config);
|
||||||
|
|
||||||
|
StartArgs args = new StartArgs(basehome);
|
||||||
|
args.parse(config);
|
||||||
|
|
||||||
|
// Test Modules
|
||||||
|
Modules modules = new Modules(basehome, args);
|
||||||
|
modules.registerAll();
|
||||||
|
|
||||||
|
// Enable module
|
||||||
|
modules.enable("bar", TEST_SOURCE);
|
||||||
|
|
||||||
|
// Collect active module list
|
||||||
|
List<Module> active = modules.getEnabled();
|
||||||
|
|
||||||
|
// Assert names are correct, and in the right order
|
||||||
|
List<String> expectedNames = new ArrayList<>();
|
||||||
|
expectedNames.add("foo");
|
||||||
|
expectedNames.add("bar");
|
||||||
|
expectedNames.add("bar-dive");
|
||||||
|
|
||||||
|
List<String> actualNames = new ArrayList<>();
|
||||||
|
for (Module actual : active)
|
||||||
|
{
|
||||||
|
actualNames.add(actual.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
assertThat("Resolved Names: " + actualNames, actualNames, contains(expectedNames.toArray()));
|
||||||
|
|
||||||
|
Props props = args.getProperties();
|
||||||
|
assertThat(props.getString("bar.name"), is("dive"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testResolveNotRequiredModuleFoundDynamic() throws IOException
|
||||||
|
{
|
||||||
|
// Test Env
|
||||||
|
File homeDir = MavenTestingUtils.getTestResourceDir("non-required-deps");
|
||||||
|
File baseDir = testdir.getEmptyPathDir().toFile();
|
||||||
|
String[] cmdLine = new String[]{"bar.type=dynamic"};
|
||||||
|
|
||||||
|
// Configuration
|
||||||
|
CommandLineConfigSource cmdLineSource = new CommandLineConfigSource(cmdLine);
|
||||||
|
ConfigSources config = new ConfigSources();
|
||||||
|
config.add(cmdLineSource);
|
||||||
|
config.add(new JettyHomeConfigSource(homeDir.toPath()));
|
||||||
|
config.add(new JettyBaseConfigSource(baseDir.toPath()));
|
||||||
|
|
||||||
|
// Initialize
|
||||||
|
BaseHome basehome = new BaseHome(config);
|
||||||
|
|
||||||
|
StartArgs args = new StartArgs(basehome);
|
||||||
|
args.parse(config);
|
||||||
|
|
||||||
|
// Test Modules
|
||||||
|
Modules modules = new Modules(basehome, args);
|
||||||
|
modules.registerAll();
|
||||||
|
|
||||||
|
// Enable module
|
||||||
|
modules.enable("bar", TEST_SOURCE);
|
||||||
|
|
||||||
|
// Collect active module list
|
||||||
|
List<Module> active = modules.getEnabled();
|
||||||
|
|
||||||
|
// Assert names are correct, and in the right order
|
||||||
|
List<String> expectedNames = new ArrayList<>();
|
||||||
|
expectedNames.add("foo");
|
||||||
|
expectedNames.add("bar");
|
||||||
|
expectedNames.add("impls/bar-dynamic");
|
||||||
|
|
||||||
|
List<String> actualNames = new ArrayList<>();
|
||||||
|
for (Module actual : active)
|
||||||
|
{
|
||||||
|
actualNames.add(actual.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
assertThat("Resolved Names: " + actualNames, actualNames, contains(expectedNames.toArray()));
|
||||||
|
|
||||||
|
Props props = args.getProperties();
|
||||||
|
assertThat(props.getString("bar.name"), is("dynamic"));
|
||||||
|
}
|
||||||
|
|
||||||
private List<String> normalizeLibs(List<Module> active)
|
private List<String> normalizeLibs(List<Module> active)
|
||||||
{
|
{
|
||||||
List<String> libs = new ArrayList<>();
|
List<String> libs = new ArrayList<>();
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
[ini]
|
||||||
|
bar.name=dive
|
|
@ -0,0 +1,6 @@
|
||||||
|
# Top level mod
|
||||||
|
|
||||||
|
[depends]
|
||||||
|
foo
|
||||||
|
?bar-${bar.type}
|
||||||
|
?impls/bar-${bar.type}
|
|
@ -0,0 +1 @@
|
||||||
|
# nothing here
|
|
@ -0,0 +1,2 @@
|
||||||
|
[ini]
|
||||||
|
bar.name=dynamic
|
|
@ -124,7 +124,8 @@ public class StdErrLog extends AbstractLogger
|
||||||
private int _level;
|
private int _level;
|
||||||
// Level that this Logger was configured as (remembered in special case of .setDebugEnabled())
|
// Level that this Logger was configured as (remembered in special case of .setDebugEnabled())
|
||||||
private int _configuredLevel;
|
private int _configuredLevel;
|
||||||
private PrintStream _stderr = System.err;
|
// The alternate stream to print to (if set)
|
||||||
|
private PrintStream _altStream;
|
||||||
private boolean _source;
|
private boolean _source;
|
||||||
// Print the long form names, otherwise use abbreviated
|
// Print the long form names, otherwise use abbreviated
|
||||||
private boolean _printLongNames = LONG_CLASSNAMES;
|
private boolean _printLongNames = LONG_CLASSNAMES;
|
||||||
|
@ -378,16 +379,14 @@ public class StdErrLog extends AbstractLogger
|
||||||
this._level = level;
|
this._level = level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The alternate stream to use for STDERR.
|
||||||
|
*
|
||||||
|
* @param stream the stream of choice, or {@code null} to use {@link System#err}
|
||||||
|
*/
|
||||||
public void setStdErrStream(PrintStream stream)
|
public void setStdErrStream(PrintStream stream)
|
||||||
{
|
{
|
||||||
if (stream == null)
|
this._altStream = stream;
|
||||||
{
|
|
||||||
this._stderr = System.err;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this._stderr = stream;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -431,7 +430,14 @@ public class StdErrLog extends AbstractLogger
|
||||||
|
|
||||||
private void println(StringBuilder builder)
|
private void println(StringBuilder builder)
|
||||||
{
|
{
|
||||||
_stderr.println(builder);
|
if (_altStream != null)
|
||||||
|
_altStream.println(builder);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// We always use the PrintStream stored in System.err,
|
||||||
|
// just in case someone has replaced it with a call to System.setErr(PrintStream)
|
||||||
|
System.err.println(builder);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void format(StringBuilder builder, String level, String msg, Object... inArgs)
|
private void format(StringBuilder builder, String level, String msg, Object... inArgs)
|
||||||
|
@ -632,7 +638,7 @@ public class StdErrLog extends AbstractLogger
|
||||||
StdErrLog logger = new StdErrLog(fullname);
|
StdErrLog logger = new StdErrLog(fullname);
|
||||||
// Preserve configuration for new loggers configuration
|
// Preserve configuration for new loggers configuration
|
||||||
logger.setPrintLongNames(_printLongNames);
|
logger.setPrintLongNames(_printLongNames);
|
||||||
logger._stderr = this._stderr;
|
logger._altStream = this._altStream;
|
||||||
|
|
||||||
// Force the child to have any programmatic configuration
|
// Force the child to have any programmatic configuration
|
||||||
if (_level != _configuredLevel)
|
if (_level != _configuredLevel)
|
||||||
|
|
2
pom.xml
2
pom.xml
|
@ -616,7 +616,7 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-shade-plugin</artifactId>
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
<version>3.2.1</version>
|
<version>3.2.2</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
|
Loading…
Reference in New Issue