问题描述
前言:
- 我要告诉你的是错误的我很清楚我打破封装有多糟糕做这样愚蠢的事情。
- 我不是想解决任何更普遍的I / O问题。这只是一个实验。
我正在尝试子类 sun.nio.ch.SourceChannelImpl
这是包私有类的包私有构造函数,在JDK中存在(在rt.jar中)所以我必须在 sun.nio.ch
包中创建它。
I'm trying to sub-class sun.nio.ch.SourceChannelImpl
which is package private class with package private constructor present in JDK (in rt.jar) so I have to create it in sun.nio.ch
package.
这是我的子类:
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)。*)问题类型,否则我会得到
It's probably not you can't define class in JDK package XYZ ((java|sun).*) type of problem because otherwise I'd get
java.lang.SecurityException: Prohibited package name: XYZ
Main
类在这个包中运行正常。
Main
class works fine in this package.
我还尝试通过设置 Policy
来禁用安全检查一切都没有帮助。我也试过 System.setSecurityManager(null);
(我不确定这是否真的禁用了它)并且它也没有帮助。
I've also tried to disable security checks by setting Policy
allowing everything and that didn't help neither. I've also tried System.setSecurityManager(null);
(I'm not sure if this actually disables it) and it didn't help neither.
有什么问题?我该如何解决?
What's the problem? How can I fix it please?
我已经尝试使用JDK 1.7.0_45,Oracle和OpenJDK。
I've tried it with JDK 1.7.0_45, both Oracle and OpenJDK.
推荐答案
SourceChannelImpl
是一个包私有类。在JVM中,包总是由单个类加载器加载。如果你有两个由不同类加载器加载的同名包,则它们不是同一个包。
SourceChannelImpl
is a "package private" class. In the JVM a package is always loaded by a single class loader. If you have two packages with the same name loaded by different class loaders, they are not the same package.
你可以通过加载部分或全部代码来解决这个问题。引导类加载器与 -Xbootclasspath / a:mybootspath
。
You can fix this by loading some or all of your code in the bootstrap class loader with -Xbootclasspath/a:mybootspath
.
这篇关于在同一个包中对sun。*类进行子类化会产生IllegalAccessError的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!