快捷搜索: 王者荣耀 脱发

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

运行环境

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

一、问题描述

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编译直接报错

二、探究过程

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

三、原因

于是我网上找到相应的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
<build>
  <plugins>
    <plugin>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>3.6.0</version>
      <configuration>
        <source>1.8</source>
        <target>1.8</target>
        <encoding>UTF-8</encoding>
        <compilerArgs>
          <arg>-XDignore.symbol.file</arg>
        </compilerArgs>
        <fork>true</fork>
      </configuration>
    </plugin>
  </plugins>
</build>
    Ant
<target name="compile">
    <javac
       destdir="${build.dir}"
       encoding="UTF-8"
       source="1.8"
       target="1.8"
       >
   		    <src path="${src.dir}"/>
   		    <compilerarg value="-XDignore.symbol.file"/>  
   		    <classpath refid="classpath" />
     </javac>
</target>

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

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

五、总结

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

六、参考链接

经验分享 程序员 微信小程序 职场和发展