jarファイルからクラスをロードする。

カレントスレッドのクラスローダにロードする方法わからず。これでいいのかなぁ…


package jarjar;

import java.io.*;
import java.util.*;
import java.util.jar.*;

public class JarClassLoader extends ClassLoader {

public static void main(String args) {
try {
JarClassLoader jloader = new JarClassLoader("ooweb-0.5.jar");
jloader.load();
println(jloader.forName("net.sf.ooweb.util.Base64"));
} catch (Throwable e) {
e.printStackTrace();
}

}

private static void println(Object x) {
System.out.println(x);
}

/////////////////////////////////////////////////////////////////
private JarFile jar = null;

private Map classes = new HashMap();

public JarClassLoader(String filenam) throws IOException {
jar = new JarFile(filenam);
}

public void load() throws IOException, ClassNotFoundException {
Map ctx = new HashMap();

for (Enumeration enum = jar.entries(); enum.hasMoreElements();) {
JarEntry entry = (JarEntry) enum.nextElement();
String name = entry.getName();

if (entry.isDirectory() || !name.endsWith(".class"))
continue;

InputStream in = jar.getInputStream(entry);
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte buf = new byte[256];

while (in.available() > 0) {
int len = in.read(buf);
out.write(buf, 0, len);
}

out.flush();
in.close();

String cname = name.replace('/', '.').substring(0, name.length() - 6);
ctx.put(cname, out);
}

Iterator names = ctx.keySet().iterator();

while (names.hasNext()) {
String name = (String) names.next();
loadClasses(name, ctx, classes);
}
}

private void loadClasses(String name, Map ctx, Map classes) throws ClassNotFoundException {
if (classes.containsKey(name))
return;

ByteArrayOutputStream bstream = (ByteArrayOutputStream) ctx.get(name);

if (bstream == null)
return;

Class clazz = null;
byte[] bs = bstream.toByteArray();

try {
clazz = defineClass(name, bs, 0, bs.length);
} catch (NoClassDefFoundError e) {
String parent = e.getMessage().replace('/', '.');
loadClasses(parent, ctx, classes);
clazz = defineClass(name, bs, 0, bs.length);
}

classes.put(name, clazz);
}

public Class forName(String name) {
return (Class) classes.get(name);
}

}