前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Javac命令使用ct.sym文件约束可使用的类

Javac命令使用ct.sym文件约束可使用的类

作者头像
白凡
发布2018-08-07 17:00:08
1.9K0
发布2018-08-07 17:00:08
举报
文章被收录于专栏:光变光变光变

在JDK6,升级为JDK7或者JDK8的过程中会遇到一些奇怪的问题,简单的介绍一下经典的ClassNotFoundsun.nio.*com.sun.image.codec.jpeg.*等。

背景简介

很多项目使用在JDK6升级到JDK7或者JDK8的过程中,会遇到一些问题。 本文主要介绍一下,在升级过程中,JDK的部分类在Android Studio、Eclipse(以下概称IDE,不包括神器NetBeans)的编译过程中没有提示。 但是使用Maven、Ant、Gradle(这三个工具在下文中概称为打包工具)打包的过程中,会出现错误‘ClassNotFound’‘程序包sun.net.sdp不存在’。 例如:

  • com.sun.image.codec.jpeg.JPEGCodec
  • com.sun.image.codec.jpeg.JPEGEncodeParam
  • jdk.internal.org.objectweb.asm.commons.AdviceAdapter
  • sun.net.sdp.SdpSupport

示例

JDK6可以编译通过、JDK7和JDK8在IDE中可以编译通过,但是使用打包工具,则编译不通过。

import com.sun.image.codec.jpeg.JPEGCodec;
public class TestCtSymJdk6Pass {
    private JPEGCodec jpegCodec;
}
编译尝试

jdk1.6/bin/javac TestCtSymJdk6Pass.java.java

通过,但是会有两个警告。

TestCtSymJdk6Pass.java:1: 警告:com.sun.image.codec.jpeg.JPEGCodec 是 Sun 的专用 API,可能会在未来版本中删除
import com.sun.image.codec.jpeg.JPEGCodec;
                               ^
TestCtSymJdk6Pass.java:3: 警告:com.sun.image.codec.jpeg.JPEGCodec 是 Sun 的专用 API,可能会在未来版本中删除
    private JPEGCodec jpegCodec;
            ^
2 警告

jdk1.7/bin/javac TestCtSymJdk6Pass.java jdk1.8/bin/javac TestCtSymJdk6Pass.java

不通过,两个错误

TestCtSymJdk6Pass.java:1: 错误: 程序包com.sun.image.codec.jpeg不存在
import com.sun.image.codec.jpeg.JPEGCodec;
                               ^
TestCtSymJdk6Pass.java:3: 错误: 找不到符号
    private JPEGCodec jpegCodec;
            ^
  符号:   类 JPEGCodec
  位置: 类 TestCtSymJdk6
2 个错误

JDK6-8都编译不通过

import com.sun.image.codec.jpeg.JPEGCodec;
import sun.net.sdp.SdpSupport;
public class TestCtSymJdk6NotPass {
    private JPEGCodec jpegCodec;
    private SdpSupport sdpSupport;
}

JDK6报错

TestCtSymJdk6NotPass.java:1: 警告:com.sun.image.codec.jpeg.JPEGCodec 是 Sun 的专用 API,可能会在未来版本中删除
import com.sun.image.codec.jpeg.JPEGCodec;
                               ^
TestCtSymJdk6NotPass.java:2: 软件包 sun.net.sdp 不存在
import sun.net.sdp.SdpSupport;
                  ^
TestCtSymJdk6NotPass.java:4: 警告:com.sun.image.codec.jpeg.JPEGCodec 是 Sun 的专用 API,可能会在未来版本中删除
    private JPEGCodec jpegCodec;
            ^
TestCtSymJdk6NotPass.java:5: 找不到符号
符号: 类 SdpSupport
位置: 类 TestCtSymJdk6NotPass
    private SdpSupport sdpSupport;
            ^
2 错误
2 警告

添加编译参数:忽略链接文件

jdk1.6/bin/javac -XDignore.symbol.file TestCtSymJdk6NotPass.java jdk1.7/bin/javac -XDignore.symbol.file TestCtSymJdk6Pass.java jdk1.8/bin/javac -XDignore.symbol.file TestCtSymJdk6Pass.java

以上三条命令都可以正常执行。

原因

在JDK6以及以后的版本,JDK在目录下新增了一个链接文件${JDK_HOME}/lib/ct.sym文件。 在使用javac命令进行编译代码时,默认使用该文件进行编译时class类的检查和链接,而不是使用rt.jar

该文件保存了JDK建议使用的类描述信息。com.sun.*包和sun.*包,以及新的jdk.*都不是Open的API,是JDK内部的私有类,这些类的接口可能在之后的版本变动,也不保证平台移植性。

事实上,JDK提供的Public API,仅有三个包:java.*javax.*org.*。它们是官方支持的公共接口(Official、Supported、Public )。

ct.sym文件是一个zip压缩包,它里面包含了部分rt.jar中的类。

ct.sym文件结构
ct.sym文件结构

ct.sym中的类文件都是简单的空函数,不包含函数体,所以非常小。

JPEGCodec反编译
JPEGCodec反编译

ct.sym中如果没有该类,则会出现ClassNotFound的错误。 比如JDK6中的sun.net.sdp.SdpSupport类。在ct.sym中就没有sun.net.sdp包。

sun.net.sdp
sun.net.sdp

比如JDK7中的com.sun.image.codec.jpeg.JPEGCodec类。

com.sun.image.codec.jpeg
com.sun.image.codec.jpeg

解决方案

方案-1 【建议】

使用JDK开放的接口实现这部分功能。

方案-2 【临时方案】

在编译的时候加入参数-XDignore.symbol.file.

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
    srcdir="src"
    destdir="bin"
    encoding="UTF-8"
    source="1.8"
    target="1.8">
    <compilerarg value="-XDignore.symbol.file"/>  
    <classpath refid="classpath" />
  </javac>
</target>

Gradle

compileJava.options.compilerArgs = [ '-XDignore.symbol.file=true' ]
方案-3 【不建议】

非常粗暴!直接删除ct.sym文件。

PS

PS

神器-NetBeans在IDE中就会提示该错误。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016-12-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景简介
  • 示例
    • 编译尝试
    • 原因
    • 解决方案
      • 方案-1 【建议】
        • 方案-2 【临时方案】
          • 方案-3 【不建议】
          • PS
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档