java - 自定义类加载器来限制对类的访问

标签 java

我的应用程序有这个自定义类加载器:

JarByteClassloader loader = new JarByteClassloader(jar);
Class c = loader.loadClass(classToLoad);
Thread.currentThread().setContextClassLoader(loader);
JarEntryObject jarEntry = (JarEntryObject) c.newInstance();

我想问是否可以限制自定义类加载器加载的实例对特定类的访问?

因此,例如,System.getProperty()System.getenv() 应该失败。通过什么方式可以做到这一点?

最佳答案

虽然对于这种情况,SecurityManager 可能是最合适的(尽管自 Java 17 起它已被弃用并标记为删除而无需替换),但实际上您可以通过类加载器限制对其他类的访问。

这可以通过重写类加载器的 loadClass 方法来完成。
有必要了解类加载器的委托(delegate)模型来限制它:

The ClassLoader class uses a delegation model to search for classes and resources. Each instance of ClassLoader has an associated parent class loader. When requested to find a class or resource, a ClassLoader instance will delegate the search for the class or resource to its parent class loader before attempting to find the class or resource itself. The virtual machine's built-in class loader, called the "bootstrap class loader", does not itself have a parent but may serve as the parent of a ClassLoader instance.

loadClass方法的作用如下:

Loads the class with the specified binary name. The default implementation of this method searches for classes in the following order:

  • Invoke findLoadedClass(String) to check if the class has already been loaded.

  • Invoke the loadClass method on the parent class loader. If the parent is null the class loader built-in to the virtual machine is used, instead.

  • Invoke the findClass(String) method to find the class.

https://docs.oracle.com/javase/8/docs/api/java/lang/ClassLoader.html

因此,如果我们重写findClass,则仅当父类加载器无法加载/查找该类时才会调用我们的代码。但我们想要拦截所有加载的类,因此我们需要重写 loadClass :

@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
    synchronized (getClassLoadingLock(name)) {
        if (allowDelegateLoadingOf(name)) {
            System.out.println("Delegate loading of " + name + " to parent class loader.");
            return super.loadClass(name);
        }

        System.out.println("Prohibit class from delegating: " + name);
        return findClass(name);
    }
}

在这种情况下,allowDelegateLoadingOf 只是一个简单的 boolean 方法,用于确定是否应委托(delegate)类并因此加载或不加载。这可以通过简单地根据白名单或黑名单包/类列表检查类名来完成。

关于java - 自定义类加载器来限制对类的访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59998928/

相关文章:

java - 更新 JList 模型导致 StackOverflowError

java - NullPointerException - 尝试调用虚拟方法 `notifyDataSetChanged()`

java - 以 'yyyy-MM-dd' 格式计算当前年份在 Java 中设置了不正确的值

java - ANTLR4:如何解析 WKT 多边形字符串?

java - 更新 Accordion 中的选项卡标题

java - 我如何在JAVA中交换两个arraylist?

java - Eclipse和Mysql连接错误

java - 谷歌地图绘制 Firebase 数据库中的多个标记

java - For 循环能否在当前迭代中获得 'see' 即将到来的值?

java - 使用 Nd4j 计算协方差矩阵