/*
* Copyright 2011-2013 the original author or authors.
*
* Licensed 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.springframework.data.hadoop.mapreduce;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
/**
* Extension for {@link URLClassLoader} that uses a parent-last (or child first) delegation.
*
* @author Costin Leau
*/
class ParentLastURLClassLoader extends URLClassLoader {
private final ClassLoader system;
public ParentLastURLClassLoader(URL[] classpath, ClassLoader parent) {
super(classpath, parent);
ClassLoader sys = getSystemClassLoader();
while (sys.getParent() != null) {
sys = sys.getParent();
}
system = sys;
}
@Override
protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
// First, check if the class has already been loaded
Class<?> c = findLoadedClass(name);
if (c == null) {
// always check system class loader (for jvm classes & co)
if (system != null) {
try {
c = system.loadClass(name);
} catch (ClassNotFoundException ignored) {
}
}
if (c == null) {
try {
// load local
c = findClass(name);
} catch (ClassNotFoundException e) {
// fall back to parent
c = super.loadClass(name, resolve);
}
}
}
if (resolve) {
resolveClass(c);
}
return c;
}
@Override
public URL getResource(String name) {
// same delegation as with load class
URL url = null;
if (system != null) {
url = system.getResource(name);
}
if (url == null) {
url = findResource(name);
if (url == null) {
url = super.getResource(name);
}
}
return url;
}
@Override
public Enumeration<URL> getResources(String name) throws IOException {
List<URL> urls = new ArrayList<URL>();
if (system != null) {
urls.addAll(Collections.list(system.getResources(name)));
}
urls.addAll(Collections.list(findResources(name)));
ClassLoader parent = getParent();
if (parent != null) {
urls.addAll(Collections.list(parent.getResources(name)));
}
return Collections.enumeration(urls);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("ParentLastURLCL\r\nURLs: ");
sb.append(Arrays.asList(getURLs()));
sb.append("\nParent CL: ");
sb.append(getParent());
sb.append("\nSystem CL: ");
sb.append(system);
sb.append("\n");
return (sb.toString());
}
}