package serializers;
import java.io.*;
import java.util.*;
import java.util.zip.*;
/**
* Class loader to use for loading non-shared implementation classes. This is necessary so
* that implementation classes can be loaded in, and as importantly, swapped out,
* before and after test run.
*
* @author tatu
*/
public class SimpleClassLoader
extends ClassLoader
{
private final HashMap<String,byte[]> loadedByteCode = new HashMap<String,byte[]>();
public SimpleClassLoader(ClassLoader parent, File dir) throws IOException
{
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
byte[] buffer = new byte[8000];
for (File file : dir.listFiles()) {
if (!file.getName().endsWith(".jar")) continue;
ZipInputStream zis = new ZipInputStream(new FileInputStream(file));
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
String name = entry.getName();
if (name.endsWith(".class")) {
// strip out ".class"; replace '/' with '.'
String className = name.substring(0, name.length()-6);
className = className.replace('/', '.');
byte[] data = readAll(zis, buffer, bytes);
if (loadedByteCode.put(name, data) != null) {
throw new IllegalArgumentException("Duplicate class '"+className+"' (from jar '"+file.getPath()+"')");
}
}
}
}
}
@Override
public Class<?> findClass(String name)
{
byte[] bytecode = loadedByteCode.get(name);
if (bytecode == null) return null;
return defineClass(name, bytecode, 0, bytecode.length);
}
private final byte[] readAll(InputStream in, byte[] buffer, ByteArrayOutputStream bytes) throws IOException
{
bytes.reset();
int count;
while ((count = in.read(buffer)) > 0) {
bytes.write(buffer, 0, count);
}
return bytes.toByteArray();
}
}