甲骨文JavaDocs解释说IllegalAccessError是
“如果应用程序试图访问或修改字段,或调用它无法访问的方法,则引发。”
我尝试动态加载一个类,然后得到这个异常。
如果我正确地理解了当您使用类加载器动态加载带有私有包的类时,就会发生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中也说明了
不幸的是,我们不能使用反射*加载类,因为这个类是包私有的。而且这个类必须是包私有的,这样API就不会暴露在其他的代码中,这些代码可以用来规避安全性。因此,*我们接受在某些JDK1.1JVM上直接引用可能失败的风险,即使在这种情况下我们永远不会执行*这段代码。叹息..。
无论如何,我如何动态加载它?我得让它开始工作。而且,如果我在使用类加载器时得到了一个错误,我就无法从它中恢复,那么我如何预先知道我不能加载这个类呢?
提前感谢任何人帮助我
发布于 2017-06-27 17:57:32
语句“我们不能使用反射加载类,因为类是包私有的”没有任何意义,可以很容易地显示:
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");
}
}这是完美的,打印method overridden by subclass复制了该SecuritySupport类的实际用例。
但是,由于该类显然是为了允许Java 1.1和JavaReversion1.2之间的转换,所以在20年前,当这种转换发生时,可能存在这样的限制。
然而,您的用例完全不同。您说您正在尝试加载一个“正在使用org.xml.sax.helpers.SecuritySupport”的类,这并不意味着它通过反射使用上述类,但正如上面所示,这并不重要。无论在哪种情况下,只有当类在同一个包中时,它才能工作,不管您是否“动态地”加载类。
只有两种可能的情况。
org.xml.sax.helpers包定义了一个SecuritySupport类,那么该类可以访问同一个包中的类。ClassLoader加载一个类,那么即使您给它一个org.xml.sax.helpers.SomeClass表单的限定名,它也不会属于这个包。如果JRE的org.xml.sax.helpers包恰好定义了一个SecuritySupport类,那么所有非JRE类都将位于不同的包中。当它试图访问那个类(它不是官方API的一部分)时,它就不能工作了。
请注意,所有标准类加载器都遵循委托模型,首先尝试通过父类加载器解析名称,这也是为什么如果存在org.xml.sax.helpers.SecuritySupport类,它们都更喜欢JRE的JRE类的原因。使用非标准的类加载器,您可以拥有不同的、不相关的类,这些类具有该限定名,它们位于不同的运行时包中。在第二个场景中,出现了一个问题,您的类为什么要使用该类。在2017年,很少需要区分Java1.1和Java1.2,而且该类提供的功能也只适用于JRE特权代码源代码中的类(或具有不同权限的不同代码源)。
https://stackoverflow.com/questions/44725466
复制相似问题