2013-01-04 124 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在运行时。