Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove ClassLoader from Settings #12868

Merged
merged 1 commit into from Aug 14, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -192,7 +192,7 @@ private void setupSecurity(Settings settings, Environment environment) throws Ex
@SuppressForbidden(reason = "Exception#printStackTrace()")
private static void setupLogging(Settings settings, Environment environment) {
try {
settings.getClassLoader().loadClass("org.apache.log4j.Logger");
Class.forName("org.apache.log4j.Logger");
LogConfigurator.configure(settings);
} catch (ClassNotFoundException e) {
// no log4j
Expand Down
Expand Up @@ -23,6 +23,7 @@
import com.carrotsearch.hppc.cursors.ObjectObjectCursor;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.Version;
import org.elasticsearch.cluster.Diff;
import org.elasticsearch.cluster.Diffable;
Expand Down Expand Up @@ -251,7 +252,12 @@ private IndexMetaData(String index, long version, State state, Settings settings
if (hashFunction == null) {
routingHashFunction = MURMUR3_HASH_FUNCTION;
} 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 {
routingHashFunction = hashFunctionClass.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
Expand Down
Expand Up @@ -20,6 +20,7 @@

import com.carrotsearch.hppc.cursors.ObjectCursor;
import org.apache.lucene.analysis.Analyzer;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.Version;
import org.elasticsearch.cluster.routing.DjbHashFunction;
import org.elasticsearch.cluster.routing.HashFunction;
Expand Down Expand Up @@ -78,7 +79,11 @@ public MetaDataIndexUpgradeService(Settings settings, ScriptService scriptServic
pre20HashFunction = DjbHashFunction.class;
break;
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 {
pre20HashFunction = DjbHashFunction.class;
Expand Down
46 changes: 0 additions & 46 deletions core/src/main/java/org/elasticsearch/common/Classes.java
Expand Up @@ -19,17 +19,7 @@

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.util.Arrays;
import java.util.Iterator;
import java.util.Locale;

import static org.elasticsearch.common.Strings.toCamelCase;

/**
*
Expand All @@ -41,34 +31,6 @@ public class Classes {
*/
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:
* e.g. "java.lang" for the <code>java.lang.String</code> class.
Expand All @@ -93,13 +55,5 @@ public static boolean isConcrete(Class<?> clazz) {
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() {}
}
Expand Up @@ -31,7 +31,7 @@ public class ShapesAvailability {
static {
boolean xSPATIAL4J_AVAILABLE;
try {
Classes.getDefaultClassLoader().loadClass("com.spatial4j.core.shape.impl.PointImpl");
Class.forName("com.spatial4j.core.shape.impl.PointImpl");
xSPATIAL4J_AVAILABLE = true;
} catch (Throwable t) {
xSPATIAL4J_AVAILABLE = false;
Expand All @@ -40,7 +40,7 @@ public class ShapesAvailability {

boolean xJTS_AVAILABLE;
try {
Classes.getDefaultClassLoader().loadClass("com.vividsolutions.jts.geom.GeometryFactory");
Class.forName("com.vividsolutions.jts.geom.GeometryFactory");
xJTS_AVAILABLE = true;
} catch (Throwable t) {
xJTS_AVAILABLE = false;
Expand Down
Expand Up @@ -30,10 +30,6 @@
*/
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) {
Constructor<? extends Module> constructor;
try {
Expand Down
56 changes: 3 additions & 53 deletions core/src/main/java/org/elasticsearch/common/settings/Settings.java
Expand Up @@ -79,9 +79,8 @@ public static boolean getSettingsRequireUnits() {

private ImmutableMap<String, String> settings;
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()
// TODO: use Collections.unmodifiableMap with a TreeMap
this.settings = ImmutableSortedMap.copyOf(settings);
Expand All @@ -96,22 +95,6 @@ public static boolean getSettingsRequireUnits() {
}
}
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;
}

/**
Expand Down Expand Up @@ -227,7 +210,6 @@ public Settings getByPrefix(String prefix) {
builder.put(entry.getKey().substring(prefix.length()), entry.getValue());
}
}
builder.classLoader(classLoader);
return builder.build();
}

Expand Down Expand Up @@ -648,7 +630,7 @@ public Map<String, Settings> getGroups(String settingPrefix, boolean ignoreNonGr
}
Map<String, Settings> retVal = new LinkedHashMap<>();
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);
}
Expand Down Expand Up @@ -701,17 +683,13 @@ public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;

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;

return true;
}

@Override
public int hashCode() {
int result = settings != null ? settings.hashCode() : 0;
result = 31 * result + (classLoader != null ? classLoader.hashCode() : 0);
return result;
}

Expand Down Expand Up @@ -769,8 +747,6 @@ public static class Builder {

private final Map<String, String> map = new LinkedHashMap<>();

private ClassLoader classLoader;

private Builder() {

}
Expand Down Expand Up @@ -998,7 +974,6 @@ public Builder put(String settingPrefix, String groupName, String[] settings, St
public Builder put(Settings settings) {
removeNonArraysFieldsIfNewSettingsContainsFieldAsArray(settings.getAsMap());
map.putAll(settings.getAsMap());
classLoader = settings.getClassLoaderIfSet();
return this;
}

Expand Down Expand Up @@ -1118,31 +1093,6 @@ public Builder loadFromStream(String resourceName, InputStream is) throws Settin
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>.
*
Expand Down Expand Up @@ -1270,7 +1220,7 @@ public Builder normalizePrefix(String prefix) {
* set on this builder.
*/
public Settings build() {
return new Settings(Collections.unmodifiableMap(map), classLoader);
return new Settings(Collections.unmodifiableMap(map));
}
}

Expand Down
5 changes: 3 additions & 2 deletions core/src/main/java/org/elasticsearch/env/Environment.java
Expand Up @@ -319,13 +319,14 @@ public URL resolveConfig(String path) throws FailedToResolveConfigException {
}
}
// 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) {
return resource;
}
// try and load it from the classpath with config/ prefix
if (!path.startsWith("config/")) {
resource = settings.getClassLoader().getResource("config/" + path);
resource = getClass().getClassLoader().getResource("config/" + path);
if (resource != null) {
return resource;
}
Expand Down
Expand Up @@ -300,7 +300,6 @@ public synchronized IndexService createIndex(String sIndexName, @IndexSettings S
Settings indexSettings = settingsBuilder()
.put(this.settings)
.put(settings)
.classLoader(settings.getClassLoader())
.build();

ModulesBuilder modules = new ModulesBuilder();
Expand Down
Expand Up @@ -180,7 +180,7 @@ public static Tuple<Settings, Environment> prepareSettings(Settings pSettings, b

static Settings replacePromptPlaceholders(Settings settings, Terminal terminal) {
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()) {
Map.Entry<String, String> entry = iter.next();
Expand Down
17 changes: 6 additions & 11 deletions core/src/main/java/org/elasticsearch/plugins/PluginsService.java
Expand Up @@ -95,7 +95,7 @@ public PluginsService(Settings settings, Environment environment) {
// this is a hack for what is between unit and integration tests...
String[] defaultPluginsClasses = settings.getAsArray("plugin.types");
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);
if (logger.isTraceEnabled()) {
logger.trace("plugin loaded from settings [{}]", pluginInfo);
Expand Down Expand Up @@ -347,7 +347,7 @@ private List<Tuple<PluginInfo,Plugin>> loadBundles(List<Bundle> bundles) {
// pluginmanager does it, but we do it again, in case lusers mess with jar files manually
try {
final List<URL> jars = new ArrayList<>();
ClassLoader parentLoader = settings.getClassLoader();
ClassLoader parentLoader = getClass().getClassLoader();
if (parentLoader instanceof URLClassLoader) {
for (URL url : ((URLClassLoader) parentLoader).getURLs()) {
jars.add(url);
Expand All @@ -360,16 +360,11 @@ private List<Tuple<PluginInfo,Plugin>> loadBundles(List<Bundle> bundles) {
}

// create a child to load the plugins in this bundle
ClassLoader loader = URLClassLoader.newInstance(bundle.urls.toArray(new URL[0]), settings.getClassLoader());
Settings settings = Settings.builder()
.put(this.settings)
.classLoader(loader)
.build();

ClassLoader loader = URLClassLoader.newInstance(bundle.urls.toArray(new URL[0]), getClass().getClassLoader());
for (PluginInfo pluginInfo : bundle.plugins) {
final Plugin plugin;
if (pluginInfo.isJvm()) {
plugin = loadPlugin(pluginInfo.getClassname(), settings);
plugin = loadPlugin(pluginInfo.getClassname(), settings, loader);
} else {
plugin = new SitePlugin(pluginInfo.getName(), pluginInfo.getDescription());
}
Expand All @@ -380,9 +375,9 @@ private List<Tuple<PluginInfo,Plugin>> loadBundles(List<Bundle> bundles) {
return plugins.build();
}

private Plugin loadPlugin(String className, Settings settings) {
private Plugin loadPlugin(String className, Settings settings, ClassLoader loader) {
try {
Class<? extends Plugin> pluginClass = settings.getClassLoader().loadClass(className).asSubclass(Plugin.class);
Class<? extends Plugin> pluginClass = loader.loadClass(className).asSubclass(Plugin.class);

try {
return pluginClass.getConstructor(Settings.class).newInstance(settings);
Expand Down
6 changes: 3 additions & 3 deletions core/src/main/java/org/elasticsearch/script/ScriptModule.java
Expand Up @@ -79,21 +79,21 @@ protected void configure() {
multibinder.addBinding().to(NativeScriptEngineService.class);

try {
settings.getClassLoader().loadClass("groovy.lang.GroovyClassLoader");
Class.forName("groovy.lang.GroovyClassLoader");
multibinder.addBinding().to(GroovyScriptEngineService.class).asEagerSingleton();
} catch (Throwable t) {
Loggers.getLogger(ScriptService.class, settings).debug("failed to load groovy", t);
}

try {
settings.getClassLoader().loadClass("com.github.mustachejava.Mustache");
Class.forName("com.github.mustachejava.Mustache");
multibinder.addBinding().to(MustacheScriptEngineService.class).asEagerSingleton();
} catch (Throwable t) {
Loggers.getLogger(ScriptService.class, settings).debug("failed to load mustache", t);
}

try {
settings.getClassLoader().loadClass("org.apache.lucene.expressions.Expression");
Class.forName("org.apache.lucene.expressions.Expression");
multibinder.addBinding().to(ExpressionScriptEngineService.class).asEagerSingleton();
} catch (Throwable t) {
Loggers.getLogger(ScriptService.class, settings).debug("failed to load lucene expressions", t);
Expand Down
Expand Up @@ -70,7 +70,7 @@ public GroovyScriptEngineService(Settings settings) {
config.addCompilationCustomizers(imports);
// Add BigDecimal -> Double transformer
config.addCompilationCustomizers(new GroovyBigDecimalTransformer(CompilePhase.CONVERSION));
this.loader = new GroovyClassLoader(settings.getClassLoader(), config);
this.loader = new GroovyClassLoader(getClass().getClassLoader(), config);
}

@Override
Expand Down