<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    dream.in.java

    能以不變應萬變是聰明人做事的準則。萬事從小事做起,積累小成功,問鼎大成功,是成功者的秘訣。

    ClassCastException 錯誤解析 [轉](

     
    轉:作者:佚名    文章來源:不詳    點擊數:
    引用文章原地址:http://blog.java-cn.com/more.asp?name=zhouli&id=12303 (只引用部分)

    現在java編程中經常碰到ClassCastException 錯誤,ClassCastException 是 JVM 在檢測到兩個類型間的轉換不兼容時引發的運行時異常。此類錯誤通常會終止用戶請求。本模式試圖為您提供了解和排除 ClassCastException 錯誤最常見成因的一些基本要素。
    為什么發生此問題?

    在執行幾乎任何子系統(Web 容器、EJB、JCA、群集等)的應用程序代碼或 WebLogic Server 代碼內均可能發生 ClassCastException。通過轉換,可以指示 Java 編譯器將給定類型的變量作為另一種變量來處理。對基礎類型和用戶定義類型都可以進行轉換。Java 語言規范定義了允許的轉換,其中的大多數可在編譯時進行驗證。不過,某些轉換還需要運行時驗證。如果在此運行時驗證過程中檢測到不兼容,JVM 就會引發 ClassCastException。

    假設有一個 S 類型的對象,我們想把它轉換為 T 類型。


    S s;
    ...
    T t = (T) s;


    如果存在以下情況,上述轉換就可能引發 ClassCastException

    • S 與 T 不兼容。規范規定:“當應用程序代碼嘗試將某一對象轉換為某一子類時,如果該對象并非該子類的實例,JVM 就會拋出 ClassCastException。”以下是一個示例代碼,執行該代碼時將會引發此類錯誤:
      public class TestCCE {

        public static void main(String args[]) {
          Object obj = new Object();
          String s = (String) obj;
        }
      }
    • S 類型和 T 類型兼容,但加載時使用了不同的 ClassLoader。
    第二個原因實際上是這種錯誤最常見的原因。這種情況在診斷上有相當的難度,而且需要對 Java 類加載以及 WebLogic 類加載體系結構方面的基礎知識有一定程度的了解。

    返回頁首什么是 ClassLoader?

    ClassLoader 是允許 JVM 查找和加載類的一種 Java 類。JVM 有內置的 ClassLoader。不過,應用程序可以定義自定義 ClassLoader。應用程序定義新的 ClassLoader 通常有兩個主要目的:

    • 自定義和擴展 JVM 加載類的方式。例如:增加對新的類庫(網絡、加密文件等)的支持
    • 劃分 JVM 名稱空間,避免名稱沖突。舉例來說,利用劃分技術可同時運行同一應用程序的多個版本(基于空間的劃分)。此項技術在應用程序服務器(如 WebLogic Server)內的另一個重要用途是啟用應用程序熱重新部署,即在不重新啟動 JVM 的情況下啟動應用程序的新版本(基于時間的劃分)。

       

    ClassLoader 按層級方式進行組織。除系統 Boot ClassLoader 外,其它 ClassLoader 都必須有父 ClassLoader。http://e-docs.bea.com/wls/docs81/programming/classloading.html (English) 中提供了對 WebLogic 類加載體系結構的說明。
    理解類加載的關鍵

    記住以下內容會有幫助:

    • 永遠無法在同一 ClassLoader 中重新加載類:“熱重新部署”需要使用新的 ClassLoader。每個類對其 ClassLoader 的引用都是不可變的:this.getClass().getClassLoader()
    • 在加載類之前,ClassLoader 始終會先詢問其父 ClassLoader(委托模型)。這意味著將永遠無法重寫“核心”類
    • 同級 ClassLoader 間互不了解
    • 由不同 ClassLoader 加載的同一類文件也會被視為不同的類,即便每個字節都完全相同。這是 ClassCastException 的一個典型成因。
    • 可以使用 Thread.setContextClassloader(cl) 將 ClassLoader 連接到線程的上下文

    診斷

    通常可以在服務器的日志和/或客戶端獲得完整的 ClassCastException 堆棧跟蹤。該堆棧應能使您對涉及的 WebLogic Server 子系統的情況有相當深入的了解。請根據這些信息確認該問題是否與某個已知 WebLogic Server 問題的情況相符。如果相符,請使用相應的解決辦法。

    如果錯誤與所有已知問題的情況均不相符,則需要做進一步探查。如果錯誤出現在您可以編輯和編譯源代碼的類中,以下方法可能有助于您理解該問題。

     

    假設出現錯誤的代碼行類似于:

    oo f = (Foo) bar.method();


    如果按照轉換規則該轉換應該有效,但仍然引發了 ClassCastException,則可能的情況是:類“bar”“Foo”是由不同的 ClassLoader 加載的。要驗證這一點,請像下面這樣拆分該代碼行:

    Object o = bar.method();
    System.err.println("The object " + o + " classloader is " +
    o.getClass().getClassLoader());
    System.err.println("Class Foo class loader is " +
    Foo.class.getClassLoader());
    Foo f = (Foo) o;


    典型的輸出可能與此類似:

    The object Foo@@3e86d0 classloader is
    sun.misc.Launcher$AppClassLoader@b9d04
    Class Foo classloader is
    weblogic.utils.classloaders.ChangeAwareClassLoader@5998cb finder:
    weblogic.utils.classloaders.MultiClassFinder@7c2528


    下一步是探查為什么涉及了不同的 ClassLoader。請執行下列檢查清單中的各項檢查:

    • 檢查應用程序打包情況,并檢查“Foo”是否是使用由不同 ClassLoader 加載的不同模塊打包而成。在這方面眾所周知的一個成因是 Web 應用程序的“prefer-web-inf-classes”功能(請參閱已知的 WebLogic 問題)
    • 檢查它正在使用的應用程序代碼或某個框架代碼是否更改了 WebLogic 線程的上下文 ClassLoader,且在請求流程期間未將其還原。如果應用程序代碼內有對 Thread.setContextClassloader(cl) 的調用,就可能存在這種情況。
    • 如果上述所有措施均無濟于事,請嘗試將問題隔離在一個簡單的、可重現的測試案例中,然后聯系 BEA 技術支持部門,以做進一步探查。

      已知的 WebLogic Server 問題

      以下匯集了可導致 ClassCastException 錯誤的各種情況,您在使用各種 WebLogic 子系統時可能會遇到這些情況。

      小程序

      有關該情況的完整說明,請參考 http://e-docs.bea.com/wls/docs81/applets/usingapplets.html (English)

       

      摘要:如果小程序中的 WebLogic Server 客戶端嘗試從 ClassLoader 獲取某些資源信息,且一并使用了緩存標志和 codebase=/bea_wls_internal/classes 標志,就可能會拋出 ClassCastException


      解決方法:
      • 在將類路徑 servlet 用作代碼基時,請不要使用“cache_option”和“cache_archive”一類的緩存選項。
      • 使用緩存選項時,請不要使用 /classes (ClasspathServlet) 做為代碼基。如果要這樣做,請先使用歸檔實用程序打包客戶端 JAR。
      有關此限制的詳細信息,請參閱 http://developer.java.sun.com/developer/bugParade/bugs/4648591.html (English)。

       

      JCA Connector

      有關該情況的完整說明,請參考 http://e-docs.bea.com/wls/docs81/notes/issues.html (English)。

       

      摘要:發出連接請求時,WebLogic Server 會返回一個代理對象,該對象通過資源適配器將連接對象封裝后返回到客戶端。WebLogic Server 使用該代理來提供一些功能,幫助應用程序使用 WebLogic Server 的“J2EE 連接器體系結構”實現。這些功能包括 (1) 連接泄漏檢測功能和 (2) 連接請求在啟動使用該連接的全局事務之前發出時,推遲 XAResource 登記。

       

      如果將連接請求返回的連接對象向原始的 Connection 類進行了轉換,就可能發生 ClassCastException。導致該異常的對象不外乎在連接請求過程中:(1) 資源適配器進行轉換時或 (2) 客戶端進行轉換時。

       

      在 WebLogic Server 8.1 SP2 中,嘗試檢測由上述資源適配器情況 (1) 導致的 ClassCastException。如果服務器檢測到該轉換失敗,將關閉代理包裝器功能,并在連接請求期間返回連接對象(不進行包裝)。服務器會記錄一條警告消息,說明代理包裝器已被關閉。出現此類轉換故障時,連接泄漏檢測和 XAResource 推遲登記功能也將被關閉(但當前在控制臺監視中并不會就此給出任何指示)。

       

      WebLogic Server 嘗試以使用容器管理的安全性的客戶端身份檢測 ClassCastException。如果要這樣做,則部署的資源適配器須定義安全性 Credential。

       

      如果客戶端在執行轉換時發生 ClassCastException,可按如下方式修改客戶(客戶端)代碼:

       

      解決方法:如果客戶端將連接對象轉換為 MyConnection,而不是將 MyConnection 作為實現資源適配器的 Connection 接口的一個類,請將該對象修改為一個擴展 Connection 的接口。實現一個用于實現 MyConnection 接口的 MyConnectionImpl 類。

       

      Servlet 動態重新加載

      有關該情況的完整說明,請參考 http://e-docs.bea.com/wls/docs81/jsp/reference.html (English)

       

      摘要:要在會話過程中動態重新加載 servlet 或 JSP,servlet 會話中存儲的對象必須是可序列化的。需要進行序列化是因為,servlet 是使用新的 ClassLoader 重新加載的,而這會導致此前加載的所有類(舊版本 servlet 中的類)與使用新的 ClassLoader 加載的所有類(新版本 servlet 類)發生不兼容的情況。這種不兼容會導致 servlet 返回 ClassCastException 錯誤。

      使用 Prefer-web-inf-classes 功能

      有關該情況的完整說明,請參考 http://e-docs.bea.com/wls/docs81/programming/classloading.html (English)

      摘要:weblogic.xml Web 應用程序部署描述符包含一個 prefer-web-inf-classes 元素(container-descriptor 元素的子元素)。缺省情況下,此元素設置為 False。如果將此元素設置為 True,則不遵循 ClassLoader 委托模型,從而使 Web 應用程序中的類定義的加載順序優先于更高級別的 ClassLoader 中的類定義。這樣 Web 應用程序就可使用其自己版本的第三方類,該類也可能是 WebLogic Server 的一部分。請參閱 weblogic.xml Deployment Descriptor Elements (English)。

       

      使用該功能時,必須注意不要混淆使用 Web 應用程序的類定義創建的實例與使用服務器的定義創建的實例。如果混淆了此類實例,就會發生 ClassCastException。

      群集:在 http 會話中存儲包含 EJBObject 的自定義對象 - CR102119

      摘要:可序列化的自定義對象會包裝 EJBObject(對 EJB 的引用)。該自定義對象存儲在 http 會話中。會話復制時,這種設計就會導致 ClassCastException。

      解決方法:在以后版本的 WebLogic Server 中將徹底解決該問題。目前的解決辦法是在包裝器內存儲 EJB 句柄(而不是 EJBObject)。群集:Failover 后使用 http 會話中的 EJB 句柄 - CR187062

      摘要:在群集中分別部署 webApp 和 EJB。EJB 句柄

    • 包裝在可序列化的自定義對象中,而該對象存儲在 http 會話中。Failover 后,通過句柄訪問 EJB 就會發生 ClassCastException。

       

      解決方法:在同一個 ear 文件中包裝 webApp 和 EJB。該問題存在于 WLS 8.1sp2 中,目前正在等待更正。
      需要更多幫助?
      如果您已經理解這個模式,但仍需要更多幫助,您可以:

      1. 在 http://support.bea.com/ 上查詢 AskBEA(例如,使用“ClassCastException”),以查找其它已發布的解決辦法。
      2. 在 http://forums.bea.com/ 上,向 BEA 的某個新聞組提出更詳細具體的問題。

      如果這還不能解決您的問題,并且您擁有有效的技術支持合同,您可以通過登錄以下網站來打開支持案例:http://support.bea.com/。

      反饋

      請給我們提供您的意見,說明此支持診斷模式“探查 ClassCastExceptions”一文是否有所幫助、您需要的任何解釋,以及對支持診斷模式的新主題的任何要求。

      免責聲明:

      依據 BEA 與您簽署的維護和支持協議條款,BEA Systems, Inc. 在本網站上提供技術技巧和補丁供您使用。雖然您可以將這些信息和代碼與您獲得 BEA 授權的軟件一起使用,但 BEA 并不對所提供的技術技巧和補丁做任何形式的擔保,無論是明確的還是隱含的。

      本文檔中引用的任何商標是其各自所有者的財產。有關完整的商標信息,請參考您的產品手冊。

    posted on 2009-04-05 01:12 YXY 閱讀(125) 評論(0)  編輯  收藏


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 日日噜噜噜噜夜夜爽亚洲精品| 成年女人色毛片免费看| 亚洲日韩国产一区二区三区| 亚洲精品伦理熟女国产一区二区 | 亚洲一区二区三区在线观看蜜桃| 一级毛片免费不卡在线| 亚洲AV无码成人专区片在线观看 | 亚洲午夜视频在线观看| 国产一级淫片a免费播放口| 亚洲VA中文字幕无码毛片 | 国产黄在线观看免费观看不卡| 最新亚洲成av人免费看| 成在线人免费无码高潮喷水| 亚洲无码在线播放| 久久久久国产免费| 亚洲伊人久久大香线蕉影院| A级毛片内射免费视频| 美女的胸又黄又www网站免费| 亚洲精品成人片在线观看| 国产一区二区三区免费观在线| 国产亚洲精品自在久久| 1区2区3区产品乱码免费| 亚洲午夜在线播放| 国产免费人成在线视频| 在线免费视频你懂的| 亚洲国产精品婷婷久久| 免费高清小黄站在线观看| 日本中文字幕免费看| 午夜亚洲www湿好大| 猫咪社区免费资源在线观看| 色www免费视频| 亚洲av女电影网| 女人被男人桶得好爽免费视频| 国产精品免费视频观看拍拍| 亚洲成年人免费网站| 国产午夜免费秋霞影院| 国产亚洲免费的视频看| 亚洲精品无码久久久久久| 亚洲精品国产精品乱码不卡√ | 国产精品亚洲色婷婷99久久精品| 亚洲日韩小电影在线观看|