2013-12-02 5 views
6

Предисловия:подклассы ВС * класс в одном пакете дает IllegalAccessError

  1. Что я собираюсь показать вам, это не так, и я хорошо осведомлен о том, как плохо я за нарушение инкапсуляции, делая такую ​​глупость.
  2. Я не пытаюсь решить более общую проблему ввода-вывода. Это просто эксперимент.

Я пытаюсь подклассу 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) 

Это, вероятно, не вы можете» t определить класс в пакете JDK XYZ ((java | sun). *) тип проблемы, потому что oth я бы получил

java.lang.SecurityException: Prohibited package name: XYZ 

Main класс отлично работает в этом пакете.

Я также попытался отключить проверки безопасности, установив Policy, разрешая все, и это не помогло ни одному. Я также пробовал System.setSecurityManager(null); (я не уверен, что это фактически отключает его), и это никому не помогло.

В чем проблема? Как я могу исправить это, пожалуйста?

Я пробовал его с JDK 1.7.0_45, как Oracle, так и OpenJDK.

ответ

6

SourceChannelImpl является «пакетом частного» класса. В JVM пакет всегда загружается одним загрузчиком классов. Если у вас есть два пакета с тем же именем, загруженные разными загрузчиками классов, они не являются одним и тем же пакетом.

Вы можете исправить это, загрузив какой-либо или весь ваш код в загрузчик класса начальной загрузки с помощью -Xbootclasspath/a:mybootspath.