当前位置: 首页 > 知识库问答 >
问题:

需要一个 Java 系统专用类装入器

蓝侯林
2023-03-14

我想找到或创建一个仅加载系统类的 Java 类装入器,不包括应用程序定义的类路径上的任何类。我的目标是使用该类装入器来构建一个从特定 JAR 文件装入的类装入器,使用仅系统类装入器解析系统类,但不会用我的应用程序定义的任何类污染 JAR 文件中的类。

到目前为止,我还没有找到任何方法来创建一个不使用私有API或对Java实现进行假设的仅系统类加载器。请参阅下面的代码,该代码适用于我当前的环境,但会做出不希望的假设。

如果没有办法创建一个独立于实现的仅系统类装入器,那么为什么不这样做呢?我试图做的是一个坏主意吗?

private ClassLoader createJarClassLoader(File f)
{
    ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
    if (systemClassLoader instanceof URLClassLoader) {
        URLClassLoader cl = (URLClassLoader) systemClassLoader;
        URL[] urls = cl.getURLs();
        List<URL> wantedURLs = new ArrayList<>();
        for (URL u : urls) {
            if (isSystemURL(u)) {
                wantedURLs.add(u);
            }
        }
        try {
            wantedURLs.add(f.toURI().toURL());
        } catch (MalformedURLException ex) {
            return null;
        }
        return new URLClassLoader(wantedURLs.toArray(new URL[0]), null);
    }
    return null;
}

private boolean isSystemURL(URL u)
{
    return u.getPath().contains("/jre/");
}

共有1个答案

慕容玉堂
2023-03-14

您需要将父ClassLoader设置为bootstrap ClassLoader。在java.lang.String对象上调用getClassLoader()以获取bootstrap ClassLoader并在ClassLoader构造函数中使用它。

public class MyClassLoader extends URLClassLoader {

    protected MyClassLoader(URL[] urls, ClassLoader parent) {
        super(urls, parent);
    }

    static MyClassLoader getInstance(URL[] urls) {
        ClassLoader parent = "".getClass().getClassLoader();
        return (new MyClassLoader(urls, parent));
    }
}

引导类加载器的表示被记录为依赖于实现

一些实现可能使用null来表示引导类加载器。如果这个类是由引导类加载器加载的,那么这个方法[getClassLoader]将在这样的实现中返回null。

但同样的措辞也适用于ClassLoader构造函数中的父类加载器,这意味着该解决方案是可移植的。

 类似资料:
  • 问题内容: 我需要一种方法来(可能)跨数百GB数据进行键值查找。理想情况下,基于分布式哈希表的东西可以与Java很好地配合。它应该是容错的,并且是开源的。 存储应该是持久性的,但理想情况下应将数据缓存在内存中以加快处理速度。 它应该能够支持多台机器的并发读取和写入(不过,读取将是普通的100倍)。基本上,目的是对Web服务的用户元数据进行快速的初始查找。 谁能推荐什么? 问题答案: 您可能想查看H

  • 问题内容: 我知道BEA正在使用LiquidVM,它不需要底层操作系统,但是想知道开源社区中是否有人在从事类似的工作。 理想情况下,我想找到一个由操作系统启动加载程序直接加载VM的实现。 问题答案: 你需要什么? 也许Sanos可以在您可以使用的硬件和JVM之间给您一小段代码? http://www.jbox.dk/sanos/

  • 我有一些遗留代码(或者更确切地说,一些我们无法控制但我们必须使用的代码),可以编写大量语句来system.out/err. 与此同时,我们正在使用一个框架,该框架使用一个围绕log4j的自定义日志系统(同样,不幸的是,我们不能控制这个)。 因此,我试图将out and err流重定向到一个将使用日志系统的定制PrintStream。我在读关于和方法,但问题是,我需要编写自己的PrintStream

  • 想象一下有一个主类——模拟器——它使用另外两个类——生产者和评价者,分别实现接口IProducer和IEEvaluator。 IProducer实现产生结果,而IEEvaluator实现评估这些结果。模拟器通过查询IProducer实现,然后将结果传递给IEEvaluator实例,来控制执行流。 生产者和评估者的实际实现在运行时是已知的,在编译时我只知道他们的接口。检查下面的示例。 这段代码编译时

  • 问题内容: 在较高的层次上,我知道我们需要通过使用它们各自的包装类在Java集合中使用它们来“包装”原始数据类型,例如int和char。我想了解Java集合如何在低级询问:“为什么我们需要将原始数据类型包装为对象才能在集合中使用它们?”在此先感谢您的帮助。 问题答案: 在虚拟机级别,这是因为与引用类型(例如java.lang.Object及其派生类型)相比,原始类型在内存中的表示方式非常不同。例如

  • 我正在运行Ubuntu 20.04,正在安装Netbean 12。安装程序提示安装JavaSE(和JavaEE)和一堆其他东西。 既然我已经安装了JDK,我真的需要安装它(JavaSE和JavaEE)吗?