1 回答
TA贡献1810条经验 获得超4个赞
URLClassLoader(java.net.URL[])指出:
使用默认委托父 ClassLoader为指定的 URL 构造一个新的 URLClassLoader 。
因此,默认委托父类加载器也将被使用,因此org.apache.xmlbeans.XmlOptions
如果找到,将从那里加载,而不是从附加的给定URL
.
因此,我们需要不使用默认的代理父类加载器。URLClassLoader(java.net.URL[], null)就是这样做的。
例子
import java.net.URL;
import java.net.URLClassLoader;
import java.lang.reflect.Constructor;
public class UseURLClassLoader {
public static void main(String[] args) throws Exception {
URL[] classLoaderUrls;
URLClassLoader urlClassLoader;
Class<?> beanClass;
classLoaderUrls = new URL[]{new URL("file:/home/axel/Dokumente/JAVA/poi/poi-3.10.1/ooxml-lib/xmlbeans-2.6.0.jar")};
urlClassLoader = new URLClassLoader(classLoaderUrls); //default delegation parent ClassLoader is used
beanClass = urlClassLoader.loadClass("org.apache.xmlbeans.XmlOptions");
System.out.println(beanClass.getResource("/org/apache/xmlbeans/XmlOptions.class")); //class is loaded using default parent class loader
URL context = new URL("file:/home/axel/Dokumente/JAVA/poi/poi-3.10.1/");
classLoaderUrls = new URL[] {
new URL(context, "poi-3.10.1-20140818.jar"),
new URL(context, "poi-ooxml-3.10.1-20140818.jar"),
new URL(context, "poi-ooxml-schemas-3.10.1-20140818.jar"),
// maybe others also necessary
new URL(context, "lib/commons-codec-1.5.jar"),
// maybe others also necessary
new URL(context, "ooxml-lib/xmlbeans-2.6.0.jar")
// maybe others also necessary
};
for (int i = 0; i < classLoaderUrls.length; i++) {
System.out.println(classLoaderUrls[i]);
}
urlClassLoader = new URLClassLoader(classLoaderUrls, null); //set default parent class loader null
beanClass = urlClassLoader.loadClass("org.apache.xmlbeans.XmlOptions");
System.out.println(beanClass.getResource("/org/apache/xmlbeans/XmlOptions.class")); //class is loaded using this class loader
}
}
对于我来说,调用如下:
axel@arichter:~/Dokumente/JAVA/poi/poi-4.0.0$ java -cp .:./*:./lib/*:./ooxml-lib/* UseURLClassLoader
它产生:
jar:file:/home/axel/Dokumente/JAVA/poi/poi-4.0.0/ooxml-lib/xmlbeans-3.0.1.jar!/org/apache/xmlbeans/XmlOptions.class
file:/home/axel/Dokumente/JAVA/poi/poi-3.10.1/poi-3.10.1-20140818.jar
file:/home/axel/Dokumente/JAVA/poi/poi-3.10.1/poi-ooxml-3.10.1-20140818.jar
file:/home/axel/Dokumente/JAVA/poi/poi-3.10.1/poi-ooxml-schemas-3.10.1-20140818.jar
file:/home/axel/Dokumente/JAVA/poi/poi-3.10.1/lib/commons-codec-1.5.jar
file:/home/axel/Dokumente/JAVA/poi/poi-3.10.1/ooxml-lib/xmlbeans-2.6.0.jar
jar:file:/home/axel/Dokumente/JAVA/poi/poi-3.10.1/ooxml-lib/xmlbeans-2.6.0.jar!/org/apache/xmlbeans/XmlOptions.class
因此,首先使用默认父类加载器加载类。对我来说,它org.apache.xmlbeans.XmlOptions从较新的xmlbeans-3.0.1.jar. 对您来说,它加载的距离较旧的xmlbeans-1.*.jar. 那是因为这些 jar 位于默认父类加载器的类路径中。
然后第二个代码部分将默认父类加载器设置为 null,因此仅使用此类加载器加载类。
但是搞乱类加载器是一团糟。正如我的代码所暗示的,将默认父类加载器设置为 null,我们需要为当前类加载器提供所有需要的类源。这通常变得非常昂贵。因此,在类路径中没有旧的jars 总是比乱用类加载器更好的解决方案。
添加回答
举报