diff --git a/config/src/main/java/com/typesafe/config/impl/ConfigImpl.java b/config/src/main/java/com/typesafe/config/impl/ConfigImpl.java index 73ddfdce..be5dd019 100644 --- a/config/src/main/java/com/typesafe/config/impl/ConfigImpl.java +++ b/config/src/main/java/com/typesafe/config/impl/ConfigImpl.java @@ -413,4 +413,51 @@ public class ConfigImpl { throw ConfigImplUtil.extractInitializerError(e); } } + + private static class DebugHolder { + private static String LOADS = "loads"; + + private static Map loadDiagnostics() { + Map result = new HashMap(); + result.put(LOADS, false); + + // People do -Dconfig.trace=foo,bar to enable tracing of different things + String s = System.getProperty("config.trace"); + if (s == null) { + return result; + } else { + String[] keys = s.split(","); + for (String k : keys) { + if (k.equals(LOADS)) { + result.put(LOADS, true); + } else { + System.err.println("config.trace property contains unknown trace topic '" + + k + "'"); + } + } + return result; + } + } + + private static final Map diagnostics = loadDiagnostics(); + + private static final boolean traceLoadsEnabled = diagnostics.get(LOADS); + + static boolean traceLoadsEnabled() { + return traceLoadsEnabled; + } + } + + /** For use ONLY by library internals, DO NOT TOUCH not guaranteed ABI */ + public static boolean traceLoadsEnabled() { + try { + return DebugHolder.traceLoadsEnabled(); + } catch (ExceptionInInitializerError e) { + throw ConfigImplUtil.extractInitializerError(e); + } + } + + public static void trace(String message) { + System.err.println(message); + } } diff --git a/config/src/main/java/com/typesafe/config/impl/Parseable.java b/config/src/main/java/com/typesafe/config/impl/Parseable.java index 49386031..8295fdfa 100644 --- a/config/src/main/java/com/typesafe/config/impl/Parseable.java +++ b/config/src/main/java/com/typesafe/config/impl/Parseable.java @@ -87,6 +87,12 @@ public abstract class Parseable implements ConfigParseable { // to support the "allow missing" feature. protected abstract Reader reader() throws IOException; + protected static void trace(String message) { + if (ConfigImpl.traceLoadsEnabled()) { + ConfigImpl.trace(message); + } + } + ConfigSyntax guessSyntax() { return null; } @@ -300,6 +306,8 @@ public abstract class Parseable implements ConfigParseable { @Override protected Reader reader() { + if (ConfigImpl.traceLoadsEnabled()) + trace("Loading config from reader " + reader); return reader; } @@ -314,6 +322,7 @@ public abstract class Parseable implements ConfigParseable { * is complete. */ public static Parseable newReader(Reader reader, ConfigParseOptions options) { + return new ParseableReader(doNotClose(reader), options); } @@ -327,6 +336,8 @@ public abstract class Parseable implements ConfigParseable { @Override protected Reader reader() { + if (ConfigImpl.traceLoadsEnabled()) + trace("Loading config from a String " + input); return new StringReader(input); } @@ -350,6 +361,8 @@ public abstract class Parseable implements ConfigParseable { @Override protected Reader reader() throws IOException { + if (ConfigImpl.traceLoadsEnabled()) + trace("Loading config from a URL: " + input.toExternalForm()); InputStream stream = input.openStream(); return readerFromStream(stream); } @@ -400,6 +413,8 @@ public abstract class Parseable implements ConfigParseable { @Override protected Reader reader() throws IOException { + if (ConfigImpl.traceLoadsEnabled()) + trace("Loading config from a file: " + input); InputStream stream = new FileInputStream(input); return readerFromStream(stream); } @@ -472,12 +487,19 @@ public abstract class Parseable implements ConfigParseable { ConfigParseOptions finalOptions) throws IOException { Enumeration e = loader.getResources(resource); if (!e.hasMoreElements()) { + if (ConfigImpl.traceLoadsEnabled()) + trace("Loading config from class loader " + loader + + " but there were no resources called " + resource); throw new IOException("resource not found on classpath: " + resource); } AbstractConfigObject merged = SimpleConfigObject.empty(origin); while (e.hasMoreElements()) { URL url = e.nextElement(); + if (ConfigImpl.traceLoadsEnabled()) + trace("Loading config from URL " + url.toExternalForm() + " from class loader " + + loader); + ConfigOrigin elementOrigin = ((SimpleConfigOrigin) origin).addURL(url); AbstractConfigValue v; @@ -611,6 +633,8 @@ public abstract class Parseable implements ConfigParseable { @Override protected AbstractConfigObject rawParseValue(ConfigOrigin origin, ConfigParseOptions finalOptions) { + if (ConfigImpl.traceLoadsEnabled()) + trace("Loading config from properties " + props); return PropertiesParser.fromProperties(origin, props); }