文章目录
- 运行环境
- 一、问题描述
- 二、探究过程
- 三、原因
- 四、解决方式
- 五、总结
- 六、参考链接
运行环境
- 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编译直接报错
二、探究过程
- 首先,该类属于基础类库
rt.jar
包下的类 - 这时候用
-verbose
看看类文件搜索路径是不是出了问题 - 可以得出类文件搜索路径已经包含了
rt.jar
(题外话:网上说CLASSPATH环境变量添加rt.jar
其实多此一举了,至少在Java8是不用加的,之前版本没试过),但是还意外看到这么个输出信息: - 也就是说javac编译时还和
%JAVA_HOME%\lib\ct.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%\jre\lib\rt.jar
,类搜索路径已经有了该路径并且已经 被列入黑名单了,加上去和没加一样
javac -classpath YOUR_PATH\rt.jar TestMimeUtility.java
- 执行结果:
- 建议不要使用
"sun.*"
或"com.sun."
包中的类,避免在项目迁移出现问题,因为它们不是Java API中的一部分 - IDEA,Eclipse工具竟然可以正确!正常!编译这些代码,好歹给个警告啊,就这么纵容吗~
- java代码中调用受限制的JDK API
- Javac命令使用ct.sym文件约束可使用的类
- import com.sun.image.codec.jpeg.*