将类路径添加到 SystemClassLoader
如何向 SystemClassLoader 添加类路径。
引言
本文介绍了一种不推荐使用的技巧,用于动态地向 SystemClassLoader
添加类路径。在使用此技巧之前,请重新考虑您的设计;通常,您应该能够使用 URLClassLoader
加载您需要的一切。
关于 SystemClassLoader
SystemClassLoader
通常是 URLClassLoader
,并且在 URLClassLoader
中,有一个名为 addURL()
的方法,因此我们可以利用它在运行时动态地向 SystemClassLoader
添加路径/jar 文件。但是,由于 "addURL()
" 是一个受保护的方法,我们必须使用反射来调用它。
示例代码如下
public static void addURLs(URL[] urls) {
ClassLoader cl = ClassLoader.getSystemClassLoader();
if ( cl instanceof URLClassLoader ) {
URLClassLoader ul = (URLClassLoader)cl;
// addURL is a protected method, but we can use reflection to call it
Class<?>[] paraTypes = new Class[1];
paraTypes[0] = URL.class;
Method method = URLClassLoader.class.getDeclaredMethod("addURL", paraTypes);
// change access to true, otherwise, it will throw exception
method.setAccessible(true);
Object[] args = new Object[1];
for(int i=0; i<urls.length; i++) {
args[0] = urls[i];
method.invoke(ul, args);
}
} else {
// SystemClassLoader is not URLClassLoader....
}
}
测试
我编写了一个测试用例,它将自动加载所有 "lib/*.jar" 并实例化 args[0]
中指定的对象。测试输出如下。请注意:我只将 "bin" 作为我的类路径,并且我在 "lib" 目录下有一个 commons-collections.jar,但程序仍然能够动态加载所需的类。
历史
- 2010.01.20:初稿。