java动态类加载避免java.lang.IllegalAccessError

标签 java classloader dynamic-loading

Oracle JavaDocs 解释说 IllegalAccessError 是

"Thrown if an application attempts to access or modify a field, or to call a method that it does not have access to."

我尝试动态加载类,但出现此异常。

如果我理解正确的话,当您使用类加载器动态加载带有私有(private)包的类时,会发生 IllegalAccessError

我尝试加载的类正在使用

org.xml.sax.helpers.SecuritySupport

在以下 url 的描述中也有说明 http://grepcode.com/file/repository.springsource.com/org.apache.xmlcommons/com.springsource.org.apache.xmlcommons/1.3.4/org/xml/sax/helpers/SecuritySupport.java 那个

Unfortunately, we can't load the class using reflection * because the class is package private. And the class has * to be package private so the APIs aren't exposed to other * code that could use them to circumvent security. Thus, * we accept the risk that the direct reference might fail * on some JDK 1.1 JVMs, even though we would never execute * this code in such a case. Sigh...

我怎样才能动态加载它?我必须让它发挥作用。 另外,如果我在使用类加载器时遇到错误,我无法从中恢复,那么我如何提前知道我无法加载此类?

提前感谢任何提供帮助的人

最佳答案

语句“我们无法使用反射加载该类,因为该类是包私有(private)的”没有任何意义,这一点很容易看出:

package somepackage;

class BaseClass {
    public static void main(String[] args) throws ReflectiveOperationException {
        BaseClass obj=(BaseClass)
            Class.forName("somepackage.SubClass").newInstance();
        obj.aMethod();
    }

    void aMethod() {
        System.out.println("base class");
    }
}
class SubClass extends BaseClass {
    @Override
    void aMethod() {
        System.out.println("method overridden by subclass");
    }
}

这工作完美,打印被子类覆盖的方法复制了该SecuritySupport类的实际用例。

但是,由于该类显然是用于允许 Java 1.1 和 Java 1.2 之间转换的目的,因此二十年前发生这种转换时可能存在此类限制。

但是,您的用例完全不同。您说您正在尝试加载一个“正在使用org.xml.sax.helpers.SecuritySupport”的类,这并不意味着它正在通过反射使用所述类,但如上所示,无论如何,这并不重要。无论哪种情况,只有当该类位于同一个包中时,无论您是否“动态”加载该类,它才会起作用。

只有两种可能的情况。

  1. 如果类确实位于同一个包中,这在运行时意味着它也已由同一个类加载器加载,这将要求它也是 JRE 的一部分,如果 JRE 的 org .xml.sax.helpers包定义了一个SecuritySupport类,那么该类可以访问同一包内的类。

  2. 如果您尝试通过不同的 ClassLoader 从不同的代码源加载类,则该类将不属于该包,即使您为其指定了限定名称org.xml.sax.helpers.SomeClass 形式。如果 JRE 的 org.xml.sax.helpers 包恰好定义了 SecuritySupport 类,则所有非 JRE 类都将位于不同的包中。当它尝试访问该类(该类不是官方 API 的一部分)时,它不起作用。

    请注意,所有标准类加载器都遵循委托(delegate)模型,尝试首先通过其父类加载器解析名称,这就是为什么它们都更喜欢 JRE 的 org.xml.sax.helpers.SecuritySupport 类,如果有的话。使用非标准类加载器,您可以在不同的运行时包中拥有具有该限定名称的不同的、不相关的类。

在第二种情况下,问题出现了,为什么你的类使用该类。 2017 年,很少需要区分 Java 1.1 和 Java 1.2,并且该类提供的功能也仅与 JRE 特权代码源(或具有不同代码源的不同代码源)内的类相关。一般来说不同的特权)。

关于java动态类加载避免java.lang.IllegalAccessError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44725466/

相关文章:

java - 尝试从 InputStream 重复读取时发生空指针异常

java - 在位置获取 SWT 小部件

java - 我应该为 Mac/Windows Java 应用程序使用什么打包工具?

java - 如何探索从哪些 JAR 加载哪些类?

python - 由于缺少符号,Python C 扩展的动态加载失败

Java:运行/打开/编辑任何文件

java - PMD规则 "Use Proper Class Loader"解释?

tomcat - 使用类加载器从 tomcat 库实例化 tomcat WEB-INF\class\myclass

flash - 使用 Adob​​e AIR 构建插件架构

c - "dynamically loading a library file"和 "specifying .so path in Makefile"之间的区别?