2013-01-04 233 views
1

我有一些使用專有sun * *。OperatingSystemMXBean的代碼,所以我對此非常小心。這段代碼爲什麼編譯,但運行時有ClassNotFoundException?

try { 
    _osBean = (com.sun.management.OperatingSystemMXBean) java.lang.management.ManagementFactory.getOperatingSystemMXBean(); 
} 
catch (ClassCastException e) { 
    _osBean = null; 
} 

然而,當這個代碼在IBM JVM上運行,而不是ClassCastException,我得到一個運行ClassNotFoundException。爲什麼這個代碼能夠編譯得很好,如果該類不可用,以及JVM如何影響這樣的事情?

+0

我想如果你用一個oracle編譯器編譯它並在IBM JVM上運行它,它會發生。 – assylias

+1

**不要使用任何'com.sun。*'類。 – fge

+1

@fge - 強詞。我寧願說,你必須小心,理解你的部署環境,並儘可能地優雅地回落。 –

回答

3

com.sun。*軟件包是由Sun爲Sun JVM(熱點)編寫的私有類,不是公共API(即使您的代碼證明它們可訪問)。 IBM JVM是一個完全不同的實現,並沒有它們(因爲它們不是任何java/jvm規範的一部分)。因爲您選擇與太陽/ oracle的JDK
編譯,試圖解決這個問題
即時猜測它編譯罰款,試圖鑄造

,而不是(這是一個公共API),看看是否適合你

+0

java.lang變體當然工作正常。我從中得到的結果是,Java不包含編譯jar中的所有類,並且這些留給JVM來動態加載?我從未真正給出過這個想法。這似乎很奇怪,因爲像C這樣的語言會爲標準庫生成機器碼? – mvd

+0

正確。它包含編譯過的jar文件中所有已編譯好的_your_代碼類,而不是編譯過的庫類(這些類位於類路徑@compile時間,大部分駐留在jvm lib目錄內的名爲rt.jar的jar文件中,對於JDK類)。另外,它不會加載類的字節碼,除非它們被引用 - 所以如果你的jar中包含一個永遠不會被使用的編譯類,它將永遠不會被加載。 – radai

1

你使用的是Sun的Javac編譯

com.sun.management.OperatingSystemMXBean 

用,而是IBM的Java與運行。您的IBM環境不會有與Sun有關的任何內容。 com.sun。*類是專有的,應謹慎使用。

順便說一下,您可以通過編譯第三方jar而不是使用它進行部署來獲得此錯誤。例如一個Apache jar或類似的東西。這不是一個與專有罐子相關的錯誤,而是一般的部署問題。

0

想必你是編譯針對太陽JDK其中包含com.sun.management.OperatingSystemMXBean。這不是標準JDK的一部分,這就是爲什麼你不應該使用它 - 它不能保證在其他Java系統上出現,並且出現在您正在使用的IBM JVM中的而不是

這與編譯時針對任何其他庫在執行時不存在的情況相同。

參見:

0

您使用的是Sun提供的編譯器和JDK(具有類),但在IBM JVM它不運行。一般來說,如果它以com.sun開頭*。是特定於sun的,並且不能依賴,如果您不能保證JVM將運行它。

0

應用程序服務器操作可能是此錯誤的原因。 例如在wildfly10 AP中,系統類(如com.sun.management)無法自動加載,您必須定義它才能加載AP。 定義可以通過\模塊\ SYSTEM \層來完成\基\太陽\ JDK \主\ module.xml

<dependencies> 
    <module name="sun.scripting" export="true"/> 
    <system export="true"> 
     <paths> 
     <path name="com/sun/management"/> 
     </path> 
     <exports> 
      <include-set> 
       <path name="META-INF/services"/> 
      </include-set> 
     </exports> 
    </system> 
</dependencies> 

通過添加上述定義中提到的文件wildfly10可以加載類和可以使用COM的方法。 sun.management.OperatingSystemMXBean在運行時。