diff --git a/config/src/main/java/com/typesafe/config/ConfigFactory.java b/config/src/main/java/com/typesafe/config/ConfigFactory.java
index 3280246a..685c2602 100644
--- a/config/src/main/java/com/typesafe/config/ConfigFactory.java
+++ b/config/src/main/java/com/typesafe/config/ConfigFactory.java
@@ -58,7 +58,8 @@ public final class ConfigFactory {
* @return configuration for an application relative to context class loader
*/
public static Config load(String resourceBasename) {
- return load(Thread.currentThread().getContextClassLoader(), resourceBasename);
+ return load(resourceBasename, ConfigParseOptions.defaults(),
+ ConfigResolveOptions.defaults());
}
/**
@@ -70,7 +71,7 @@ public final class ConfigFactory {
* @return configuration for an application relative to given class loader
*/
public static Config load(ClassLoader loader, String resourceBasename) {
- return load(loader, resourceBasename, ConfigParseOptions.defaults(),
+ return load(resourceBasename, ConfigParseOptions.defaults().setClassLoader(loader),
ConfigResolveOptions.defaults());
}
@@ -88,29 +89,30 @@ public final class ConfigFactory {
*/
public static Config load(String resourceBasename, ConfigParseOptions parseOptions,
ConfigResolveOptions resolveOptions) {
- return load(Thread.currentThread().getContextClassLoader(), resourceBasename, parseOptions,
- resolveOptions);
+ Config appConfig = ConfigFactory.parseResourcesAnySyntax(resourceBasename, parseOptions);
+ return load(parseOptions.getClassLoader(), appConfig, resolveOptions);
}
/**
* Like {@link #load(String,ConfigParseOptions,ConfigResolveOptions)} but
- * allows you to specify a class loader
+ * has a class loader parameter that overrides any from the
+ * {@code ConfigParseOptions}.
*
* @param loader
- * class loader in which to find resources
+ * class loader in which to find resources (overrides loader in
+ * parse options)
* @param resourceBasename
* the classpath resource name with optional extension
* @param parseOptions
- * options to use when parsing the resource
+ * options to use when parsing the resource (class loader
+ * overridden)
* @param resolveOptions
* options to use when resolving the stack
* @return configuration for an application
*/
public static Config load(ClassLoader loader, String resourceBasename,
ConfigParseOptions parseOptions, ConfigResolveOptions resolveOptions) {
- Config appConfig = ConfigFactory.parseResourcesAnySyntax(loader, resourceBasename,
- parseOptions);
- return load(loader, appConfig, resolveOptions);
+ return load(resourceBasename, parseOptions.setClassLoader(loader), resolveOptions);
}
/**
@@ -192,10 +194,16 @@ public final class ConfigFactory {
// people want that they can use an include statement.
return load(loader, parseResources(loader, resource));
} else if (file != null) {
- return load(loader, parseFile(new File(file)));
+ return load(
+ loader,
+ parseFile(new File(file),
+ ConfigParseOptions.defaults().setClassLoader(loader)));
} else {
try {
- return load(loader, parseURL(new URL(url)));
+ return load(
+ loader,
+ parseURL(new URL(url),
+ ConfigParseOptions.defaults().setClassLoader(loader)));
} catch (MalformedURLException e) {
throw new ConfigException.Generic("Bad URL in config.url system property: '"
+ url + "': " + e.getMessage(), e);
@@ -550,7 +558,8 @@ public final class ConfigFactory {
* a resource name as in {@link java.lang.Class#getResource},
* with or without extension
* @param options
- * parse options
+ * parse options (class loader is ignored in favor of the one
+ * from klass)
* @return the parsed configuration
*/
public static Config parseResourcesAnySyntax(Class> klass, String resourceBasename,
@@ -566,27 +575,28 @@ public final class ConfigFactory {
/**
* Parses all resources on the classpath with the given name and merges them
* into a single Config
.
- *
+ *
*
* This works like {@link java.lang.ClassLoader#getResource}, not like * {@link java.lang.Class#getResource}, so the name never begins with a * slash. - * + * *
* See {@link #parseResources(Class,String,ConfigParseOptions)} for full
* details.
- *
+ *
* @param loader
- * will be used to load resources
+ * will be used to load resources by setting this loader on the
+ * provided options
* @param resource
* resource to look up
* @param options
- * parse options
+ * parse options (class loader is ignored)
* @return the parsed configuration
*/
public static Config parseResources(ClassLoader loader, String resource,
ConfigParseOptions options) {
- return Parseable.newResources(loader, resource, options).parse().toConfig();
+ return Parseable.newResources(resource, options.setClassLoader(loader)).parse().toConfig();
}
public static Config parseResources(ClassLoader loader, String resource) {
@@ -607,18 +617,19 @@ public final class ConfigFactory {
* some details and caveats on this method.
*
* @param loader
- * class loader to look up resources in
+ * class loader to look up resources in, will be set on options
* @param resourceBasename
* a resource name as in
* {@link java.lang.ClassLoader#getResource}, with or without
* extension
* @param options
- * parse options
+ * parse options (class loader ignored)
* @return the parsed configuration
*/
public static Config parseResourcesAnySyntax(ClassLoader loader, String resourceBasename,
ConfigParseOptions options) {
- return ConfigImpl.parseResourcesAnySyntax(loader, resourceBasename, options).toConfig();
+ return ConfigImpl.parseResourcesAnySyntax(resourceBasename, options.setClassLoader(loader))
+ .toConfig();
}
public static Config parseResourcesAnySyntax(ClassLoader loader, String resourceBasename) {
@@ -630,8 +641,7 @@ public final class ConfigFactory {
* uses thread's current context class loader.
*/
public static Config parseResources(String resource, ConfigParseOptions options) {
- return Parseable
- .newResources(Thread.currentThread().getContextClassLoader(), resource, options)
+ return Parseable.newResources(resource, options)
.parse().toConfig();
}
@@ -640,8 +650,7 @@ public final class ConfigFactory {
* current context class loader.
*/
public static Config parseResources(String resource) {
- return parseResources(Thread.currentThread().getContextClassLoader(), resource,
- ConfigParseOptions.defaults());
+ return parseResources(resource, ConfigParseOptions.defaults());
}
/**
@@ -650,8 +659,7 @@ public final class ConfigFactory {
* but uses thread's current context class loader.
*/
public static Config parseResourcesAnySyntax(String resourceBasename, ConfigParseOptions options) {
- return ConfigImpl.parseResourcesAnySyntax(Thread.currentThread().getContextClassLoader(),
- resourceBasename, options).toConfig();
+ return ConfigImpl.parseResourcesAnySyntax(resourceBasename, options).toConfig();
}
/**
@@ -659,8 +667,7 @@ public final class ConfigFactory {
* thread's current context class loader.
*/
public static Config parseResourcesAnySyntax(String resourceBasename) {
- return parseResourcesAnySyntax(Thread.currentThread().getContextClassLoader(),
- resourceBasename, ConfigParseOptions.defaults());
+ return parseResourcesAnySyntax(resourceBasename, ConfigParseOptions.defaults());
}
public static Config parseString(String s, ConfigParseOptions options) {
diff --git a/config/src/main/java/com/typesafe/config/ConfigParseOptions.java b/config/src/main/java/com/typesafe/config/ConfigParseOptions.java
index 2d057e81..f84dc0a7 100644
--- a/config/src/main/java/com/typesafe/config/ConfigParseOptions.java
+++ b/config/src/main/java/com/typesafe/config/ConfigParseOptions.java
@@ -25,23 +25,25 @@ public final class ConfigParseOptions {
final String originDescription;
final boolean allowMissing;
final ConfigIncluder includer;
+ final ClassLoader classLoader;
- protected ConfigParseOptions(ConfigSyntax syntax, String originDescription,
- boolean allowMissing, ConfigIncluder includer) {
+ private ConfigParseOptions(ConfigSyntax syntax, String originDescription, boolean allowMissing,
+ ConfigIncluder includer, ClassLoader classLoader) {
this.syntax = syntax;
this.originDescription = originDescription;
this.allowMissing = allowMissing;
this.includer = includer;
+ this.classLoader = classLoader;
}
public static ConfigParseOptions defaults() {
- return new ConfigParseOptions(null, null, true, null);
+ return new ConfigParseOptions(null, null, true, null, null);
}
/**
* Set the file format. If set to null, try to guess from any available
* filename extension; if guessing fails, assume {@link ConfigSyntax#CONF}.
- *
+ *
* @param syntax
* a syntax or {@code null} for best guess
* @return options with the syntax set
@@ -50,8 +52,8 @@ public final class ConfigParseOptions {
if (this.syntax == syntax)
return this;
else
- return new ConfigParseOptions(syntax, this.originDescription,
- this.allowMissing, this.includer);
+ return new ConfigParseOptions(syntax, this.originDescription, this.allowMissing,
+ this.includer, this.classLoader);
}
public ConfigSyntax getSyntax() {
@@ -75,8 +77,8 @@ public final class ConfigParseOptions {
&& this.originDescription.equals(originDescription))
return this;
else
- return new ConfigParseOptions(this.syntax, originDescription,
- this.allowMissing, this.includer);
+ return new ConfigParseOptions(this.syntax, originDescription, this.allowMissing,
+ this.includer, this.classLoader);
}
public String getOriginDescription() {
@@ -103,8 +105,8 @@ public final class ConfigParseOptions {
if (this.allowMissing == allowMissing)
return this;
else
- return new ConfigParseOptions(this.syntax, this.originDescription,
- allowMissing, this.includer);
+ return new ConfigParseOptions(this.syntax, this.originDescription, allowMissing,
+ this.includer, this.classLoader);
}
public boolean getAllowMissing() {
@@ -122,7 +124,8 @@ public final class ConfigParseOptions {
return this;
else
return new ConfigParseOptions(this.syntax, this.originDescription,
- this.allowMissing, includer);
+ this.allowMissing,
+ includer, this.classLoader);
}
public ConfigParseOptions prependIncluder(ConfigIncluder includer) {
@@ -147,4 +150,34 @@ public final class ConfigParseOptions {
return includer;
}
+ /**
+ * Set the class loader. If set to null,
+ * Thread.currentThread().getContextClassLoader()
will be used.
+ *
+ * @param loader
+ * a class loader or {@code null} to use thread context class
+ * loader
+ * @return options with the class loader set
+ */
+ public ConfigParseOptions setClassLoader(ClassLoader loader) {
+ if (this.classLoader == loader)
+ return this;
+ else
+ return new ConfigParseOptions(this.syntax, this.originDescription, this.allowMissing,
+ this.includer, loader);
+ }
+
+ /**
+ * Get the class loader; never returns {@code null}, if the class loader was
+ * unset, returns
+ * Thread.currentThread().getContextClassLoader()
.
+ *
+ * @return class loader to use
+ */
+ public ClassLoader getClassLoader() {
+ if (this.classLoader == null)
+ return Thread.currentThread().getContextClassLoader();
+ else
+ return this.classLoader;
+ }
}
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 55c221fa..e62a1216 100644
--- a/config/src/main/java/com/typesafe/config/impl/ConfigImpl.java
+++ b/config/src/main/java/com/typesafe/config/impl/ConfigImpl.java
@@ -90,12 +90,12 @@ public class ConfigImpl {
}
/** For use ONLY by library internals, DO NOT TOUCH not guaranteed ABI */
- public static ConfigObject parseResourcesAnySyntax(final ClassLoader loader,
- String resourceBasename, final ConfigParseOptions baseOptions) {
+ public static ConfigObject parseResourcesAnySyntax(String resourceBasename,
+ final ConfigParseOptions baseOptions) {
NameSource source = new NameSource() {
@Override
public ConfigParseable nameToParseable(String name) {
- return Parseable.newResources(loader, name, baseOptions);
+ return Parseable.newResources(name, baseOptions);
}
};
return SimpleIncluder.fromBasename(source, resourceBasename, baseOptions);
@@ -334,7 +334,8 @@ public class ConfigImpl {
@Override
public Config call() {
Config unresolvedResources = Parseable
- .newResources(loader, "reference.conf", ConfigParseOptions.defaults())
+ .newResources("reference.conf",
+ ConfigParseOptions.defaults().setClassLoader(loader))
.parse().toConfig();
return systemPropertiesAsConfig().withFallback(unresolvedResources).resolve();
}
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 6e9415df..a6f0cea8 100644
--- a/config/src/main/java/com/typesafe/config/impl/Parseable.java
+++ b/config/src/main/java/com/typesafe/config/impl/Parseable.java
@@ -438,8 +438,7 @@ public abstract class Parseable implements ConfigParseable {
String resource = filename;
if (filename.startsWith("/"))
resource = filename.substring(1);
- return newResources(this.getClass().getClassLoader(), resource, options()
- .setOriginDescription(null));
+ return newResources(resource, options().setOriginDescription(null));
}
}
@@ -459,11 +458,9 @@ public abstract class Parseable implements ConfigParseable {
}
private final static class ParseableResources extends Parseable {
- final private ClassLoader loader;
final private String resource;
- ParseableResources(ClassLoader loader, String resource, ConfigParseOptions options) {
- this.loader = loader;
+ ParseableResources(String resource, ConfigParseOptions options) {
this.resource = resource;
postConstruct(options);
}
@@ -476,6 +473,7 @@ public abstract class Parseable implements ConfigParseable {
@Override
protected AbstractConfigObject rawParseValue(ConfigOrigin origin,
ConfigParseOptions finalOptions) throws IOException {
+ ClassLoader loader = finalOptions.getClassLoader();
Enumeration