閱讀678 返回首頁    go 阿裏雲 go 技術社區[雲棲]


[翻譯]JDK 8 兼容性指南

翻譯官方文檔,刪除部分可忽略。

譯者:坤穀,井桐,激酶

兼容性是一個複雜的問題。 本文介紹了Java平台潛在的三種不兼容問題:

  • 源碼: 源碼兼容性問題關注Java源代碼轉換成class文件是否兼容,包括代碼是否仍然可編譯。
  • 二進製: 在Java語言規範中,二進製兼容性定義為:“類的改變是二進製兼容的(或者不破壞二進製兼容性),是指如果改變前的類的二進製在鏈接時沒有錯誤,那麼改變後的類在鏈接時仍然沒有錯誤。”
  • 行為 : 行為兼容性包括在運行時執行的代碼的語義。 欲了解更多信息,請參閱OpenJDK的開發人員指南 中,兼容性的種類一節。 下麵的兼容性文檔跟蹤相鄰的Java版本之間的不兼容。 例如,這個兼容性文檔隻報告的Java SE 8和Java SE 7的不兼容,而不是以前的版本。 要檢查的Java SE 8與早期的Java版本的不兼容性,必須按順序跟蹤一下不兼容性溫的。 Java SE 7和JDK 7的兼容性 JDK 6兼容性 J2SE 5.0不兼容問題(自1.4.2)

二進製兼容性

除了下麵列出的不兼容問題,Java SE 8與Java SE 7是二進製兼容的。 除了提到的不兼容,Java SE 7編譯的類文件將在Java SE8正常運行。而Java SE 8編譯的類文件將無法在早期版本的Java SE運行。

源碼兼容性

Java SE 8包括新的語言功能和平台的API。這些都在源文件中使用,這些源文件不能在早期版本的Java平台中編譯。
一般情況下,源碼兼容性策略是避免引入的源代碼不兼容問題。 然而,實現Java SE 8的功能所需的更改可能導致代碼無法在Java SE的7編譯。見Java SE 8和Java SE 7之間的不兼容性JDK 8和JDK 7之間的不兼容性
Deprecated API僅用於與早期版本的兼容性支持。除非打開-nowarn命令行選項,隻要使用了Deprecated API,javac編譯器就會生成警告信息。 建議應用進行修改,以杜絕使用Deprecated API。
sun.*包的 一些API在發生了變化。 這些API不供開發人員使用。 開發人員導入sun.*包,需要自己承擔風險。 欲了解更多詳細信息,請參閱為什麼開發人員不應該編寫調用‘sun’包的程序
對於Deprecated API列表,請參閱Deprecated API

行為兼容性

簡而言之,行為兼容性意味著在輸入相同時,程序在不同版本的庫或平台執行相同(或等同)的操作。 有些平台行為的底層實現是故意設定為未定義的,這樣平台發布可以更改。 出於這個原因,建議寫代碼不依賴於未定義的行為:如果依賴了未定義行為,問題不能算平台不兼容,而是算代碼的bug。

Java類文件

Java類文件格式已經更新為Java SE 8版本。
按照JVM規範,Java SE 8的類文件版本是52.0。 由Java SE 8編譯器產生的版本為52.0的類文件不能在早期版本Java SE中使用。
下麵的文檔有Java語言規範(JLS)和Java虛擬機規範(JVMS)的更改信息。

Java SE 8和Java SE 7之間的不兼容性

盡管Java SE 8是與Java平台的早期版本是非常兼容的, 幾乎所有現有的程序可以不加修改地運行在Java SE 8,不過JRE和JDK也有一些小的潛在的不兼容性。為了完整性,這裏記錄極少數情況下“極端案例”。
本節介紹了Java語言的JVM或Java SE API的Java SE 8不兼容。
請注意,此版本中一些API已棄用,有些功能已被完全刪除。 雖然這些都是不兼容,他們被列為在單獨的列表。 欲了解更多信息,請參閱Deprecated APIsJDK 8移除的功能
2015年3月Java SE 8進行了版本維護,不兼容的問題有相應的修改。

  • JVM:接口默認方法不能觸發接口立即初始化

    不兼容性: 行為
    Bug:8043188
    (譯者注:8u40已修複)

  • JVM:JDWP支持接口默認方法和靜態方法

    不兼容性: 行為
    RFE:8042123
    (譯者注:8u40已修複)

  • JVM:對invokespecial指令調用實例初始化方法的校驗更加嚴格
    (譯者注:隻有當前類型或直接超類的實例允許調用)
    不兼容性: 行為
    REF: 7160765 (譯者注:可能是安全相關,無法看到更詳細內容)

  • JVM:默認每個類文件中都設置了ACC_SUPER標誌
    Java SE 8以及以上,Java虛擬機默認每個類文件中都設置了ACC_SUPER標誌,無論標誌在類文件的實際值和類文件的版本的。 該ACC_SUPER標誌影響invokespecial的行為。
    不兼容性: 行為(譯者注:可能是安全相關,無法看到更詳細內容)

  • JAVA:classes_text支持小語種
    當使用DateFormat和SimpleDateFormat來格式化日期時間值時 ,上下文有關的月份名稱支持既有格式化形式又有獨立形式的小語種。 例如,在捷克語中,一月的格式化形式是ledna,而獨立形式是leden。 DateFormatSymbols的getMonthNames方法和getShortMonthNames方法返回這些語言的月份格式化形式。請注意,直到的Java SE 7,DateFormatSymbols都是返回獨立的形式。您可以用Calendar.getDisplayName方法和Calendar.getDisplayNames方法來製定返回哪種形式。 請參考API文檔。
    不兼容性: 行為
    RFE:7079560

  • 核心庫:javax.lang.model引入IntersectionType
    在Java SE 8,對於具有multiple bounds的TypeVariables ,javax.lang.model.type.TypeVariable.getUpperBound的返回值和早期版本的返回值不同。現在返回新引入IntersectionType的實例,而原來返回DeclaredType的實例。 這可能會導致javax.lang.model.util.TypeVisitor現有的實現行為改變:之前TypeVariable.getUpperBound返回multiple bounds變量時調用visitDeclared方法,現在調用visitIntersection方法。 對返回值調用getKind()也能觀察到差別。
    不兼容性: 行為
    RFE: 6557966

  • 核心庫:non-public java.lang.reflect.Proxy
    實現了non-public interface的java.lang.reflect.Proxy將是non-public, final, 且非abstract的。 在Java SE 8之前,代理類是public, final, 且非abstract。

    • 如果現有的代碼不在同一個運行時package裏麵調用Proxy.getProxyClass和Constructor.newInstance方法來創建一個代理實例,它會失敗,並拋IllegalAccessException。 對於這樣的代碼,它需要更改源碼為:(1)調用Constructor.setAccessible設置訪問標誌設置為true,或(2)使用方便的Proxy.newProxyInstance方法。
    • 如果現有代碼試圖創建其他運行時package的non-public接口代理,需要授權新的permission ReflectPermission("newProxyInPackage.{package name}")不兼容性: 源碼
  • 核心庫:java.lang.reflect.Proxy不允許空InvocationHandler
    如果給定的InvocationHandler參數為空,java.lang.reflect.Proxy(InvocationHandler h)構造函數現在拋NullPointerException。
    現有代碼使用空參數構造動態代理實例將拋NullPointerException。 這種用法估計很罕見,因為空代理實例無論用在何處都將拋NullPointerException。
    不兼容性: 行為
    RFE: 4487672

  • 核心庫:java.math的BigDecimal.stripTrailingZeros的零值問題
    Java SE 8之前,如果調用BigDecimal.stripTrailingZeros的數值等於零,將返回該值。 現在則返回常量BigDecimal.ZERO
    不兼容性質: 行為
    RFE: 6480539

  • 核心庫:java.net的HttpURLConnection響應頭引號問題
    在以前的版本中HttpURLConnection摘要身份驗證實現有誤,在WWW-Authenticate響應頭中對一些值加了引號。 在Java SE 8版本中,這些值不再加引號。 這是嚴格遵循RFC 2617 HTTP Authentication: Basic and Digest Access Authentication
    一些服務器實現的某些版本已知預期這些值被引用。 HTTP請求到這些服務器可能無法再成功進行身份驗證。 而以前由於這些值被加引號而失敗的身份驗證,可能現在能成功驗證。
    不兼容性: 行為
    RFE: 8010505

  • 核心庫:java.net的socket非臨時端口安全問題
    在此版本中,分配給包括不​​可信代碼的所有代碼默認socket權限已被更改。 以前,所有代碼能夠bind任何類型的socket,以及任何大於或等於1024的端口號。此版本仍可以bind socket到每個係統上的臨時端口範圍。 臨時端口的確切範圍因操作係統而不同,但通常在高範圍(如從49152到65535)。新的限製是bind socket到臨時端口範圍之外需要顯式係統安全策略授權。絕大多數使用客戶端TCP socket(開啟了SecurityManager)的應用將不會看到任何問題,因為這些通常bind到臨時端口。 而使用datagram socket或服務端tcp socket(開啟了SecurityManager)應用可能拋安全異常。之前版本不會。 如果發生這種情況,使用者應該檢查被請求的端口號是否符合預期。如果符合預期,添加一個socket授權到本地安全策略來解決此問題。
    不兼容性: 行為

  • 核心庫:java.net的DatagramPacket構造函數不再聲明異常
    在Java SE 8之前,帶java.net.SocketAddress參數的java.net.DatagramPacket構造函數,聲明拋出java.net.SocketException。 然而,這個異常永遠不會被拋出。 在Java SE 8版本中,該構造函數不再聲明拋出java.net.SocketException。 如果的代碼catch了SocketException或它的超類java.io.IOException ,在使用與Java SE 8編譯之前刪除這些catch塊。
    不兼容性: 源碼
    RFE: 8022126

  • 核心庫:java.util.i18n的LocaleServiceProvider判斷Locale問題
    選擇LocaleServiceProvider的機製已經改變。LocaleServiceProvider的實現現在能夠通過overideLocaleServiceProvider.isSupportedLocale方法來確定Locale是否支持。 然而,如果從JDK7遷移locale service providers, overide此方法對於嚴格的擴展檢查可能涉及與現有應用程序的一些兼容性問題。參考LocaleServiceProvider類及其isSupportedLocale方法的描述了解更多細節。
    不兼容性: 行為
    RFE: 7168528

  • 客戶端庫:java.awt

    不兼容性: 行為
    RFE: 7146237

  • 安全庫:javax.net.ssl拒絕客戶端初始化的renegotiation
    Oracle JSSE provider的新sytem propertyjdk.tls.rejectClientInitializedRenego拒絕客戶端初始化的renegotiation 。如果這個sytem property為true。服務端拒絕客戶端renegotiation的請求,並且拋出handshake_failure警報。
    不兼容性: 行為
    RFE: 7188658

  • Hotspot JVM:gc刪除Perm
    刪除並忽略命令行選項 PermSize和MaxPermSize。 如果使用了這兩個選項,會發出如下警告:

    Java HotSpot(TM) Server VM warning: ignoring option PermSize=32m; support was removed in 8.0
    Java HotSpot(TM) Server VM warning: ignoring option MaxPermSize=128m; support was removed in 8.0
    

    不兼容性: 源碼
    RFE: 6965548

JDK 8與JDK 7之間的不兼容性

本段描述JDK 8在javac、HotSpot或Java SE API中與JDK 7不兼容之處。
需要注意的是,部分API在本次發布中已經標注為不建議使用,甚至部分特性已經被完全移除。這些不兼容的地方在這裏單獨列出來。如果需要更多的信息,參看Deprecated APIsJDK 8移除的功能

  • JVM:JDI中接口支持默認方法和靜態方法
    Java SE 8語言規範為接口引入了靜態方法和默認方法,因此JDI規範和具體實現中都已經允許使用這個技術。在JDI中,com.sun.jdi.InterfaceType類包含了方法Value invokeMethod(ThreadReference thread, Method method, List<? extends Value> arguments, int options)
    不兼容性: 行為
    RFE: 8042123
    (譯者注:8u40已修複)

  • 核心庫:java.lang的windows中檢測登錄用戶home目錄
    在windows中檢測登錄用戶home目錄的步驟,更新為遵照微軟推薦的方法。這處改動對在如下兩類情況下可能需要重點關注:1.比較舊的windows版本;2.用戶home目錄在注冊表或環境變量中設置到其他的目錄下。
    不兼容性: 行為
    RFE: 6519127

  • 核心庫:java.lang.reflect的getMethods調用結果
    新特性默認方法會影響兩個方法Class.getMethod、Class.getMethods的調用結果。
    Class.getMethod、Class.getMethods的javadoc繼承了Java語言規範的定義。Java SE 8改變了這個規則,以便支持默認方法的同時削減繼承於超接口的冗餘方法(可參考JLS 8, 8.4.8)的數量。比如說,一個類有兩個超接口:I和J,每一個都定義了int length();,一般來說,我們認為兩個方法都是這個類的成員,但是如果J同樣擴展於I,那麼在Java SE 8中,這個類僅集成了一個方法:J.length()
    在Java SE 8發布的時候,Class.getMethod和Class.getMethods的實現並沒有隨定義的更新而更新(兩個方法都會返回非繼承的超接口的方法)。從兼容性看,這個區別沒那麼重要了,而與Java SE 7返回的一致性則是優先考慮的。因此無論如何,當重寫方法(如上麵提到的J.length)為默認方法,首先應該要過濾掉其他重寫的方法(如上麵提到的I.length)。
    從JDK 8u20開始,代碼實現改為在重寫默認方法時,增加上麵提到的過濾的步驟。
    不兼容性: 行為
    RFE: 8029674

  • 核心庫:java.text舍入行為問題
    在之前版本中,當使用NumberFormatDecimalFormat類時,在特殊情況下是會發生舍入行為的錯誤。這種錯誤行為一般發生在調用format()方法時,給的值非常接近於格式化字符串所定義的中間位置。在這種情況下,錯誤的雙精度值舍入或不舍入行為就會發生。
    舉例說,當使用默認推薦的NumberFormatFormat API:NumberFormat nf = java.text.NumberFormat.getInstance(),跟著格式化代碼nf.format(0.8055d),0.8055d值在計算機無法精確地表示為一個二進製的值,而是0.80549999999999999378275106209912337362766265869140625。在這裏默認的舍入是“half-even”法(譯者注:此舍入模式也稱為“銀行家舍入法”,主要在美國使用。四舍六入,五分兩種情況,如果前一位為奇數,則入位,否則舍去),JDK 7中調用format()方法會錯誤的輸出0.806,然而正確的值應該是0.805,因為內存中記錄的值是小於中間位置的。
    在所有可能由程序員自定義樣式(而不是默認的樣式)的位置裏,這個舍入行為被修正。
    不兼容性: 行為
    RFE: 7131459

  • 核心庫:java.util.collections的removeAll,retainAll不接受null
    在之前的版本中,一些Collection.removeAll(Collection)retainAll(Collection)的實現會靜默的忽略傳入null參數的情況。從這個版本開始,如果集合傳入一個null參數,將會拋出一個NullPointerException
    不兼容性: 行為
    RFE: 8021591

  • 核心服務:java.management強製管理接口public
    在規範中提到的管理接口需要是puclic的,在這個版本中變成強製的了。非public的接口不存續暴露管理功能,所有的MBean和MXBean接口必須是public的。
    係統屬性jdk.jmx.mbeans.allowNonPublic用於恢複成之前允許非public管理接口的行為。這個屬性是過渡期使用的,在後續的發布版中將會被移除。
    不兼容性: 行為

  • 客戶端庫:java.awt
    java.awt.Component.setFocusTraversalKeys()方法中,如果參數keystrokes裏的任何對象不是AWTKeyStroke的話,會拋出ClassCastException(之前是IllegalArgumentException)。
    不兼容性: 行為

  • 安全庫:java.security限製com.sun.media.sound
    com.sun.media.sound添加到了JDK 8受限製包列表中。在SecurityManager下運行的應用無法訪問這個包及其下各層級,除非得到明確的授權。com.sun.media.sound包一個內部的、不受支持的包,這相當於是說這不應該被外部的應用所使用。
    不兼容性: 源碼
    RFE: 8019830

  • 其他庫:corba限製se及其子包
    JDK內部包com.sun.corba.se及其子包已被添加到受限包列表中,運行SecurityManager情況下無法直接訪問。
    不兼容性: 行為
    RFE: 8021257

  • 工具:javac改正二進製比較的類型規則
    Java語言規範(JLS)的15.21章節中關於二進製比較的類型規則沒有正確的被javac實施。從JDK 5 版本開始,javac根據JLS規範15.21章節接受了一些類型不正確的對象-原生類型比較的程序。這些比較現在會被認為是類型錯誤。
    不兼容性: 行為
    RFE: 8013357

  • 工具:javac參數和方法的注解拷貝到合成橋接方法
    在這一次發布中,參數和方法的注解將會拷貝到合成橋接方法。這個修複意味著現在程序類似:

    @Target(value = {ElementType.PARAMETER})
    @Retention(RetentionPolicy.RUNTIME)
    @interface ParamAnnotation {}
    
    @Target(value = {ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @interface MethodAnnotation {}
    
    abstract class T<A,B> {
        B m(A a){return null;}
    }
    
    class CovariantReturnType extends T<Integer, Integer> {
        @MethodAnnotation
        Integer m(@ParamAnnotation Integer i) {
            return i;
        }
    
        public class VisibilityChange extends CovariantReturnType {}
    }
    

    每一個生成的橋接方法擁有所有的注解,參數注解也將會複製。這種行為上的改變將會影響一些注解處理器或任何使用注解的普通的程序。
    不兼容性: 行為
    RFE: 6695379

  • 工具:javac參數注解會拷貝到自動生成的內部類構造器
    參數注解會拷貝到自動生成的內部類構造器中。這個修複意味著現在如下的程序:

    @Target(value = {ElementType.PARAMETER})
    @interface ParamAnnotation {}
    
    public class initParams {
      public initParams(@ParamAnnotation int i) {}
    
      public void m() {
         new initParams(2) {};
      }
    }
    

    方法m()裏,內部類生成的構造器中,參數int i會有一個注解@ParamAnnotation。這個行為的變化可能影響一些注解處理器,或者使用了注解的應用程序。
    不兼容性:
    行為

  • 工具:javac不再識別編譯目標值1.4.1、1.4.2和jsr14
    javac不再識別編譯目標值1.4.11.4.2jsr14,這些之前就沒有記錄在文檔中。很多最新的代碼生成慣用語中1.4.11.4.21.4使用的更多,而組合選項-source 1.4 -target 1.5會在更新一些的慣用語中使用,同時也會輸出更新一些的字節碼文件格式。“jsr14”選項則是泛型被添加到平台後的一個過度選項,現在泛型編譯目標應該是1.5或更高。
    不兼容性: 行為
    RFE: 8010179

  • 工具:javac類型轉換編譯問題
    下麵的代碼在JDK 7中編譯會出現警告,而在JDK 8中將無法編譯:

    import java.util.List;
    
    class SampleClass {
    
        static class Baz<T> {
            public static List<Baz<Object>> sampleMethod(Baz<Object> param) {
                return null;
            }
        }
    
        private static void bar(Baz arg) {
            Baz element = Baz.sampleMethod(arg).get(0);
        }
    }
    

    JDK 8編譯上麵的代碼中會報如下錯誤:

    SampleClass.java:12: error:incompatible types: Object cannot be converted to Baz
        Baz element = Baz.sampleMethod(arg).get(0);
    
        Note: SampleClass.java uses unchecked or unsafe operations.
    Note: Recompile with -Xlint:unchecked for details.
    1 error
    

    在這個例子中,原始類型被傳遞到sampleMethod(Baz<Object>)方法中,而這個方法應該傳遞的是其子類型(參考JLS,Java SE 7 Edition, 15.12.2.2章節)。如果要可用的話,就需要一個未經檢查的轉換,而他的返回類型是被擦除的(參考JLS,Java SE 7 Edition, 15.12.2.6章節)。在這個例子中,sampleMethod(Baz<Object>)的返回類型是java.util.List,而不是java.util.List<Baz<Object>>,因此get(int)的返回值是Object,這就和被賦值的Baz類型不一致了。
    更多的信息,請參見java.net上相關的電子郵件交流。
    不兼容性: 源碼
    RFE: 7144506

  • 工具:javac的final字段明確賦值問題
    使用this關鍵字為final字段明確的賦值分析。
    傳統的,Java語言禁止通過簡單的名字(比如“x”)來訪問沒有明確賦值的final字段。在Java SE 7裏,字段是可以通過“this.x”進行訪問的(參見: https://bugs.openjdk.java.net/browse/JDK-7004835)。任何合法的程序在舊的規則下是非法的,而在新的規則下是不安全的,因為他必然會訪問一個沒有明確賦值的空白的final字段。
    從JDK 8u20開始,javac編譯器已經更新實現了Java SE 7的規則。
    不兼容性: 源碼
    Bug: 8039026
    (譯者注8u20已修複)

  • 工具:javac接口的實現進行編譯時接口需要存在
    當編譯一個類,這個類中使用到的其中一個類實現了一個接口,而這個接口定義在別的文件中,這種類文件(定義接口的文件)在javac編譯時必須可用。這是JDK 8的一個新的需求,不這樣做會導致一個編譯錯誤。例如:
    Client.java:

    import p1.A;
    
    class Client {
       void test() {
           new A.m();
       }
    }
    

    p1/A.java:

    package p1;
    
    public class A implements I {
       public void m() { }
    }
    

    p1/I.java:

    package p1;
    
    public interface I {
       void m();
    }
    

    如果p1/I.java或p1/I.class在編譯Client.java時不可用,就會出現下麵的錯誤信息:

    Client.java: error: cannot access I
           new A().m();
                ^
      class file for p1.I not found
    

    不兼容性: 行為

  • XML:JAXP的Xalan擴展功能安全問題
    JAXP中的Xalan擴展功能已經修改,以便於當SecurityManager存在時,默認的實現總是會被使用。這一改變會影響DOM Document創建的NodeSet。在之前,DOM實現由DOM工廠查找過程來定位。在這之後,當運行SecurityManager時,查找過程會跳過,並且用默認的DOM實現。
    這個改變僅影響使用了第三方DOM實現的應用。一般來說,NodeSet結構預計與JDK默認實現相兼容。
    不兼容性: 行為

  • XML:JAXP1.6規範更新
    JDK 8附帶了JAXP 1.6,包括規範更新,要求使用java.util.ServiceLoader查找服務提供者。跨JAXP的服務提供者能夠通過定義在java.util.ServiceLoader的流程被一致的放置。而JDK7中提供者配置文件可以是位於不同地方的,例如,通過不同的類加載器的getXXX方法比起ServiceLoader,這個改變導致與JDK 7的細微的差異。
    JDK 8 ships with JAXP 1.6 and so includes specification updates that mandate the use of java.util.ServiceLoader for finding service providers. Service providers across JAXP will now be located consistently following the process as defined in java.util.ServiceLoader. The changes may result in some subtle differences from implementations of JDK 7 where the provider-configuration file may have been located differently, for example, by using a different getXXX method of the ClassLoader than ServiceLoader.
    應用實現自己的類加載器,應該確認類加載器的getXXX方式的實現是一致的,以便保持兼容性。
    JSR 173中StAX API定義了接收factoryId參數的newInstancenewFactory方法。因為在StAX規範中對這個參數沒有任何限製,意味著可以是任意字符串。在JDK 8規範中進行了一下變更,在JAXP上下文裏,如果他想要表示服務配置文件的名稱,factoryId的值必須是基本服務類的名字,即,他不是一個係統屬性名稱。
    不兼容性: 行為
    RFE: 8005954

  • XML:JAXP的javax.xml.stream工廠的類加載器不再忽略
    javax.xml.stream工廠中,類加載器參數不再能忽略。
    javax.xml.stream包包含工廠類(XMLEventFactory、XMLOutputFactory、XMLInputFactory),這些工廠類定義newFactory方法時需要兩個參數:factoryId和ClassLoader。在JDK 7中,第二個參數在查找和實例化服務時可以被省略。在JDK 8中不再能省略。可以參考這些方法的Java API文檔來獲取更詳細信息。
    不兼容性: 行為
    RFE:
    8005954

Java SE 8中移除的功能

  • API:java.lang的Thread.stop關閉
    Thread.stop方法從JDK 1.2版本就被棄用了。這個方法現在會拋出一個UnsupportedOperationException。

  • 核心庫:java.net從需要的協議處理程序的列表中移除ftp協議
    ftp是一個曆史遺留的協議,它在很長時間內被一些更加安全的文件傳輸協議(比如sftp)取代。ftp協議已經從協議處理程序列表中移除並且保證透明的。它實際上不是移除協議處理程序-應用使用這個協議時能夠繼續工作,但是它的存在已經不再需要。
    RFE: 8000941

  • 安全庫:java.security不支持不安全的1024以下RSR密鑰
    在衡量基於加密算法的公鑰強度上,秘鑰的長度是一個很重要的安全參數。小於1024 bits的RSA秘鑰被認為是可以破解的。
    在這次更新中,如果他們的RSA秘鑰長度小於1024 bits的話認證會被阻止。這個限製是通過Java Security property,jdk.certpath.disabledAlgorithms實施。這種做法會影響附著security property的provider(比如Sun provider和SunJSSE provider)。security property和jdk.certpath.disabledAlgorithms也同樣覆蓋TLS使用的靜態秘鑰(X.509證書秘鑰)的使用。
    有了這些秘鑰長度的限製,這些使用基於長度小於1024 bits的RSA秘鑰的X.509證書在證書路徑的建立和驗證過程中會遇到兼容性的問題。這些秘鑰的長度限製同樣會影響需要驗證X.509證書的JDK組件,比如JAR簽名驗證,SSL/TLS傳輸和HTTPS連接。
    為了避免這些兼容性問題,使用了基於長度小於1024 bits的RSA秘鑰的X.509證書的用戶會被推薦使用更強的秘鑰並更新他們的證書。作為一種變通的方法,在自己能夠承受的風險之上,為了允許較小長度的秘鑰,用戶可以調節秘鑰的長度來限製安全性(jdk.certpath.disabledAlgorithms)。
    不兼容性: 行為

JDK 8中移除的功能

  • Install:安裝時不再提供關閉自動更新選項
    為了關閉JRE的自動更新,關閉自動更新並且設置部署配置中的係統屬性文件的deployment.expiration.check.enabled屬性為false。為了關閉自動更新,移除Java控製麵板中的更新按鈕中的檢測自動檢測功能。查看Deployment Configuration File and Properties獲取關於deployment.expiration.check.enabled property的更多信息。

  • Install:Solaris的Class Data Sharing文件不會被創建
    在這之前,Solaris SVID包在安裝時會創建Class Data Sharing文件。在JDK 8中,32位的Solaris不再被支持,因此Class Data Sharing文件也默認不會被創建。如果想要手動創建Class Data Sharing文件。執行下列命令:
    $JAVA_HOME/bin/java -Xshare:dump
    當命令執行後,Class Data Sharing文件位於:
    $JAVA_HOME/jre/lib/server/{amd64,sparcv9}/classes.jsa
    RFE: 8023498

  • Deployment:Plugin移除經典的Java Plug-in
    舊的Java Plug-in(Java SE 6u10之前的版本)會在這個版本中被移除。
    RFE: 7076143

  • Deployment:Plugin移除Java 快速開始(Java Quick Starter)
    Java快速開始(JQS)服務在這個版本中會被移除
    RFE: 8004321

  • Deployment:Plugin移除Active-X Bridge
    Active-X Bridge在這個版本會被移除。
    RFE: 8004321

  • 核心庫:sun.jdbc.odbc移除JDBC-ODBC Bridge
    從JDK 8版本開始,JDK將不再包含JDBC-ODBC Bridge。JDBC-ODBC Bridge已經被認為是一個過渡期的產品,並且是一個僅僅用於選擇JDK軟件包並不包含在JRE中的JRE不支持的產品。可以使用數據庫供應商提供或者是一個商業版本的JDBC Driver替換JDBC-ODBC Bridge。
    RFE: 7176225

  • Tools:apt移除apt工具
    apt工具以及com.sun.mirror包中和它相關的API都將在這個版本中移除。使用命令行工具javac以及包javax.annotation.processing,包javax.lang.model處理注解。
    RFE:
    7041249

  • Tools:java移除32位的Solaris
    32位的Solaris操作係統的Java實現會在這個版本中移除。$JAVA_HOME/bin$JAVA_HOME/jre/bin文件夾現在隻包含64位的版本。為了過渡的目的,ISA(Instruction Specific Architecture)目錄中$JAVA_HOME/bin/{sparcv9,amd64}$JAVA_HOME/jre/{sparcv9,amd64}有指向32位版本的符號鏈接。這些ISA目錄將在JDK 9版本中被移除。
    SUNWj8rt,SUNWj8dev和SUNWj8dmo,這些之前包含32位版本的安裝包現在包含64位版本。SUNWj8rtx,SUNWj8dvx和SUNWj8dmx安裝包將被移除。
    64位版本的java不會包含諸如Java Web Start和Java Plug-in的部署工具,因此桌麵集成也不再需要了。
    注意到64位的Solaris的可執行文件不能加載位32位Solaris編譯和鏈接的JNI庫。因此任何在32位Solaris係統中創建的JNI庫都需要重新編譯64位Solaris版本。
    RFE: 8023288

Deprecated API

  • 核心庫:java.lang:class_loading棄用endorsed
    endorsed-standards override mechanism允許在Java Community Process維護的標準之外,或者是持續獨立發展的作為Java SE平台的獨立的APIs上實現新版本並且在運行時刻安裝。
    一個模塊化的映像是由模塊而不是jar包文件組成。往前看,我們希望通過可升級的模塊(upgradeable module)隻支持模塊化形式的認可的標準和獨立的APIs。
    這個特性會在JDK 8u40版本中被棄用。這個棄用是為將來的Java SE版本中出現的module特性而做準備的。如果想要了解更多信息,查看JEP 200 - The Modular JDKJEP 220 - Modular Run-Time Images
    這些改變不會改變運行時刻的行為。
    RFE: 8065675

  • 核心庫:java.lang:class_loading棄用extension
    擴展機製(extension mechanism)允許包含擴展了Java SE平台APIs的jar文件安裝到一個運行時映像,使它們的內容在可見的情況下編譯或運行的映像上的每一個應用程序。
    這樣的擴展機製在發布於1998年的JDK 1.2版本引入,但是在現在我們看不到任何憑證顯示有人去使用這個特性。這並不奇怪,因為多數現代的Java應用程序會直接在class path上直接安裝類庫而不是在運行時刻去安裝類庫。
    這個特性會在JDK 8u40版本時棄用。這個棄用是為將來的Java SE版本中出現的module特性而做準備的。如果想要了解更多信息,查看JEP 200 - The Modular JDKJEP 220 - Modular Run-Time Images
    這個特性的棄用需要下列標準規範的改變:

    • java.lang.System.getProperties()方法中,java.ext.dirs係統屬性的規範會被修訂為包含一個會在將來版本中移除的棄用聲明。
    • java.util.jar.Attributes.Name類中,域EXTENSION_INSTALLATIONIMPLEMENTATION_URLIMPLEMENTATION_VENDOR_ID的被棄用表明應該使用class path代替它們。
    • 在JAR文件的規範中,所有和打包JAR包的小程序依賴的已安裝的可選包和觸發對可選包下載的相關的manifest屬性都被棄用。這些屬性包括:xtension-Name, Extension-List, <extension>-Extension-Name, <extension>-Specification-Version, <extension>-Implementation-Vendor-ID, <extension>-Implementation-Version, <extension>-Implementation-URL, Implementation-Vendor-Id, Implementation-URL,Extension-Installation。 這些改變不會改變運行時刻的行為。 RFE: 8065702
  • 核心庫:java.lang棄用SecurityManager.checkMemberAccess
    SecurityManager.checkMemberAccess被棄用。它在調用者的棧幀深度為4的時候容易出錯。JDK的實現將不再調用SecurityManager.checkMemberAccess方法去執行成員變量訪問控製的檢測;替代它的是調用SecurityManager.checkPermission方法。
    通過重寫checkMemberAccess方法定製的SecurityManager的實現可能會被影響導致重寫的方法不會被調用。

  • 核心庫:java.lang棄用SecurityManager類的checkTopLevelWindow, checkSystemClipboardAccess, checkAwtEventQueueAccess
    可替代的方法: checkPermission
    RFE: 8008981

  • 核心庫:java.rmi棄用RMI/JRMP的HTTP代理
    RMI/JRMP的HTTP代理功能被棄用,而且HTTP的代理功能默認被關閉
    RFE: 8023862

  • 核心庫:java.rmi棄用RMI(JRMP)靜態生成stubs
    不再支持RMI(JRMP)靜態生成stubs
    RFE: 8023863

  • 核心庫:java.util.jar棄用Pack200.Unpacker接口的addPropertyChangeListener和removePropertyChangeListener
    這些方法希望在將來的Java SE版本中移除
    可替代的方法: 跟蹤unpacker執行過程,輪詢PROGRESS屬性的值。
    RFE: 8000362

  • 核心庫:java.util.logging棄用LogManager接口的addPropertyChangeListener和removePropertyChangeListener
    這些方法希望在將來的Java SE版本中移除

  • 核心庫:com.sun.security.auth.callback棄用DialogCallbackHandler類
    使用時會告知將會被移除,在JDK 9的版本中會被徹底移除。
    RFE: 7190273

  • 核心服務:javax.management的RMI連接器IIOP將移除
    JSR-160規範已經更新了關於RMI連接器不再需要支持IIOP傳輸。Oracle JDK 8會繼續支持IIOP的傳輸,但是支持IIOP的傳輸希望會在將來版本的JMX Remote API中移除。
    RFE: 8001048

  • 客戶端庫:javax.accessibility棄用javax.swing.JComponent.accessibleFocusHandler
    可替代的方法: java.awt.Component.AccessibleAWTComponent.accessibleAWTFocusHandler
    RFE: 7179482

  • JavaFX:Scene Graph棄用Builder
    可替代的方法: 使用合適的構造器和set方法去構造對象。
    RFE: RT-30520

  • 安全庫:java.security棄用insertProvider
    java.security.SecurityPermission insertProvider.{provider name}的目標名稱在將來使用時會被勸阻,因為他可能在重寫java.security.Provider.getName方法時會遇到命名約束而被阻止。同樣,在使用通過插入一個指定命名或者是選擇獲取的任意名稱的provider授予代碼權限時會有同樣的風險。
    可替代的方法: 新的insertProvider目標名稱。兼容現有已經被保留的policy文件,原因在於新舊的權限都會被Security.addProviderinsertProviderAt方法檢測。
    RFE: 8001319

  • HotSpot JVM:gc棄用一些組合
    以下的GC組合被棄用:

    • DefNew + CMS
    • ParNew + SerialOld
    • Incremental CMS

    對應的命令行選項會產生警告信息並且建議你不要使用這樣的組合。這些命令行選項會在將來的某個主要版本中移除。

    • 命令行選項-Xinggc被棄用
    • 命令行選項-XX:CMSIncrementalMode被棄用。注意,這個命令行選項會影響所有的CMSIncremental選項。
    • 命令行選項-XX:+UseParNewGC被棄用。除非你同時使用選項-XX:+UseConcMarkSweepGC
    • 命令行選項-XX:-UseParNewGC隻有在和-XX:+UseConcMarkSweepGC選項一起使用時被棄用。 想要獲得更多的信息,請查看 https://openjdk.java.net/jeps/173 RFE:8006479
  • Hotspot:gc棄用CMS GC的前端收集器
    CMS GC的前端收集器(foreground collector)已經被棄用,並且希望在將來的某個版本中移除。使用G1或者是常規的CMS替代。
    比如在使用-XX:+UseCMSCompactAtFullCollection -XX:+CMSFullGCsBeforeCompaction -XX:+UseCMSCollectionPassing等選項時,會打印一個已經棄用的警告,但是VM仍會繼續工作。
    RFE: 8027132

最後更新:2017-04-01 13:44:33

  上一篇:go [翻譯]JDK8有什麼新東西?
  下一篇:go ALICloudDB for PostgreSQL 試用報告 - 2 教你RDS PG的水平分庫