javac编译错误: 程序包 com.sun.xxx 不存在

文章目录

  • 运行环境
  • 一、问题描述
  • 二、探究过程
  • 三、原因
  • 四、解决方式
  • 五、总结
  • 六、参考链接

运行环境

  • Java版本:java version “1.8.0_281”
  • 操作系统:Windows 10

一、问题描述

  • 问题来源于编译项目代码,其中有一个类引用了com.sun下的类
com.sun.xml.internal.messaging.saaj.packaging.mime.internet.MimeUtility;
  • 单独写一个测试类TestMimeUtility.java研究下…
import com.sun.xml.internal.messaging.saaj.packaging.mime.internet.MimeUtility;

public class TestMimeUtility {
    public static void main(String[] args) {
        System.out.println("TestMimeUtility");
        System.out.println(MimeUtility.ALL);
    }
}
  • 使用javac编译直接报错

javac编译错误: 程序包 com.sun.xxx 不存在_第1张图片

二、探究过程

  • 首先,该类属于基础类库 rt.jar 包下的类
    javac编译错误: 程序包 com.sun.xxx 不存在_第2张图片
  • 这时候用 -verbose 看看类文件搜索路径是不是出了问题
    javac编译错误: 程序包 com.sun.xxx 不存在_第3张图片
  • 可以得出类文件搜索路径已经包含了rt.jar(题外话:网上说CLASSPATH环境变量添加rt.jar其实多此一举了,至少在Java8是不用加的,之前版本没试过),但是还意外看到这么个输出信息:
    javac编译错误: 程序包 com.sun.xxx 不存在_第4张图片
  • 也就是说javac编译时还和%JAVA_HOME%\lib\ct.sym这个文件有关系,于是我用相应解压缩软件打开,发现并没有com.sun.xml包,所以说未找到这个类的原因来自于这里,问题定位到ct.sym文件
    javac编译错误: 程序包 com.sun.xxx 不存在_第5张图片

三、原因

于是我网上找到相应的issue查了下原因,大致如下:

  • 在JDK6以及以后的版本【版本我没有去确认】,JDK在目录下新增了一个链接文件${JDK_HOME}/lib/ct.sym。在使用javac命令进行编译代码时,默认使用该文件进行编译时class类的检查和链接,而不是直接使用%JAVA_HOME%/jre/lib/rt.jar
  • 该文件保存了JDK建议使用的类描述信息。com.sun.*包和sun.*包,以及新的jdk.*都不是Open的API,这些类的接口可能在之后的版本变动,也不保证平台移植性。【编译时会有警告或者是找不到类】
  • 事实上,JDK提供的Public API,仅有三个包:java.*javax.*org.*。它们是官方支持的公共接口

四、解决方式

1. 如果是自己写的类依赖了这些类,建议进行重写替换,避免后续系统升级给其他维护人员带来麻烦!
2. 如果一定要编译,可以在编译时添加忽略链接文件选项:-XDignore.symbol.file

  • javac

javac -XDignore.symbol.file TestMimeUtility.java

  • Maven

  
    
      maven-compiler-plugin
      3.6.0
      
        1.8
        1.8
        UTF-8
        
          -XDignore.symbol.file
        
        true
      
    
  

  • Ant

    
   		    
   		      
   		    
     

3.类文件搜索路径添加另一个rt.jar的路径

  • 网上好像挺多人用这个方式的,直接把rt.jar替换掉,但其实知道怎么回事后还不如直接使用 -XDignore.symbol.file 选项呢…
  • 另外要注意的是另一个rt.jar路径不能是%JAVA_HOME%\jre\lib\rt.jar,类搜索路径已经有了该路径并且已经 被列入黑名单了,加上去和没加一样
javac -classpath YOUR_PATH\rt.jar  TestMimeUtility.java
  • 执行结果:

javac编译错误: 程序包 com.sun.xxx 不存在_第6张图片

五、总结

  • 建议不要使用 "sun.*""com.sun."包中的类,避免在项目迁移出现问题,因为它们不是Java API中的一部分
  • IDEA,Eclipse工具竟然可以正确!正常!编译这些代码,好歹给个警告啊,就这么纵容吗~

六、参考链接

  • java代码中调用受限制的JDK API
  • Javac命令使用ct.sym文件约束可使用的类
  • import com.sun.image.codec.jpeg.*

你可能感兴趣的:(Java,java,javac,jdk)