为什么这段代码编译,但运行时ClassNotFoundException



我有一些使用专有sun.*的代码。操作systemmxbean,所以我对它很小心。

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

然而,当这段代码在IBM JVM上运行时,我得到的不是ClassCastException,而是运行时ClassNotFoundException。如果这个类不可用,为什么这段代码能够编译得很好? JVM对这类有什么影响?

com.sun。包是由sun为sun JVM (hotspot)编写的私有类,不是公共API(即使你的代码证明它们是可访问的)。IBM JVM是一个完全不同的实现,没有它们(因为它们不是任何java/JVM规范的一部分)。我猜它编译得很好,因为你编译的是sun/oracle JDK
要尝试解决这个问题,请尝试转换为

java.lang.management.OperatingSystemMXBean

(这是一个公共API),看看它是否适合你

您正在使用Sun Javac来编译

com.sun.management.OperatingSystemMXBean

,但是要用IBM Java来运行。您的IBM环境将没有任何与Sun相关的内容。com.sun。*类是私有的,应该谨慎使用。

顺便说一句,您可以简单地通过对第三方jar进行编译而不是使用它进行部署来获得此错误。例如,Apache jar或类似的。这不是一个特别与专有jar相关的错误,而是一般的部署问题。

假设你正在编译针对包含com.sun.management.OperatingSystemMXBean的Sun JDK。这不是标准JDK的一部分,这就是为什么您不应该使用它的原因—它不能保证在其他Java系统上存在,并且在您正在使用的IBM JVM中似乎存在。

这与在执行时不存在的任何其他库进行编译相同。

参见:

  • "为什么开发者不应该编写调用'sun'包的程序"

应用程序服务器操作可能是导致此错误的原因。例如,在wildfly10 AP中,不能自动加载像com.sun.management这样的系统类,您必须定义它才能加载AP。定义可以通过modulessystemlayersbasesunjdkmainmodule.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的方法。

您正在使用Sun提供的编译器和JDK(它有这个类),但是运行在不具有这个类的IBM JVM上。通常,如果它以com.sun开头。*是特定于sun的,如果你不能保证JVM会运行它,就不应该依赖。

相关内容

  • 没有找到相关文章

最新更新