improve class loader to use the class loader set in the settings constructing the node

This commit is contained in:
Shay Banon 2012-02-12 23:55:16 +02:00
parent 0729413341
commit 0ff84d222f
11 changed files with 35 additions and 248 deletions

View File

@ -21,7 +21,6 @@ package org.elasticsearch.bootstrap;
import org.elasticsearch.ExceptionsHelper;
import org.elasticsearch.Version;
import org.elasticsearch.common.Classes;
import org.elasticsearch.common.collect.Tuple;
import org.elasticsearch.common.inject.CreationException;
import org.elasticsearch.common.inject.spi.Message;
@ -88,7 +87,7 @@ public class Bootstrap {
private static void setupLogging(Tuple<Settings, Environment> tuple) {
try {
Classes.getDefaultClassLoader().loadClass("org.apache.log4j.Logger");
tuple.v1().getClassLoader().loadClass("org.apache.log4j.Logger");
LogConfigurator.configure(tuple.v1());
} catch (ClassNotFoundException e) {
// no log4j

View File

@ -1,96 +0,0 @@
/*
* Licensed to ElasticSearch and Shay Banon under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. ElasticSearch licenses this
* file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.common.io;
import org.elasticsearch.common.Classes;
import java.io.*;
/**
*
*/
class CompactObjectInputStream extends ObjectInputStream {
private final ClassLoader classLoader;
CompactObjectInputStream(InputStream in) throws IOException {
this(in, null);
}
CompactObjectInputStream(InputStream in, ClassLoader classLoader) throws IOException {
super(in);
this.classLoader = classLoader;
}
@Override
protected void readStreamHeader() throws IOException,
StreamCorruptedException {
int version = readByte() & 0xFF;
if (version != STREAM_VERSION) {
throw new StreamCorruptedException(
"Unsupported version: " + version);
}
}
@Override
protected ObjectStreamClass readClassDescriptor()
throws IOException, ClassNotFoundException {
int type = read();
if (type < 0) {
throw new EOFException();
}
switch (type) {
case CompactObjectOutputStream.TYPE_FAT_DESCRIPTOR:
return super.readClassDescriptor();
case CompactObjectOutputStream.TYPE_THIN_DESCRIPTOR:
String className = readUTF();
Class<?> clazz = loadClass(className);
return ObjectStreamClass.lookup(clazz);
default:
throw new StreamCorruptedException(
"Unexpected class descriptor type: " + type);
}
}
@Override
protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
String className = desc.getName();
try {
return loadClass(className);
} catch (ClassNotFoundException ex) {
return super.resolveClass(desc);
}
}
protected Class<?> loadClass(String className) throws ClassNotFoundException {
Class<?> clazz;
ClassLoader classLoader = this.classLoader;
if (classLoader == null) {
classLoader = Classes.getDefaultClassLoader();
}
if (classLoader != null) {
clazz = classLoader.loadClass(className);
} else {
clazz = Class.forName(className);
}
return clazz;
}
}

View File

@ -1,55 +0,0 @@
/*
* Licensed to ElasticSearch and Shay Banon under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. ElasticSearch licenses this
* file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.common.io;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamClass;
import java.io.OutputStream;
/**
*
*/
class CompactObjectOutputStream extends ObjectOutputStream {
static final int TYPE_FAT_DESCRIPTOR = 0;
static final int TYPE_THIN_DESCRIPTOR = 1;
CompactObjectOutputStream(OutputStream out) throws IOException {
super(out);
}
@Override
protected void writeStreamHeader() throws IOException {
writeByte(STREAM_VERSION);
}
@Override
protected void writeClassDescriptor(ObjectStreamClass desc) throws IOException {
Class<?> clazz = desc.forClass();
if (clazz.isPrimitive() || clazz.isArray()) {
write(TYPE_FAT_DESCRIPTOR);
super.writeClassDescriptor(desc);
} else {
write(TYPE_THIN_DESCRIPTOR);
writeUTF(desc.getName());
}
}
}

View File

@ -1,79 +0,0 @@
/*
* Licensed to ElasticSearch and Shay Banon under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. ElasticSearch licenses this
* file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.common.io;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.io.Serializable;
/**
*
*/
public final class Serializers {
public static byte[] throwableToBytes(Throwable t) throws IOException {
FastByteArrayOutputStream os = new FastByteArrayOutputStream();
ThrowableObjectOutputStream oos = new ThrowableObjectOutputStream(os);
oos.writeObject(t);
oos.close();
return os.underlyingBytes();
}
public static Throwable throwableFromBytes(byte[] bytes) throws IOException, ClassNotFoundException {
FastByteArrayInputStream is = new FastByteArrayInputStream(bytes);
ThrowableObjectInputStream ois = new ThrowableObjectInputStream(is);
Throwable t = (Throwable) ois.readObject();
ois.close();
return t;
}
public static void objectToStream(Serializable obj, DataOutput out) throws IOException {
byte[] bytes = objectToBytes(obj);
out.writeInt(bytes.length);
out.write(bytes);
}
public static Object objectFromStream(DataInput in) throws ClassNotFoundException, IOException {
byte[] bytes = new byte[in.readInt()];
in.readFully(bytes);
return objectFromBytes(bytes);
}
public static byte[] objectToBytes(Serializable obj) throws IOException {
FastByteArrayOutputStream os = new FastByteArrayOutputStream();
CompactObjectOutputStream oos = new CompactObjectOutputStream(os);
oos.writeObject(obj);
oos.close();
return os.underlyingBytes();
}
public static Object objectFromBytes(byte[] bytes) throws IOException, ClassNotFoundException {
FastByteArrayInputStream is = new FastByteArrayInputStream(bytes);
CompactObjectInputStream ois = new CompactObjectInputStream(is);
Object obj = ois.readObject();
ois.close();
return obj;
}
private Serializers() {
}
}

View File

@ -19,6 +19,8 @@
package org.elasticsearch.common.io;
import org.elasticsearch.common.Classes;
import java.io.*;
/**
@ -84,7 +86,7 @@ public class ThrowableObjectInputStream extends ObjectInputStream {
Class<?> clazz;
ClassLoader classLoader = this.classLoader;
if (classLoader == null) {
classLoader = Thread.currentThread().getContextClassLoader();
classLoader = Classes.getDefaultClassLoader();
}
if (classLoader != null) {

View File

@ -59,11 +59,16 @@ public class ImmutableSettings implements Settings {
private ImmutableSettings(Map<String, String> settings, ClassLoader classLoader) {
this.settings = ImmutableMap.copyOf(settings);
this.classLoader = classLoader == null ? buildClassLoader() : classLoader;
this.classLoader = classLoader;
}
@Override
public ClassLoader getClassLoader() {
return this.classLoader == null ? Classes.getDefaultClassLoader() : classLoader;
}
@Override
public ClassLoader getClassLoaderIfSet() {
return this.classLoader;
}
@ -338,10 +343,6 @@ public class ImmutableSettings implements Settings {
return result;
}
private static ClassLoader buildClassLoader() {
return Classes.getDefaultClassLoader();
}
public static Settings readSettingsFromStream(StreamInput in) throws IOException {
Builder builder = new Builder();
int numberOfSettings = in.readVInt();
@ -562,6 +563,7 @@ public class ImmutableSettings implements Settings {
*/
public Builder put(Settings settings) {
map.putAll(settings.getAsMap());
classLoader = settings.getClassLoaderIfSet();
return this;
}
@ -632,7 +634,7 @@ public class ImmutableSettings implements Settings {
public Builder loadFromClasspath(String resourceName) throws SettingsException {
ClassLoader classLoader = this.classLoader;
if (classLoader == null) {
classLoader = buildClassLoader();
classLoader = Classes.getDefaultClassLoader();
}
InputStream is = classLoader.getResourceAsStream(resourceName);
if (is == null) {

View File

@ -21,6 +21,7 @@ package org.elasticsearch.common.settings;
import com.google.common.collect.ImmutableMap;
import org.elasticsearch.Version;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.unit.ByteSizeValue;
import org.elasticsearch.common.unit.SizeValue;
import org.elasticsearch.common.unit.TimeValue;
@ -56,10 +57,17 @@ public interface Settings {
Settings getByPrefix(String prefix);
/**
* The class loader associated with this settings.
* The class loader associated with this settings, or {@link org.elasticsearch.common.Classes#getDefaultClassLoader()}
* if not set.
*/
ClassLoader getClassLoader();
/**
* The class loader associated with this settings, but only if explicitly set, otherwise <tt>null</tt>.
*/
@Nullable
ClassLoader getClassLoaderIfSet();
/**
* The settings as a {@link java.util.Map}.
*/

View File

@ -20,7 +20,6 @@
package org.elasticsearch.env;
import org.elasticsearch.cluster.ClusterName;
import org.elasticsearch.common.Classes;
import org.elasticsearch.common.io.Streams;
import org.elasticsearch.common.settings.Settings;
@ -35,11 +34,11 @@ import static org.elasticsearch.common.settings.ImmutableSettings.Builder.EMPTY_
/**
* The environment of where things exists.
*
*
*/
public class Environment {
private final Settings settings;
private final File homeFile;
private final File workFile;
@ -61,6 +60,7 @@ public class Environment {
}
public Environment(Settings settings) {
this.settings = settings;
if (settings.get("path.home") != null) {
homeFile = new File(cleanPath(settings.get("path.home")));
} else {
@ -106,6 +106,13 @@ public class Environment {
}
}
/**
* The settings used to build this environment.
*/
public Settings settings() {
return this.settings;
}
/**
* The home of the installation.
*/
@ -183,13 +190,13 @@ public class Environment {
}
}
// try and load it from the classpath directly
URL resource = Classes.getDefaultClassLoader().getResource(path);
URL resource = settings.getClassLoader().getResource(path);
if (resource != null) {
return resource;
}
// try and load it from the classpath with config/ prefix
if (!path.startsWith("config/")) {
resource = Classes.getDefaultClassLoader().getResource("config/" + path);
resource = settings.getClassLoader().getResource("config/" + path);
if (resource != null) {
return resource;
}

View File

@ -259,7 +259,6 @@ public class InternalIndicesService extends AbstractLifecycleComponent<IndicesSe
logger.debug("creating Index [{}], shards [{}]/[{}]", sIndexName, settings.get(SETTING_NUMBER_OF_SHARDS), settings.get(SETTING_NUMBER_OF_REPLICAS));
Settings indexSettings = settingsBuilder()
.put("settingsType", "index")
.put(this.settings)
.put(settings)
.classLoader(settings.getClassLoader())

View File

@ -274,7 +274,7 @@ public class LocalTransport extends AbstractLifecycleComponent<Transport> implem
private void handlerResponseError(StreamInput buffer, final TransportResponseHandler handler) {
Throwable error;
try {
ThrowableObjectInputStream ois = new ThrowableObjectInputStream(buffer);
ThrowableObjectInputStream ois = new ThrowableObjectInputStream(buffer, settings.getClassLoader());
error = (Throwable) ois.readObject();
} catch (Exception e) {
error = new TransportSerializationException("Failed to deserialize exception response from stream", e);

View File

@ -271,7 +271,7 @@ public class MessageChannelHandler extends SimpleChannelUpstreamHandler {
private void handlerResponseError(StreamInput buffer, final TransportResponseHandler handler) {
Throwable error;
try {
ThrowableObjectInputStream ois = new ThrowableObjectInputStream(buffer);
ThrowableObjectInputStream ois = new ThrowableObjectInputStream(buffer, transport.settings().getClassLoader());
error = (Throwable) ois.readObject();
} catch (Exception e) {
error = new TransportSerializationException("Failed to deserialize exception response from stream", e);