Subclassing sun. * A class in the same package gives IllegalAccessError

Foreword:

  • What I will show you is WRONG, and I know very well how poorly I am in encapsulation, doing such stupidity.
  • I am not trying to solve a more general input / output problem. This is just an experiment.

I am trying to subclass sun.nio.ch.SourceChannelImpl , which is a private package class with a private package constructor present in the JDK (in rt.jar), so I have to create it in the sun.nio.ch package.

Here is my subclass:

 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 is 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) 

You probably cannot define the class in the JDK package XYZ ((java | sun). *) The type of problem, because otherwise I would get

 java.lang.SecurityException: Prohibited package name: XYZ 

Main class works fine in this package.

I also tried disabling security checks by setting Policy to everything, and that didn't help any. I also tried System.setSecurityManager(null); (I'm not sure if this actually disables it), and that didn't help either.

What is the problem? How can I fix this please?

I tried this with JDK 1.7.0_45, both Oracle and OpenJDK.

+6
source share
1 answer

SourceChannelImpl is a closed package class. In the JVM, a package is always loaded with 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 .

+6
source

Source: https://habr.com/ru/post/959177/


All Articles