EmbedderClassLoader.java
package org.jbehave.core.embedder;
import java.io.File;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
/**
* EmbedderClassLoader is a URLClassLoader with a specified list of classpath
* elements. It also provides a utility method
* {@link #newInstance(Class, String)} to instantiate generic types.
*/
public class EmbedderClassLoader extends URLClassLoader {
public EmbedderClassLoader(ClassLoader parent) {
this(Arrays.<String>asList(), parent);
}
public EmbedderClassLoader(List<String> classpathElements) {
this(classpathElements, Embedder.class.getClassLoader());
}
public EmbedderClassLoader(List<String> classpathElements, ClassLoader parent) {
super(classpathURLs(classpathElements), parent);
}
@SuppressWarnings("unchecked")
public <T> T newInstance(Class<T> type, String className) {
try {
Thread.currentThread().setContextClassLoader(this);
return (T) loadClass(className, true).newInstance();
} catch (Exception e) {
throw new InstantiationFailed(className, type, this, e);
}
}
public boolean isAbstract(String className) {
try {
return Modifier.isAbstract(loadClass(className, true).getModifiers());
} catch (ClassNotFoundException e) {
return false;
}
}
List<String> asShortPaths(URL... urls) {
List<String> names = new ArrayList<>();
for (URL url : urls) {
String path = url.getPath();
if (isJar(path)) {
names.add(shortPath(path));
} else {
names.add(path);
}
}
return names;
}
private static String shortPath(String path) {
return path.substring(path.lastIndexOf("/") + 1);
}
private static boolean isJar(String path) {
return path.endsWith(".jar");
}
private static URL[] classpathURLs(List<String> elements) {
List<URL> urls = new ArrayList<>();
if (elements != null) {
for (String element : elements) {
urls.add(toURL(element));
}
}
return urls.toArray(new URL[urls.size()]);
}
private static URL toURL(String element) {
try {
return new File(element).toURI().toURL();
} catch (Exception e) {
throw new InvalidClasspathElement(element, e);
}
}
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).append("urls", asShortPaths(getURLs()))
.append("parent", getParent()).toString();
}
@SuppressWarnings("serial")
public static class InstantiationFailed extends RuntimeException {
public InstantiationFailed(String className, Class<?> type, ClassLoader classLoader, Throwable cause) {
super("Instantiation failed for" + className + " of type " + type + " using class loader " + classLoader,
cause);
}
}
@SuppressWarnings("serial")
public static class InvalidClasspathElement extends RuntimeException {
public InvalidClasspathElement(String element, Throwable cause) {
super("Invalid classpath element " + element, cause);
}
}
}