前言:
我要告诉你的是错误,我很清楚我做这种愚蠢的事情打破封装有多糟糕.
我不是要解决任何更普遍的I/O问题.这只是一个实验.
我正在尝试sun.nio.ch.SourceChannelImpl
使用JDK中存在的包私有构造函数的包私有类子类(在rt.jar中),所以我必须在sun.nio.ch
包中创建它.
这是我的子类:
package sun.nio.ch; import java.io.FileDescriptor; import java.nio.channels.spi.SelectorProvider; class MySourceChannel extends SourceChannelImpl { public MySourceChannel(SelectorProvider sp, FileDescriptor fd) { super(sp, fd); } }
这是我的简单测试:
package sun.nio.ch; import java.io.FileDescriptor; public class Main { public static void main(String[] args) { new MySourceChannel(null, FileDescriptor.in); } }
而这是失败:
Exception in thread "main" java.lang.IllegalAccessError: class sun.nio.ch.MySourceChannel cannot access its superclass sun.nio.ch.SourceChannelImpl at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:800) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) at java.net.URLClassLoader.defineClass(URLClassLoader.java:449) at java.net.URLClassLoader.access$100(URLClassLoader.java:71) at java.net.URLClassLoader$1.run(URLClassLoader.java:361) at java.net.URLClassLoader$1.run(URLClassLoader.java:355) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:354) at java.lang.ClassLoader.loadClass(ClassLoader.java:425) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) at java.lang.ClassLoader.loadClass(ClassLoader.java:358) at sun.nio.ch.Main.main(Main.java:5)
可能不是你不能在JDK包中定义类XYZ((java | sun).*)类型的问题因为否则我会得到
java.lang.SecurityException: Prohibited package name: XYZ
Main
class在这个包中工作正常.
我也尝试通过设置Policy
允许一切来禁用安全检查,这两者都没有帮助.我也尝试过System.setSecurityManager(null);
(我不确定这实际上是否会禁用它)并且它也没有帮助.
有什么问题?我该怎么办呢?
我已经尝试过使用JDK 1.7.0_45,Oracle和OpenJDK.
SourceChannelImpl
是一个"包私人"类.在JVM中,包总是由单个类加载器加载.如果有两个具有相同名称的包由不同的类加载器加载,则它们不是同一个包.
您可以通过在引导程序类加载器中加载部分或全部代码来解决此问题-Xbootclasspath/a:mybootspath
.