Internal: Remove ClassLoader from Settings

Settings currently has a classloader member, which any user (plugin
or core ES code) can access to load classes/resources. This is extremely
error prone as setting the classloder on the Settings instance is a
public method. Furthermore, it is not really necessary. Classes that
need resources should load resources using normal means
(getClass().getResourceAsStream). Those that need classes
should use Class.forName, which will load the class with the
same classloader as the calling class. This means, in the few
places where classes are loaded by string name, they will use
the appropriate loader: either the default classloader which loads
core ES code, or a child classloader for each plugin.

This change removes the classloader member from Settings, as
well as other classloader related uses (except for a handful
of cases which must use a classloader, at least for now).
This commit is contained in:
Ryan Ernst 2015-08-13 19:43:03 -07:00
parent dcf3f4679f
commit 6dcfda99e8
29 changed files with 70 additions and 178 deletions

View File

@ -192,7 +192,7 @@ public class Bootstrap {
@SuppressForbidden(reason = "Exception#printStackTrace()") @SuppressForbidden(reason = "Exception#printStackTrace()")
private static void setupLogging(Settings settings, Environment environment) { private static void setupLogging(Settings settings, Environment environment) {
try { try {
settings.getClassLoader().loadClass("org.apache.log4j.Logger"); Class.forName("org.apache.log4j.Logger");
LogConfigurator.configure(settings); LogConfigurator.configure(settings);
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
// no log4j // no log4j

View File

@ -23,6 +23,7 @@ import com.carrotsearch.hppc.cursors.ObjectCursor;
import com.carrotsearch.hppc.cursors.ObjectObjectCursor; import com.carrotsearch.hppc.cursors.ObjectObjectCursor;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.Version; import org.elasticsearch.Version;
import org.elasticsearch.cluster.Diff; import org.elasticsearch.cluster.Diff;
import org.elasticsearch.cluster.Diffable; import org.elasticsearch.cluster.Diffable;
@ -251,7 +252,12 @@ public class IndexMetaData implements Diffable<IndexMetaData>, FromXContentBuild
if (hashFunction == null) { if (hashFunction == null) {
routingHashFunction = MURMUR3_HASH_FUNCTION; routingHashFunction = MURMUR3_HASH_FUNCTION;
} else { } else {
final Class<? extends HashFunction> hashFunctionClass = Classes.loadClass(getClass().getClassLoader(), hashFunction); final Class<? extends HashFunction> hashFunctionClass;
try {
hashFunctionClass = Class.forName(hashFunction).asSubclass(HashFunction.class);
} catch (ClassNotFoundException|NoClassDefFoundError e) {
throw new ElasticsearchException("failed to load custom hash function [" + hashFunction + "]", e);
}
try { try {
routingHashFunction = hashFunctionClass.newInstance(); routingHashFunction = hashFunctionClass.newInstance();
} catch (InstantiationException | IllegalAccessException e) { } catch (InstantiationException | IllegalAccessException e) {

View File

@ -20,6 +20,7 @@ package org.elasticsearch.cluster.metadata;
import com.carrotsearch.hppc.cursors.ObjectCursor; import com.carrotsearch.hppc.cursors.ObjectCursor;
import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.Analyzer;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.Version; import org.elasticsearch.Version;
import org.elasticsearch.cluster.routing.DjbHashFunction; import org.elasticsearch.cluster.routing.DjbHashFunction;
import org.elasticsearch.cluster.routing.HashFunction; import org.elasticsearch.cluster.routing.HashFunction;
@ -78,7 +79,11 @@ public class MetaDataIndexUpgradeService extends AbstractComponent {
pre20HashFunction = DjbHashFunction.class; pre20HashFunction = DjbHashFunction.class;
break; break;
default: default:
pre20HashFunction = Classes.loadClass(getClass().getClassLoader(), pre20HashFunctionName); try {
pre20HashFunction = Class.forName(pre20HashFunctionName).asSubclass(HashFunction.class);
} catch (ClassNotFoundException|NoClassDefFoundError e) {
throw new ElasticsearchException("failed to load custom hash function [" + pre20HashFunctionName + "]", e);
}
} }
} else { } else {
pre20HashFunction = DjbHashFunction.class; pre20HashFunction = DjbHashFunction.class;

View File

@ -19,17 +19,7 @@
package org.elasticsearch.common; package org.elasticsearch.common;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.bootstrap.Elasticsearch;
import org.elasticsearch.common.inject.Module;
import org.elasticsearch.common.settings.NoClassSettingsException;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Locale;
import static org.elasticsearch.common.Strings.toCamelCase;
/** /**
* *
@ -41,34 +31,6 @@ public class Classes {
*/ */
private static final char PACKAGE_SEPARATOR = '.'; private static final char PACKAGE_SEPARATOR = '.';
/**
* Return the default ClassLoader to use: typically the thread context
* ClassLoader, if available; the ClassLoader that loaded the ClassUtils
* class will be used as fallback.
* <p/>
* <p>Call this method if you intend to use the thread context ClassLoader
* in a scenario where you absolutely need a non-null ClassLoader reference:
* for example, for class path resource loading (but not necessarily for
* <code>Class.forName</code>, which accepts a <code>null</code> ClassLoader
* reference as well).
*
* @return the default ClassLoader (never <code>null</code>)
* @see java.lang.Thread#getContextClassLoader()
*/
public static ClassLoader getDefaultClassLoader() {
ClassLoader cl = null;
try {
cl = Thread.currentThread().getContextClassLoader();
} catch (Throwable ex) {
// Cannot access thread context ClassLoader - falling back to system class loader...
}
if (cl == null) {
// No thread context class loader -> use class loader of this class.
cl = Classes.class.getClassLoader();
}
return cl;
}
/** /**
* Determine the name of the package of the given class: * Determine the name of the package of the given class:
* e.g. "java.lang" for the <code>java.lang.String</code> class. * e.g. "java.lang" for the <code>java.lang.String</code> class.
@ -93,13 +55,5 @@ public class Classes {
return !clazz.isInterface() && !Modifier.isAbstract(modifiers); return !clazz.isInterface() && !Modifier.isAbstract(modifiers);
} }
public static <T> Class<? extends T> loadClass(ClassLoader classLoader, String className) {
try {
return (Class<? extends T>) classLoader.loadClass(className);
} catch (ClassNotFoundException|NoClassDefFoundError e) {
throw new ElasticsearchException("failed to load class [" + className + "]", e);
}
}
private Classes() {} private Classes() {}
} }

View File

@ -31,7 +31,7 @@ public class ShapesAvailability {
static { static {
boolean xSPATIAL4J_AVAILABLE; boolean xSPATIAL4J_AVAILABLE;
try { try {
Classes.getDefaultClassLoader().loadClass("com.spatial4j.core.shape.impl.PointImpl"); Class.forName("com.spatial4j.core.shape.impl.PointImpl");
xSPATIAL4J_AVAILABLE = true; xSPATIAL4J_AVAILABLE = true;
} catch (Throwable t) { } catch (Throwable t) {
xSPATIAL4J_AVAILABLE = false; xSPATIAL4J_AVAILABLE = false;
@ -40,7 +40,7 @@ public class ShapesAvailability {
boolean xJTS_AVAILABLE; boolean xJTS_AVAILABLE;
try { try {
Classes.getDefaultClassLoader().loadClass("com.vividsolutions.jts.geom.GeometryFactory"); Class.forName("com.vividsolutions.jts.geom.GeometryFactory");
xJTS_AVAILABLE = true; xJTS_AVAILABLE = true;
} catch (Throwable t) { } catch (Throwable t) {
xJTS_AVAILABLE = false; xJTS_AVAILABLE = false;

View File

@ -30,10 +30,6 @@ import java.lang.reflect.Constructor;
*/ */
public class Modules { public class Modules {
public static Module createModule(String moduleClass, Settings settings) throws ClassNotFoundException {
return createModule((Class<? extends Module>) settings.getClassLoader().loadClass(moduleClass), settings);
}
public static Module createModule(Class<? extends Module> moduleClass, @Nullable Settings settings) { public static Module createModule(Class<? extends Module> moduleClass, @Nullable Settings settings) {
Constructor<? extends Module> constructor; Constructor<? extends Module> constructor;
try { try {

View File

@ -79,9 +79,8 @@ public final class Settings implements ToXContent {
private ImmutableMap<String, String> settings; private ImmutableMap<String, String> settings;
private final ImmutableMap<String, String> forcedUnderscoreSettings; private final ImmutableMap<String, String> forcedUnderscoreSettings;
private transient ClassLoader classLoader;
Settings(Map<String, String> settings, ClassLoader classLoader) { Settings(Map<String, String> settings) {
// we use a sorted map for consistent serialization when using getAsMap() // we use a sorted map for consistent serialization when using getAsMap()
// TODO: use Collections.unmodifiableMap with a TreeMap // TODO: use Collections.unmodifiableMap with a TreeMap
this.settings = ImmutableSortedMap.copyOf(settings); this.settings = ImmutableSortedMap.copyOf(settings);
@ -96,22 +95,6 @@ public final class Settings implements ToXContent {
} }
} }
this.forcedUnderscoreSettings = forcedUnderscoreSettings == null ? ImmutableMap.<String, String>of() : ImmutableMap.copyOf(forcedUnderscoreSettings); this.forcedUnderscoreSettings = forcedUnderscoreSettings == null ? ImmutableMap.<String, String>of() : ImmutableMap.copyOf(forcedUnderscoreSettings);
this.classLoader = classLoader;
}
/**
* The class loader associated with this settings, or {@link org.elasticsearch.common.Classes#getDefaultClassLoader()}
* if not set.
*/
public ClassLoader getClassLoader() {
return this.classLoader == null ? Classes.getDefaultClassLoader() : classLoader;
}
/**
* The class loader associated with this settings, but only if explicitly set, otherwise <tt>null</tt>.
*/
public ClassLoader getClassLoaderIfSet() {
return this.classLoader;
} }
/** /**
@ -227,7 +210,6 @@ public final class Settings implements ToXContent {
builder.put(entry.getKey().substring(prefix.length()), entry.getValue()); builder.put(entry.getKey().substring(prefix.length()), entry.getValue());
} }
} }
builder.classLoader(classLoader);
return builder.build(); return builder.build();
} }
@ -648,7 +630,7 @@ public final class Settings implements ToXContent {
} }
Map<String, Settings> retVal = new LinkedHashMap<>(); Map<String, Settings> retVal = new LinkedHashMap<>();
for (Map.Entry<String, Map<String, String>> entry : map.entrySet()) { for (Map.Entry<String, Map<String, String>> entry : map.entrySet()) {
retVal.put(entry.getKey(), new Settings(Collections.unmodifiableMap(entry.getValue()), classLoader)); retVal.put(entry.getKey(), new Settings(Collections.unmodifiableMap(entry.getValue())));
} }
return Collections.unmodifiableMap(retVal); return Collections.unmodifiableMap(retVal);
} }
@ -701,17 +683,13 @@ public final class Settings implements ToXContent {
if (o == null || getClass() != o.getClass()) return false; if (o == null || getClass() != o.getClass()) return false;
Settings that = (Settings) o; Settings that = (Settings) o;
if (classLoader != null ? !classLoader.equals(that.classLoader) : that.classLoader != null) return false;
if (settings != null ? !settings.equals(that.settings) : that.settings != null) return false; if (settings != null ? !settings.equals(that.settings) : that.settings != null) return false;
return true; return true;
} }
@Override @Override
public int hashCode() { public int hashCode() {
int result = settings != null ? settings.hashCode() : 0; int result = settings != null ? settings.hashCode() : 0;
result = 31 * result + (classLoader != null ? classLoader.hashCode() : 0);
return result; return result;
} }
@ -769,8 +747,6 @@ public final class Settings implements ToXContent {
private final Map<String, String> map = new LinkedHashMap<>(); private final Map<String, String> map = new LinkedHashMap<>();
private ClassLoader classLoader;
private Builder() { private Builder() {
} }
@ -998,7 +974,6 @@ public final class Settings implements ToXContent {
public Builder put(Settings settings) { public Builder put(Settings settings) {
removeNonArraysFieldsIfNewSettingsContainsFieldAsArray(settings.getAsMap()); removeNonArraysFieldsIfNewSettingsContainsFieldAsArray(settings.getAsMap());
map.putAll(settings.getAsMap()); map.putAll(settings.getAsMap());
classLoader = settings.getClassLoaderIfSet();
return this; return this;
} }
@ -1118,31 +1093,6 @@ public final class Settings implements ToXContent {
return this; return this;
} }
/**
* Loads settings from classpath that represents them using the
* {@link SettingsLoaderFactory#loaderFromSource(String)}.
*/
public Builder loadFromClasspath(String resourceName) throws SettingsException {
ClassLoader classLoader = this.classLoader;
if (classLoader == null) {
classLoader = Classes.getDefaultClassLoader();
}
InputStream is = classLoader.getResourceAsStream(resourceName);
if (is == null) {
throw new SettingsException("Failed to load settings from [" + resourceName + "]");
}
return loadFromStream(resourceName, is);
}
/**
* Sets the class loader associated with the settings built.
*/
public Builder classLoader(ClassLoader classLoader) {
this.classLoader = classLoader;
return this;
}
/** /**
* Puts all the properties with keys starting with the provided <tt>prefix</tt>. * Puts all the properties with keys starting with the provided <tt>prefix</tt>.
* *
@ -1270,7 +1220,7 @@ public final class Settings implements ToXContent {
* set on this builder. * set on this builder.
*/ */
public Settings build() { public Settings build() {
return new Settings(Collections.unmodifiableMap(map), classLoader); return new Settings(Collections.unmodifiableMap(map));
} }
} }

View File

@ -319,13 +319,14 @@ public class Environment {
} }
} }
// try and load it from the classpath directly // try and load it from the classpath directly
URL resource = settings.getClassLoader().getResource(path); // TODO: remove this, callers can look up their own config on classpath
URL resource = getClass().getClassLoader().getResource(path);
if (resource != null) { if (resource != null) {
return resource; return resource;
} }
// try and load it from the classpath with config/ prefix // try and load it from the classpath with config/ prefix
if (!path.startsWith("config/")) { if (!path.startsWith("config/")) {
resource = settings.getClassLoader().getResource("config/" + path); resource = getClass().getClassLoader().getResource("config/" + path);
if (resource != null) { if (resource != null) {
return resource; return resource;
} }

View File

@ -300,7 +300,6 @@ public class IndicesService extends AbstractLifecycleComponent<IndicesService> i
Settings indexSettings = settingsBuilder() Settings indexSettings = settingsBuilder()
.put(this.settings) .put(this.settings)
.put(settings) .put(settings)
.classLoader(settings.getClassLoader())
.build(); .build();
ModulesBuilder modules = new ModulesBuilder(); ModulesBuilder modules = new ModulesBuilder();

View File

@ -180,7 +180,7 @@ public class InternalSettingsPreparer {
static Settings replacePromptPlaceholders(Settings settings, Terminal terminal) { static Settings replacePromptPlaceholders(Settings settings, Terminal terminal) {
UnmodifiableIterator<Map.Entry<String, String>> iter = settings.getAsMap().entrySet().iterator(); UnmodifiableIterator<Map.Entry<String, String>> iter = settings.getAsMap().entrySet().iterator();
Settings.Builder builder = Settings.builder().classLoader(settings.getClassLoaderIfSet()); Settings.Builder builder = Settings.builder();
while (iter.hasNext()) { while (iter.hasNext()) {
Map.Entry<String, String> entry = iter.next(); Map.Entry<String, String> entry = iter.next();

View File

@ -95,7 +95,7 @@ public class PluginsService extends AbstractComponent {
// this is a hack for what is between unit and integration tests... // this is a hack for what is between unit and integration tests...
String[] defaultPluginsClasses = settings.getAsArray("plugin.types"); String[] defaultPluginsClasses = settings.getAsArray("plugin.types");
for (String pluginClass : defaultPluginsClasses) { for (String pluginClass : defaultPluginsClasses) {
Plugin plugin = loadPlugin(pluginClass, settings); Plugin plugin = loadPlugin(pluginClass, settings, getClass().getClassLoader());
PluginInfo pluginInfo = new PluginInfo(plugin.name(), plugin.description(), false, "NA", true, pluginClass, false); PluginInfo pluginInfo = new PluginInfo(plugin.name(), plugin.description(), false, "NA", true, pluginClass, false);
if (logger.isTraceEnabled()) { if (logger.isTraceEnabled()) {
logger.trace("plugin loaded from settings [{}]", pluginInfo); logger.trace("plugin loaded from settings [{}]", pluginInfo);
@ -347,7 +347,7 @@ public class PluginsService extends AbstractComponent {
// pluginmanager does it, but we do it again, in case lusers mess with jar files manually // pluginmanager does it, but we do it again, in case lusers mess with jar files manually
try { try {
final List<URL> jars = new ArrayList<>(); final List<URL> jars = new ArrayList<>();
ClassLoader parentLoader = settings.getClassLoader(); ClassLoader parentLoader = getClass().getClassLoader();
if (parentLoader instanceof URLClassLoader) { if (parentLoader instanceof URLClassLoader) {
for (URL url : ((URLClassLoader) parentLoader).getURLs()) { for (URL url : ((URLClassLoader) parentLoader).getURLs()) {
jars.add(url); jars.add(url);
@ -360,16 +360,11 @@ public class PluginsService extends AbstractComponent {
} }
// create a child to load the plugins in this bundle // create a child to load the plugins in this bundle
ClassLoader loader = URLClassLoader.newInstance(bundle.urls.toArray(new URL[0]), settings.getClassLoader()); ClassLoader loader = URLClassLoader.newInstance(bundle.urls.toArray(new URL[0]), getClass().getClassLoader());
Settings settings = Settings.builder()
.put(this.settings)
.classLoader(loader)
.build();
for (PluginInfo pluginInfo : bundle.plugins) { for (PluginInfo pluginInfo : bundle.plugins) {
final Plugin plugin; final Plugin plugin;
if (pluginInfo.isJvm()) { if (pluginInfo.isJvm()) {
plugin = loadPlugin(pluginInfo.getClassname(), settings); plugin = loadPlugin(pluginInfo.getClassname(), settings, loader);
} else { } else {
plugin = new SitePlugin(pluginInfo.getName(), pluginInfo.getDescription()); plugin = new SitePlugin(pluginInfo.getName(), pluginInfo.getDescription());
} }
@ -380,9 +375,9 @@ public class PluginsService extends AbstractComponent {
return plugins.build(); return plugins.build();
} }
private Plugin loadPlugin(String className, Settings settings) { private Plugin loadPlugin(String className, Settings settings, ClassLoader loader) {
try { try {
Class<? extends Plugin> pluginClass = settings.getClassLoader().loadClass(className).asSubclass(Plugin.class); Class<? extends Plugin> pluginClass = loader.loadClass(className).asSubclass(Plugin.class);
try { try {
return pluginClass.getConstructor(Settings.class).newInstance(settings); return pluginClass.getConstructor(Settings.class).newInstance(settings);

View File

@ -79,21 +79,21 @@ public class ScriptModule extends AbstractModule {
multibinder.addBinding().to(NativeScriptEngineService.class); multibinder.addBinding().to(NativeScriptEngineService.class);
try { try {
settings.getClassLoader().loadClass("groovy.lang.GroovyClassLoader"); Class.forName("groovy.lang.GroovyClassLoader");
multibinder.addBinding().to(GroovyScriptEngineService.class).asEagerSingleton(); multibinder.addBinding().to(GroovyScriptEngineService.class).asEagerSingleton();
} catch (Throwable t) { } catch (Throwable t) {
Loggers.getLogger(ScriptService.class, settings).debug("failed to load groovy", t); Loggers.getLogger(ScriptService.class, settings).debug("failed to load groovy", t);
} }
try { try {
settings.getClassLoader().loadClass("com.github.mustachejava.Mustache"); Class.forName("com.github.mustachejava.Mustache");
multibinder.addBinding().to(MustacheScriptEngineService.class).asEagerSingleton(); multibinder.addBinding().to(MustacheScriptEngineService.class).asEagerSingleton();
} catch (Throwable t) { } catch (Throwable t) {
Loggers.getLogger(ScriptService.class, settings).debug("failed to load mustache", t); Loggers.getLogger(ScriptService.class, settings).debug("failed to load mustache", t);
} }
try { try {
settings.getClassLoader().loadClass("org.apache.lucene.expressions.Expression"); Class.forName("org.apache.lucene.expressions.Expression");
multibinder.addBinding().to(ExpressionScriptEngineService.class).asEagerSingleton(); multibinder.addBinding().to(ExpressionScriptEngineService.class).asEagerSingleton();
} catch (Throwable t) { } catch (Throwable t) {
Loggers.getLogger(ScriptService.class, settings).debug("failed to load lucene expressions", t); Loggers.getLogger(ScriptService.class, settings).debug("failed to load lucene expressions", t);

View File

@ -70,7 +70,7 @@ public class GroovyScriptEngineService extends AbstractComponent implements Scri
config.addCompilationCustomizers(imports); config.addCompilationCustomizers(imports);
// Add BigDecimal -> Double transformer // Add BigDecimal -> Double transformer
config.addCompilationCustomizers(new GroovyBigDecimalTransformer(CompilePhase.CONVERSION)); config.addCompilationCustomizers(new GroovyBigDecimalTransformer(CompilePhase.CONVERSION));
this.loader = new GroovyClassLoader(settings.getClassLoader(), config); this.loader = new GroovyClassLoader(getClass().getClassLoader(), config);
} }
@Override @Override

View File

@ -152,7 +152,7 @@ public class ExceptionSerializationTests extends ESTestCase {
pkg.append(p.getFileName().toString()).append("."); pkg.append(p.getFileName().toString()).append(".");
} }
pkg.append(filename.substring(0, filename.length() - 6)); pkg.append(filename.substring(0, filename.length() - 6));
return Thread.currentThread().getContextClassLoader().loadClass(pkg.toString()); return getClass().getClassLoader().loadClass(pkg.toString());
} }
@Override @Override

View File

@ -34,8 +34,9 @@ public class JsonSettingsLoaderTests extends ESTestCase {
@Test @Test
public void testSimpleJsonSettings() throws Exception { public void testSimpleJsonSettings() throws Exception {
String json = "/org/elasticsearch/common/settings/loader/test-settings.json";
Settings settings = settingsBuilder() Settings settings = settingsBuilder()
.loadFromClasspath("org/elasticsearch/common/settings/loader/test-settings.json") .loadFromStream(json, getClass().getResourceAsStream(json))
.build(); .build();
assertThat(settings.get("test1.value1"), equalTo("value1")); assertThat(settings.get("test1.value1"), equalTo("value1"));

View File

@ -34,8 +34,9 @@ public class YamlSettingsLoaderTests extends ESTestCase {
@Test @Test
public void testSimpleYamlSettings() throws Exception { public void testSimpleYamlSettings() throws Exception {
String yaml = "/org/elasticsearch/common/settings/loader/test-settings.yml";
Settings settings = settingsBuilder() Settings settings = settingsBuilder()
.loadFromClasspath("org/elasticsearch/common/settings/loader/test-settings.yml") .loadFromStream(yaml, getClass().getResourceAsStream(yaml))
.build(); .build();
assertThat(settings.get("test1.value1"), equalTo("value1")); assertThat(settings.get("test1.value1"), equalTo("value1"));
@ -52,28 +53,17 @@ public class YamlSettingsLoaderTests extends ESTestCase {
@Test(expected = SettingsException.class) @Test(expected = SettingsException.class)
public void testIndentation() { public void testIndentation() {
String yaml = "/org/elasticsearch/common/settings/loader/indentation-settings.yml";
settingsBuilder() settingsBuilder()
.loadFromClasspath("org/elasticsearch/common/settings/loader/indentation-settings.yml") .loadFromStream(yaml, getClass().getResourceAsStream(yaml))
.build(); .build();
} }
@Test(expected = SettingsException.class) @Test(expected = SettingsException.class)
public void testIndentationWithExplicitDocumentStart() { public void testIndentationWithExplicitDocumentStart() {
String yaml = "/org/elasticsearch/common/settings/loader/indentation-with-explicit-document-start-settings.yml";
settingsBuilder() settingsBuilder()
.loadFromClasspath("org/elasticsearch/common/settings/loader/indentation-with-explicit-document-start-settings.yml") .loadFromStream(yaml, getClass().getResourceAsStream(yaml))
.build(); .build();
} }
@Test
public void testYamlSettingsNoFile() throws Exception {
String invalidResourceName = "org/elasticsearch/common/settings/loader/no-test-settings.yml";
try {
Settings defaultSettings = settingsBuilder().loadFromClasspath(invalidResourceName).build();
fail("For a not exiting file an exception should be thrown.");
} catch (Exception e) {
assertTrue(e instanceof SettingsException);
assertThat(e.getMessage(), equalTo("Failed to load settings from [" + invalidResourceName + "]"));
}
}
} }

View File

@ -79,7 +79,7 @@ public class AnalysisModuleTests extends ESTestCase {
} }
private Settings loadFromClasspath(String path) { private Settings loadFromClasspath(String path) {
return settingsBuilder().loadFromClasspath(path) return settingsBuilder().loadFromStream(path, getClass().getResourceAsStream(path))
.put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT) .put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT)
.put("path.home", createTempDir().toString()) .put("path.home", createTempDir().toString())
.build(); .build();
@ -88,13 +88,13 @@ public class AnalysisModuleTests extends ESTestCase {
@Test @Test
public void testSimpleConfigurationJson() { public void testSimpleConfigurationJson() {
Settings settings = loadFromClasspath("org/elasticsearch/index/analysis/test1.json"); Settings settings = loadFromClasspath("/org/elasticsearch/index/analysis/test1.json");
testSimpleConfiguration(settings); testSimpleConfiguration(settings);
} }
@Test @Test
public void testSimpleConfigurationYaml() { public void testSimpleConfigurationYaml() {
Settings settings = loadFromClasspath("org/elasticsearch/index/analysis/test1.yml"); Settings settings = loadFromClasspath("/org/elasticsearch/index/analysis/test1.yml");
testSimpleConfiguration(settings); testSimpleConfiguration(settings);
} }
@ -107,8 +107,9 @@ public class AnalysisModuleTests extends ESTestCase {
@Test @Test
public void testVersionedAnalyzers() throws Exception { public void testVersionedAnalyzers() throws Exception {
String yaml = "/org/elasticsearch/index/analysis/test1.yml";
Settings settings2 = settingsBuilder() Settings settings2 = settingsBuilder()
.loadFromClasspath("org/elasticsearch/index/analysis/test1.yml") .loadFromStream(yaml, getClass().getResourceAsStream(yaml))
.put("path.home", createTempDir().toString()) .put("path.home", createTempDir().toString())
.put(IndexMetaData.SETTING_VERSION_CREATED, Version.V_0_90_0) .put(IndexMetaData.SETTING_VERSION_CREATED, Version.V_0_90_0)
.build(); .build();

View File

@ -39,7 +39,7 @@ public class AnalysisTestsHelper {
public static AnalysisService createAnalysisServiceFromClassPath(Path baseDir, String resource) { public static AnalysisService createAnalysisServiceFromClassPath(Path baseDir, String resource) {
Settings settings = Settings.settingsBuilder() Settings settings = Settings.settingsBuilder()
.loadFromClasspath(resource) .loadFromStream(resource, AnalysisTestsHelper.class.getResourceAsStream(resource))
.put("path.home", baseDir.toString()) .put("path.home", baseDir.toString())
.build(); .build();

View File

@ -29,7 +29,7 @@ import java.io.StringReader;
public class CJKFilterFactoryTests extends ESTokenStreamTestCase { public class CJKFilterFactoryTests extends ESTokenStreamTestCase {
private static final String RESOURCE = "org/elasticsearch/index/analysis/cjk_analysis.json"; private static final String RESOURCE = "/org/elasticsearch/index/analysis/cjk_analysis.json";
@Test @Test
public void testDefault() throws IOException { public void testDefault() throws IOException {

View File

@ -115,16 +115,18 @@ public class CompoundAnalysisTests extends ESTestCase {
} }
private Settings getJsonSettings() { private Settings getJsonSettings() {
String json = "/org/elasticsearch/index/analysis/test1.json";
return settingsBuilder() return settingsBuilder()
.loadFromClasspath("org/elasticsearch/index/analysis/test1.json") .loadFromStream(json, getClass().getResourceAsStream(json))
.put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT) .put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT)
.put("path.home", createTempDir().toString()) .put("path.home", createTempDir().toString())
.build(); .build();
} }
private Settings getYamlSettings() { private Settings getYamlSettings() {
String yaml = "/org/elasticsearch/index/analysis/test1.yml";
return settingsBuilder() return settingsBuilder()
.loadFromClasspath("org/elasticsearch/index/analysis/test1.yml") .loadFromStream(yaml, getClass().getResourceAsStream(yaml))
.put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT) .put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT)
.put("path.home", createTempDir().toString()) .put("path.home", createTempDir().toString())
.build(); .build();

View File

@ -34,7 +34,7 @@ import static org.hamcrest.Matchers.instanceOf;
public class KeepFilterFactoryTests extends ESTokenStreamTestCase { public class KeepFilterFactoryTests extends ESTokenStreamTestCase {
private static final String RESOURCE = "org/elasticsearch/index/analysis/keep_analysis.json"; private static final String RESOURCE = "/org/elasticsearch/index/analysis/keep_analysis.json";
@Test @Test

View File

@ -41,10 +41,11 @@ public class PatternCaptureTokenFilterTests extends ESTokenStreamTestCase {
@Test @Test
public void testPatternCaptureTokenFilter() throws Exception { public void testPatternCaptureTokenFilter() throws Exception {
String json = "/org/elasticsearch/index/analysis/pattern_capture.json";
Index index = new Index("test"); Index index = new Index("test");
Settings settings = settingsBuilder() Settings settings = settingsBuilder()
.put("path.home", createTempDir()) .put("path.home", createTempDir())
.loadFromClasspath("org/elasticsearch/index/analysis/pattern_capture.json") .loadFromStream(json, getClass().getResourceAsStream(json))
.put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT) .put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT)
.build(); .build();
Injector parentInjector = new ModulesBuilder().add(new SettingsModule(settings), new EnvironmentModule(new Environment(settings)), new IndicesAnalysisModule()).createInjector(); Injector parentInjector = new ModulesBuilder().add(new SettingsModule(settings), new EnvironmentModule(new Environment(settings)), new IndicesAnalysisModule()).createInjector();

View File

@ -36,7 +36,7 @@ import static org.hamcrest.Matchers.instanceOf;
@ThreadLeakScope(Scope.NONE) @ThreadLeakScope(Scope.NONE)
public class ShingleTokenFilterFactoryTests extends ESTokenStreamTestCase { public class ShingleTokenFilterFactoryTests extends ESTokenStreamTestCase {
private static final String RESOURCE = "org/elasticsearch/index/analysis/shingle_analysis.json"; private static final String RESOURCE = "/org/elasticsearch/index/analysis/shingle_analysis.json";
@Test @Test
public void testDefault() throws IOException { public void testDefault() throws IOException {

View File

@ -41,9 +41,10 @@ public class StopAnalyzerTests extends ESTokenStreamTestCase {
@Test @Test
public void testDefaultsCompoundAnalysis() throws Exception { public void testDefaultsCompoundAnalysis() throws Exception {
String json = "/org/elasticsearch/index/analysis/stop.json";
Index index = new Index("test"); Index index = new Index("test");
Settings settings = settingsBuilder() Settings settings = settingsBuilder()
.loadFromClasspath("org/elasticsearch/index/analysis/stop.json") .loadFromStream(json, getClass().getResourceAsStream(json))
.put("path.home", createTempDir().toString()) .put("path.home", createTempDir().toString())
.put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT) .put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT)
.build(); .build();

View File

@ -134,8 +134,9 @@ public class CommonGramsTokenFilterFactoryTests extends ESTokenStreamTestCase {
@Test @Test
public void testCommonGramsAnalysis() throws IOException { public void testCommonGramsAnalysis() throws IOException {
String json = "/org/elasticsearch/index/analysis/commongrams/commongrams.json";
Settings settings = Settings.settingsBuilder() Settings settings = Settings.settingsBuilder()
.loadFromClasspath("org/elasticsearch/index/analysis/commongrams/commongrams.json") .loadFromStream(json, getClass().getResourceAsStream(json))
.put("path.home", createTempDir().toString()) .put("path.home", createTempDir().toString())
.build(); .build();
{ {
@ -218,8 +219,9 @@ public class CommonGramsTokenFilterFactoryTests extends ESTokenStreamTestCase {
@Test @Test
public void testQueryModeCommonGramsAnalysis() throws IOException { public void testQueryModeCommonGramsAnalysis() throws IOException {
String json = "/org/elasticsearch/index/analysis/commongrams/commongrams_query_mode.json";
Settings settings = Settings.settingsBuilder() Settings settings = Settings.settingsBuilder()
.loadFromClasspath("org/elasticsearch/index/analysis/commongrams/commongrams_query_mode.json") .loadFromStream(json, getClass().getResourceAsStream(json))
.put("path.home", createTempDir().toString()) .put("path.home", createTempDir().toString())
.build(); .build();
{ {

View File

@ -59,8 +59,9 @@ public class SynonymsAnalysisTest extends ESTestCase {
@Test @Test
public void testSynonymsAnalysis() throws IOException { public void testSynonymsAnalysis() throws IOException {
String json = "/org/elasticsearch/index/analysis/synonyms/synonyms.json";
Settings settings = settingsBuilder(). Settings settings = settingsBuilder().
loadFromClasspath("org/elasticsearch/index/analysis/synonyms/synonyms.json") loadFromStream(json, getClass().getResourceAsStream(json))
.put("path.home", createTempDir().toString()) .put("path.home", createTempDir().toString())
.put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT).build(); .put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT).build();

View File

@ -222,19 +222,4 @@ public class InternalSettingsPreparerTests extends ESTestCase {
assertThat(settings.get("name"), is("prompted name 0")); assertThat(settings.get("name"), is("prompted name 0"));
assertThat(settings.get("node.name"), is("prompted name 0")); assertThat(settings.get("node.name"), is("prompted name 0"));
} }
@Test
public void testPreserveSettingsClassloader() {
final ClassLoader classLoader = URLClassLoader.newInstance(new URL[0]);
Settings settings = settingsBuilder()
.put("foo", "bar")
.put("path.home", createTempDir())
.classLoader(classLoader)
.build();
Tuple<Settings, Environment> tuple = InternalSettingsPreparer.prepareSettings(settings, randomBoolean());
Settings preparedSettings = tuple.v1();
assertThat(preparedSettings.getClassLoaderIfSet(), is(classLoader));
}
} }

View File

@ -191,9 +191,10 @@ public class KuromojiAnalysisTests extends ESTestCase {
public AnalysisService createAnalysisService() { public AnalysisService createAnalysisService() {
String json = "/org/elasticsearch/index/analysis/kuromoji_analysis.json";
Settings settings = Settings.settingsBuilder() Settings settings = Settings.settingsBuilder()
.put("path.home", createTempDir()) .put("path.home", createTempDir())
.loadFromClasspath("org/elasticsearch/index/analysis/kuromoji_analysis.json") .loadFromStream(json, getClass().getResourceAsStream(json))
.put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT) .put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT)
.build(); .build();

View File

@ -45,7 +45,8 @@ public class SimplePhoneticAnalysisTests extends ESTestCase {
@Test @Test
public void testPhoneticTokenFilterFactory() { public void testPhoneticTokenFilterFactory() {
Settings settings = settingsBuilder().loadFromClasspath("org/elasticsearch/index/analysis/phonetic-1.yml") String yaml = "/org/elasticsearch/index/analysis/phonetic-1.yml";
Settings settings = settingsBuilder().loadFromStream(yaml, getClass().getResourceAsStream(yaml))
.put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT) .put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT)
.put("path.home", createTempDir()) .put("path.home", createTempDir())
.build(); .build();