簡體   English   中英

在同一個包中對sun。*類進行子類化會產生IllegalAccessError

[英]Subclassing sun.* class in same package gives IllegalAccessError

前言:

  1. 我要向你展示的是錯誤的,我很清楚通過做這樣愚蠢的事情來打破封裝有多糟糕。
  2. 我不是要解決任何更普遍的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類在此包中正常工作。

我也嘗試通過設置Policy允許一切來禁用安全檢查,這也沒有幫助。 我也試過System.setSecurityManager(null); (我不確定這是否真的禁用它)並且它也沒有幫助。

有什么問題? 我該怎么辦呢?

我已經嘗試過使用JDK 1.7.0_45,Oracle和OpenJDK。

SourceChannelImpl是一個“包私有”類。 在JVM中,包總是由單個類加載器加載。 如果有兩個具有相同名稱的包由不同的類加載器加載,則它們不是同一個包。

您可以通過使用-Xbootclasspath/a:mybootspath在引導程序類加載器中加載部分或全部代碼來解決此-Xbootclasspath/a:mybootspath

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM