Issue #7064 - Fix `(null)` for source output in `--list-config` (#7065)

Improved start handling of output so that testcases
can now validate the output if they need to.

Signed-off-by: Joakim Erdfelt <joakim.erdfelt@gmail.com>
This commit is contained in:
Joakim Erdfelt 2021-11-16 09:07:46 -06:00 committed by GitHub
parent 6bfab6efb6
commit edaead4a5b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 147 additions and 123 deletions

View File

@ -20,6 +20,7 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.ConnectException;
@ -137,26 +138,26 @@ public class Main
}).start();
}
private void dumpClasspathWithVersions(Classpath classpath)
private void dumpClasspathWithVersions(PrintStream out, Classpath classpath)
{
StartLog.endStartLog();
System.out.println();
System.out.println("Jetty Server Classpath:");
System.out.println("-----------------------");
out.println();
out.println("Jetty Server Classpath:");
out.println("-----------------------");
if (classpath.count() == 0)
{
System.out.println("No classpath entries and/or version information available show.");
out.println("No classpath entries and/or version information available show.");
return;
}
System.out.println("Version Information on " + classpath.count() + " entr" + ((classpath.count() > 1) ? "ies" : "y") + " in the classpath.");
System.out.println("Note: order presented here is how they would appear on the classpath.");
System.out.println(" changes to the --module=name command line options will be reflected here.");
out.println("Version Information on " + classpath.count() + " entr" + ((classpath.count() > 1) ? "ies" : "y") + " in the classpath.");
out.println("Note: order presented here is how they would appear on the classpath.");
out.println(" changes to the --module=name command line options will be reflected here.");
int i = 0;
for (File element : classpath.getElements())
{
System.out.printf("%2d: %24s | %s\n", i++, getVersion(element), baseHome.toShortForm(element));
out.printf("%2d: %24s | %s\n", i++, getVersion(element), baseHome.toShortForm(element));
}
}
@ -227,51 +228,51 @@ public class Main
main.invoke(null, methodParams);
}
public void listConfig(StartArgs args)
public void listConfig(PrintStream out, StartArgs args)
{
StartLog.endStartLog();
Modules modules = args.getAllModules();
// Dump Enabled Modules
modules.listEnabled();
modules.listEnabled(out);
// Dump Jetty Home / Base
args.dumpEnvironment();
args.dumpEnvironment(out);
// Dump JVM Args
args.dumpJvmArgs();
args.dumpJvmArgs(out);
// Dump System Properties
args.dumpSystemProperties();
args.dumpSystemProperties(out);
// Dump Properties
args.dumpProperties();
args.dumpProperties(out);
// Dump Classpath
dumpClasspathWithVersions(args.getClasspath());
dumpClasspathWithVersions(out, args.getClasspath());
// Dump Resolved XMLs
args.dumpActiveXmls();
args.dumpActiveXmls(out);
}
public void listModules(StartArgs args)
public void listModules(PrintStream out, StartArgs args)
{
final List<String> tags = args.getListModules();
StartLog.endStartLog();
String t = tags.toString();
System.out.printf("%nModules %s:%n", t);
System.out.printf("=========%s%n", "=".repeat(t.length()));
args.getAllModules().listModules(tags);
out.printf("%nModules %s:%n", t);
out.printf("=========%s%n", "=".repeat(t.length()));
args.getAllModules().listModules(out, tags);
// for default module listings, also show enabled modules
if ("[-internal]".equals(t) || "[*]".equals(t))
args.getAllModules().listEnabled();
args.getAllModules().listEnabled(out);
}
public void showModules(StartArgs args)
public void showModules(PrintStream out, StartArgs args)
{
StartLog.endStartLog();
args.getAllModules().showModules(args.getShowModules());
args.getAllModules().showModules(out, args.getShowModules());
}
/**
@ -393,25 +394,25 @@ public class Main
// Show the version information and return
if (args.isListClasspath())
{
dumpClasspathWithVersions(classpath);
dumpClasspathWithVersions(System.out, classpath);
}
// Show configuration
if (args.isListConfig())
{
listConfig(args);
listConfig(System.out, args);
}
// List modules
if (args.getListModules() != null)
{
listModules(args);
listModules(System.out, args);
}
// Show modules
if (args.getShowModules() != null)
{
showModules(args);
showModules(System.out, args);
}
// Generate Module Graph File

View File

@ -15,6 +15,7 @@ package org.eclipse.jetty.start;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
@ -78,7 +79,7 @@ public class Modules implements Iterable<Module>
}
}
public void showModules(List<String> modules)
public void showModules(PrintStream out, List<String> modules)
{
Stream<Module> stream = (modules.contains("*") || modules.isEmpty())
? _modules.stream().sorted()
@ -92,20 +93,20 @@ public class Modules implements Iterable<Module>
String label;
Set<String> provides = module.getProvides();
provides.remove(module.getName());
System.out.printf("%n Module: %s %s%n", module.getName(), provides.size() > 0 ? provides : "");
out.printf("%n Module: %s %s%n", module.getName(), provides.size() > 0 ? provides : "");
for (String description : module.getDescription())
{
System.out.printf(" : %s%n", description);
out.printf(" : %s%n", description);
}
if (!module.getTags().isEmpty())
{
label = " Tags: %s";
for (String t : module.getTags())
{
System.out.printf(label, t);
out.printf(label, t);
label = ", %s";
}
System.out.println();
out.println();
}
if (!module.getDepends().isEmpty())
{
@ -113,60 +114,60 @@ public class Modules implements Iterable<Module>
for (String parent : module.getDepends())
{
parent = Module.normalizeModuleName(parent);
System.out.printf(label, parent);
out.printf(label, parent);
if (Module.isConditionalDependency(parent))
System.out.print(" [conditional]");
out.print(" [conditional]");
label = ", %s";
}
System.out.println();
out.println();
}
if (!module.getBefore().isEmpty())
{
label = " Before: %s";
for (String before : module.getBefore())
{
System.out.printf(label, before);
out.printf(label, before);
label = ", %s";
}
System.out.println();
out.println();
}
if (!module.getAfter().isEmpty())
{
label = " After: %s";
for (String after : module.getAfter())
{
System.out.printf(label, after);
out.printf(label, after);
label = ", %s";
}
System.out.println();
out.println();
}
for (String lib : module.getLibs())
{
System.out.printf(" LIB: %s%n", lib);
out.printf(" LIB: %s%n", lib);
}
for (String xml : module.getXmls())
{
System.out.printf(" XML: %s%n", xml);
out.printf(" XML: %s%n", xml);
}
for (String jpms : module.getJPMS())
{
System.out.printf(" JPMS: %s%n", jpms);
out.printf(" JPMS: %s%n", jpms);
}
for (String jvm : module.getJvmArgs())
{
System.out.printf(" JVM: %s%n", jvm);
out.printf(" JVM: %s%n", jvm);
}
if (module.isEnabled())
{
for (String selection : module.getEnableSources())
{
System.out.printf(" Enabled: %s%n", selection);
out.printf(" Enabled: %s%n", selection);
}
}
});
}
public void listModules(List<String> tags)
public void listModules(PrintStream out, List<String> tags)
{
if (tags.contains("-*"))
return;
@ -199,20 +200,20 @@ public class Modules implements Iterable<Module>
if (!wild && !module.getPrimaryTag().equals(tag.get()))
{
tag.set(module.getPrimaryTag());
System.out.printf("%n%s modules:", module.getPrimaryTag());
System.out.printf("%n%s---------%n", "-".repeat(module.getPrimaryTag().length()));
out.printf("%n%s modules:", module.getPrimaryTag());
out.printf("%n%s---------%n", "-".repeat(module.getPrimaryTag().length()));
}
List<String> description = module.getDescription();
System.out.printf(format, module.getName(), description != null && description.size() > 0 ? description.get(0) : "");
out.printf(format, module.getName(), description != null && description.size() > 0 ? description.get(0) : "");
});
}
public void listEnabled()
public void listEnabled(PrintStream out)
{
System.out.println();
System.out.println("Enabled Modules:");
System.out.println("----------------");
out.println();
out.println("Enabled Modules:");
out.println("----------------");
int i = 0;
List<Module> enabled = getEnabled();
@ -222,12 +223,12 @@ public class Modules implements Iterable<Module>
String index = (i++) + ")";
for (String s : module.getEnableSources())
{
System.out.printf(" %4s %-15s %s%n", index, name, s);
out.printf(" %4s %-15s %s%n", index, name, s);
index = "";
name = "";
}
if (module.isTransitive() && module.hasIniTemplate())
System.out.printf(" init template available with --add-module=%s%n", module.getName());
out.printf(" init template available with --add-module=%s%n", module.getName());
}
}

View File

@ -17,6 +17,7 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@ -264,94 +265,94 @@ public class StartArgs
}
}
public void dumpActiveXmls()
public void dumpActiveXmls(PrintStream out)
{
System.out.println();
System.out.println("Jetty Active XMLs:");
System.out.println("------------------");
out.println();
out.println("Jetty Active XMLs:");
out.println("------------------");
if (xmls.isEmpty())
{
System.out.println(" (no xml files specified)");
out.println(" (no xml files specified)");
return;
}
for (Path xml : xmls)
{
System.out.printf(" %s%n", baseHome.toShortForm(xml.toAbsolutePath()));
out.printf(" %s%n", baseHome.toShortForm(xml.toAbsolutePath()));
}
}
public void dumpEnvironment()
public void dumpEnvironment(PrintStream out)
{
// Java Details
System.out.println();
System.out.println("Java Environment:");
System.out.println("-----------------");
dumpSystemProperty("java.home");
dumpSystemProperty("java.vm.vendor");
dumpSystemProperty("java.vm.version");
dumpSystemProperty("java.vm.name");
dumpSystemProperty("java.vm.info");
dumpSystemProperty("java.runtime.name");
dumpSystemProperty("java.runtime.version");
dumpSystemProperty("java.io.tmpdir");
dumpSystemProperty("user.dir");
dumpSystemProperty("user.language");
dumpSystemProperty("user.country");
out.println();
out.println("Java Environment:");
out.println("-----------------");
dumpSystemProperty(out, "java.home");
dumpSystemProperty(out, "java.vm.vendor");
dumpSystemProperty(out, "java.vm.version");
dumpSystemProperty(out, "java.vm.name");
dumpSystemProperty(out, "java.vm.info");
dumpSystemProperty(out, "java.runtime.name");
dumpSystemProperty(out, "java.runtime.version");
dumpSystemProperty(out, "java.io.tmpdir");
dumpSystemProperty(out, "user.dir");
dumpSystemProperty(out, "user.language");
dumpSystemProperty(out, "user.country");
// Jetty Environment
System.out.println();
System.out.println("Jetty Environment:");
System.out.println("------------------");
dumpProperty(JETTY_VERSION_KEY);
dumpProperty(JETTY_TAG_NAME_KEY);
dumpProperty(JETTY_BUILDNUM_KEY);
dumpProperty("jetty.home");
dumpProperty("jetty.base");
out.println();
out.println("Jetty Environment:");
out.println("------------------");
dumpProperty(out, JETTY_VERSION_KEY);
dumpProperty(out, JETTY_TAG_NAME_KEY);
dumpProperty(out, JETTY_BUILDNUM_KEY);
dumpProperty(out, "jetty.home");
dumpProperty(out, "jetty.base");
// Jetty Configuration Environment
System.out.println();
System.out.println("Config Search Order:");
System.out.println("--------------------");
out.println();
out.println("Config Search Order:");
out.println("--------------------");
for (ConfigSource config : baseHome.getConfigSources())
{
System.out.printf(" %s", config.getId());
out.printf(" %s", config.getId());
if (config instanceof DirConfigSource)
{
DirConfigSource dirsource = (DirConfigSource)config;
if (dirsource.isPropertyBased())
{
System.out.printf(" -> %s", dirsource.getDir());
out.printf(" -> %s", dirsource.getDir());
}
}
System.out.println();
out.println();
}
}
public void dumpJvmArgs()
public void dumpJvmArgs(PrintStream out)
{
if (jvmArgs.isEmpty())
return;
System.out.println();
System.out.println("Forked JVM Arguments:");
System.out.println("---------------------");
out.println();
out.println("Forked JVM Arguments:");
out.println("---------------------");
for (String jvmArgKey : jvmArgs)
{
String value = System.getProperty(jvmArgKey);
if (value != null)
System.out.printf(" %s = %s%n", jvmArgKey, value);
out.printf(" %s = %s%n", jvmArgKey, value);
else
System.out.printf(" %s%n", jvmArgKey);
out.printf(" %s%n", jvmArgKey);
}
}
public void dumpProperties()
public void dumpProperties(PrintStream out)
{
System.out.println();
System.out.println("Properties:");
System.out.println("-----------");
out.println();
out.println("Properties:");
out.println("-----------");
List<String> sortedKeys = new ArrayList<>();
for (Prop prop : properties)
@ -365,7 +366,7 @@ public class StartArgs
if (sortedKeys.isEmpty())
{
System.out.println(" (no properties specified)");
out.println(" (no properties specified)");
return;
}
@ -373,7 +374,7 @@ public class StartArgs
for (String key : sortedKeys)
{
dumpProperty(key);
dumpProperty(out, key);
}
for (Path path : propertyFiles)
@ -387,46 +388,45 @@ public class StartArgs
props.load(new FileInputStream(path.toFile()));
for (Object key : props.keySet())
{
System.out.printf(" %s:%s = %s%n", p, key, props.getProperty(String.valueOf(key)));
out.printf(" %s:%s = %s%n", p, key, props.getProperty(String.valueOf(key)));
}
}
catch (Throwable th)
{
System.out.printf(" %s NOT READABLE!%n", p);
out.printf(" %s NOT READABLE!%n", p);
}
}
else
{
System.out.printf(" %s NOT READABLE!%n", p);
out.printf(" %s NOT READABLE!%n", p);
}
}
}
private void dumpProperty(String key)
private void dumpProperty(PrintStream out, String key)
{
Prop prop = properties.getProp(key);
if (prop == null)
{
System.out.printf(" %s (not defined)%n", key);
out.printf(" %s (not defined)%n", key);
}
else
{
System.out.printf(" %s = %s%n", key, prop.value);
out.printf(" %s = %s%n", key, prop.value);
if (StartLog.isDebugEnabled())
System.out.printf(" origin: %s%n", prop.source);
out.printf(" origin: %s%n", prop.source);
}
}
public void dumpSystemProperties()
public void dumpSystemProperties(PrintStream out)
{
System.out.println();
System.out.println("System Properties:");
System.out.println("------------------");
out.println();
out.println("System Properties:");
out.println("------------------");
if (systemPropertySource.keySet().isEmpty())
{
System.out.println(" (no system properties specified)");
out.println(" (no system properties specified)");
return;
}
@ -435,15 +435,18 @@ public class StartArgs
for (String key : sortedKeys)
{
dumpSystemProperty(key);
dumpSystemProperty(out, key);
}
}
private void dumpSystemProperty(String key)
private void dumpSystemProperty(PrintStream out, String key)
{
String value = System.getProperty(key);
String source = systemPropertySource.get(key);
System.out.printf(" %s = %s (%s)%n", key, value, source);
// "source" is where this property came from (jvm, command line, configuration file, etc)
String source = "";
if (systemPropertySource.get(key) != null)
source = String.format(" (%s)", systemPropertySource.get(key));
out.printf(" %s = %s%s%n", key, value, source);
}
/**

View File

@ -13,7 +13,10 @@
package org.eclipse.jetty.start;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
@ -26,6 +29,7 @@ import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class MainTest
@ -48,7 +52,6 @@ public class MainTest
Main main = new Main();
StartArgs args = main.processCommandLine(cmdLineArgs.toArray(new String[0]));
// System.err.println(args);
// assertEquals(0, args.getEnabledModules().size(), "--stop should not build module tree");
assertEquals("10000", args.getProperties().getString("STOP.PORT"), "--stop missing port");
@ -57,19 +60,35 @@ public class MainTest
}
@Test
@Disabled("Too noisy for general testing")
public void testListConfig() throws Exception
{
List<String> cmdLineArgs = new ArrayList<>();
File testJettyHome = MavenTestingUtils.getTestResourceDir("dist-home");
cmdLineArgs.add("user.dir=" + testJettyHome);
cmdLineArgs.add("-Duser.dir=foo"); // used to test "source" display on "Java Environment"
cmdLineArgs.add("jetty.home=" + testJettyHome);
cmdLineArgs.add("--list-config");
// cmdLineArgs.add("--debug");
List<String> output;
Main main = new Main();
StartArgs args = main.processCommandLine(cmdLineArgs.toArray(new String[0]));
main.listConfig(args);
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream out = new PrintStream(baos, true, StandardCharsets.UTF_8))
{
main.listConfig(out, args);
out.flush();
output = List.of(baos.toString(StandardCharsets.UTF_8).split(System.lineSeparator()));
}
// Test a System Property that comes from JVM
String javaVersionLine = output.stream().filter((line) -> line.contains("java.version ="))
.findFirst().orElseThrow();
assertThat("java.version should have no indicated source", javaVersionLine, not(containsString("(null)")));
String userDirLine = output.stream().filter((line) -> line.startsWith(" user.dir ="))
.findFirst().orElseThrow();
assertThat("A source of 'null' is pointless", userDirLine, not(containsString("(null)")));
assertThat("user.dir should indicate that it was specified on the command line", userDirLine, containsString("(<command-line>)"));
}
@Test