最近本人在写一个service container,需要加载指定的jar。需要自定义一个classloader,可以加载到指定的jar包中的class。
以下是具体实现,其实最核心的就是重写findClass方法。
代码如下:
public class AppClassLoader extends ClassLoader {
private static Map<String, Class> classes = new HashMap<String, Class>();
private static AppClassLoader loader;
private String jarName;
/**
* @param jarName
* @throws Exception
*/
private AppClassLoader(String jarName) throws Exception {
this.jarName = jarName;
init();
}
/**
* 生成或取得AppClassLoader实例
* @return AppClassLoader
*/
public static synchronized AppClassLoader getInstance(String jarName) {
if (loader == null)
try {
loader = new AppClassLoader(jarName);
} catch (Exception e) {
System.err.println(e.getMessage());
return null;
}
return loader;
}
private void init() throws Exception {
JarInputStream jar = new JarInputStream(new FileInputStream(new File(jarName)));
JarEntry entry;
while ((entry = jar.getNextJarEntry()) != null) {
if (entry.getName().toLowerCase().endsWith(".class")) {
String classname = entry.getName().substring(0, entry.getName().length() - ".class".length())
.replace('/', '.');
byte[] data = getResourceData(jar);
Class clazz = defineClass(classname, data, 0, data.length);
classes.put(classname, clazz);
}
}
}
@Override
public Class findClass(String name) {
if (classes.get(name) != null) {
return classes.get(name);
}
return null;
}
final static private byte[] getResourceData(JarInputStream jar) throws IOException {
ByteArrayOutputStream data = new ByteArrayOutputStream();
byte[] buffer = new byte[8192];
int size;
while (jar.available() > 0) {
size = jar.read(buffer);
if (size > 0) {
data.write(buffer, 0, size);
}
}
byte[] val = data.toByteArray();
data.close();
return val;
}
}
本文分享自 ImportSource 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!