Foreword:
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.
Here is my sub-class:
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);
}
}
Here is my simple test:
package sun.nio.ch;
import java.io.FileDescriptor;
public class Main {
public static void main(String[] args) {
new MySourceChannel(null, FileDescriptor.in);
}
}
And here's the failure:
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)
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
class works fine in this package.
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?
I've tried it with JDK 1.7.0_45, both Oracle and OpenJDK.
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.
You can fix this by loading some or all of your code in the bootstrap class loader with -Xbootclasspath/a:mybootspath
.