首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在Java中创建父-最后/子-第一ClassLoader,或者如何覆盖已经加载在父CL中的旧Xerces版本?

如何在Java中创建父-最后/子-第一ClassLoader,或者如何覆盖已经加载在父CL中的旧Xerces版本?
EN

Stack Overflow用户
提问于 2011-03-26 21:40:52
回答 5查看 39.3K关注 0票数 38

我想要创建一个父类-最后/子-第一类加载器,例如一个类加载器,它将首先在子类loder中查找类,然后委托它的父ClassLoader搜索类。

Clarification:

现在我知道了,为了获得完整的ClassLoading分离,我需要使用类似于URLClassLoader传递null作为它的父级的东西,这要归功于前面的问题中的这个答案

然而,目前的问题来帮助我解决这个问题:

  1. 我的代码+依赖的jars正在加载到现有的系统中,使用ClassLoader将系统的ClassLoader设置为父系统(URLClassLoader)
  2. 该系统使用了一些与我需要的版本不兼容的库(例如,旧版本的Xerces,这不允许我运行我的代码)
  3. 如果独立运行,我的代码运行非常好,但是如果从那个ClassLoader运行它就会失败。
  4. 但是,我确实需要访问父ClassLoader中的许多其他类。
  5. 因此,我希望允许我重写父类加载器" jars“:如果在子类加载器中找到了我调用的类(例如,我用自己的jars提供了Xerces的更新版本,而不是加载代码和jars的classloader用户)。

以下是加载我的代码+ Jars的系统代码(我无法更改此代码)

代码语言:javascript
运行
复制
File addOnFolder = new File("/addOns"); 
URL url = addOnFolder.toURL();         
URL[] urls = new URL[]{url};
ClassLoader parent = getClass().getClassLoader();
cl = URLClassLoader.newInstance(urls, parent);

下面是“我的”代码(完全摘自"Hello“代码演示):

代码语言:javascript
运行
复制
package flyingsaucerpdf;

import java.io.*;
import com.lowagie.text.DocumentException;
import org.xhtmlrenderer.pdf.ITextRenderer;

public class FirstDoc {

    public static void main(String[] args) 
            throws IOException, DocumentException {

        String f = new File("sample.xhtml").getAbsolutePath();
        System.out.println(f);
        //if(true) return;
        String inputFile = "sample.html";
        String url = new File(inputFile).toURI().toURL().toString();
        String outputFile = "firstdoc.pdf";
        OutputStream os = new FileOutputStream(outputFile);

        ITextRenderer renderer = new ITextRenderer();
        renderer.setDocument(url);
        renderer.layout();
        renderer.createPDF(os);

        os.close();
    }
}

这可以独立工作(运行main),但在通过父CL加载此错误时失败:

org.w3c.dom.DOMException: NAMESPACE_ERR:尝试以一种与名称空间有关的不正确的方式创建或更改对象。

可能是因为父系统使用旧版本的Xerces,而且即使我在/addOns文件夹中提供了正确的Xerces jar,因为父系统已经加载和使用了它的类,因此由于委托的方向,它不允许我自己的代码使用自己的jar。我希望这使我的问题更清楚,我相信这是以前的问题。(也许我没有问对的问题)

EN

Stack Overflow用户

发布于 2011-03-26 22:38:36

通过阅读Jetty或Tomcat的源代码,它们都提供了父类加载器来实现webapp语义。

https://github.com/apache/tomcat/blob/7.0.93/java/org/apache/catalina/loader/WebappClassLoaderBase.java

也就是说,通过重写findClass类中的ClassLoader方法。但既然你能偷,为什么要重新发明轮子呢?

通过阅读您的各种更新,我看到您在XML系统中遇到了一些典型的问题。

一般的问题是:如果您创建了一个完全隔离的类加载器,那么很难使用它返回的对象。如果允许共享,则当父版本包含错误的内容时,可能会出现问题。

正是为了应对所有这些疯狂,OSGi发明了,但这是一个大药丸吞咽。

即使在webapp中,类加载器也可以豁免一些包不受“本地优先”处理的影响,前提是容器和webapp必须就它们之间的API达成一致。

票数 14
EN
查看全部 5 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5445511

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档