Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Javac命令使用ct.sym文件约束可使用的类

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

作者头像
白凡
发布于 2018-08-07 09:00:08
发布于 2018-08-07 09:00:08
2.1K00
代码可运行
举报
文章被收录于专栏:光变光变
运行总次数:0
代码可运行

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

背景简介

很多项目使用在JDK6升级到JDK7或者JDK8的过程中,会遇到一些问题。 本文主要介绍一下,在升级过程中,JDK的部分类在Android StudioEclipse(以下概称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中可以编译通过,但是使用打包工具,则编译不通过。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import com.sun.image.codec.jpeg.JPEGCodec;
public class TestCtSymJdk6Pass {
    private JPEGCodec jpegCodec;
}
编译尝试

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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

不通过,两个错误

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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都编译不通过

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import com.sun.image.codec.jpeg.JPEGCodec;
import sun.net.sdp.SdpSupport;
public class TestCtSymJdk6NotPass {
    private JPEGCodec jpegCodec;
    private SdpSupport sdpSupport;
}

JDK6报错

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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中如果没有该类,则会出现ClassNotFound的错误。 比如JDK6中的sun.net.sdp.SdpSupport类。在ct.sym中就没有sun.net.sdp包。

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

解决方案

方案-1 【建议】

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

方案-2 【临时方案】

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

Maven

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
compileJava.options.compilerArgs = [ '-XDignore.symbol.file=true' ]
方案-3 【不建议】

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

PS

PS

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

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

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

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

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
100 行 Java 代码实现一个表情包生成器!
在同学群里,每次她们聊天都能带上炫酷的表情,我百思不得其解她们是从哪里获得的这些表情。最后通过一番沟通得知,她们使用的是讯飞输入法。作为一个程序员,我咽不下这口气,我得自己实现一个表情自动生成器,于是就自己动手做了一个 demo,没想到还真给搞定了~
业余草
2020/12/07
9470
100 行 Java 代码实现一个表情包生成器!
【Java】已解决:java.lang.NoClassDefFoundError: com/sun/image/codec/jpeg/ImageFormatException
在Java开发中,NoClassDefFoundError是一类常见的运行时错误。本文将聚焦于java.lang.NoClassDefFoundError: com/sun/image/codec/jpeg/ImageFormatException,深入分析其背景、原因、错误示例和正确的解决方案,并提供相关的注意事项,帮助开发者避免类似问题的发生。
屿小夏
2025/05/24
630
JS引擎(2):Java平台上JavaScript引擎—Rhino/Nashorn概述
Rhino和Nashorn都是用Java实现的JavaScript引擎。它们自身都是普通的Java程序,运行在JVM上
周陆军博客
2023/04/09
3.4K0
原来注解是这么实现的啊!
Java注解是在JDK1.5被引入的技术,配合反射可以在运行期间处理注解,配合apt tool可以在编译器处理注解,在JDK1.6之后,apt tool被整合到了javac里面。
Java识堂
2021/02/05
5980
原来注解是这么实现的啊!
彩色照片转换为黑白照片(Color image converted to black and white picture)
This blog will be talking about the color image converted to black and white picture.
Hongten
2018/09/13
1.1K0
彩色照片转换为黑白照片(Color image converted to black and white picture)
使用 Image.SCALE_SMOOTH算法进行图片压缩
有一只柴犬
2024/01/25
3210
使用 Image.SCALE_SMOOTH算法进行图片压缩
Java之二维码工具类
<dependency>     <groupId>com.google.zxing</groupId>     <artifactId>core</artifactId>     <version>3.3.0</version> </dependency>     <!-- https://mvnrepository.com/artifact/com.google.zxing/javase --> <dependency>     <groupId>com.google.zxing</groupId>     <artifactId>javase</artifactId>     <version>3.3.0</version>
周杰伦本人
2023/10/12
3660
Java之二维码工具类
开发小技巧备忘
今天一段时间一直在忙工作上的事,并没有系统地学习研究某一个具体的问题,但回顾这一个月的工作,发现还是有一些经验可以记录一下的。但这些经验没法系统地整理起来,因此只能算是开发中的杂项了。 杂项一:httpclient典型用法 基础用法 HttpClient httpClient = HttpClientBuilder.create().build(); HttpPost postMethod = null; try { postMethod = new HttpPost(reqUrl); p
jeremyxu
2018/05/10
6940
回敬Python蹭女神热度助发朋友圈,Java实现头像分成九宫图,再生成拼图头像
于是,我点开文章后,大概看了下文章的意思,其实就是把一个图片分成九宫图,即拼图的碎片,既然Python都能实现,作为回应,java必然也是可以做到的。
软件测试君
2020/07/31
8120
回敬Python蹭女神热度助发朋友圈,Java实现头像分成九宫图,再生成拼图头像
深入理解Java虚拟机–javac命令[通俗易懂]
javac命令用于将 .java 源文件编译成 .class 字节码文件,在windows命令行中使用”javac -help”命令查看其用法:
全栈程序员站长
2022/09/02
1.5K0
聊聊如何通过APT+AST来实现AOP功能
如果有使用过spring aop功能的小伙伴,应该都会知道spring aop主要是通过动态代理在运行时,对业务进行切面拦截操作。今天我们就来实现一下如何通过APT+AST在编译期时实现AOP功能。不过在此之前先科普一下APT和AST相关内容
lyb-geek
2023/04/25
5090
聊聊如何通过APT+AST来实现AOP功能
一文带你读懂String类源码
String 是日常开发非常频繁的类,此外我们常用的操作还有字符串连接操作符等等。String对象是不可变的,查看JDK文档,我们不难发现String类的每个修改值的方法,其实都是创建了一个新的String对象,以包含修改后的字符串内容。
后台技术汇
2022/05/28
3420
一文带你读懂String类源码
Java HelloWorld 學習
将常量压入栈的指令 aconst_null 将null对象引用压入栈 iconst_m1 将int类型常量-1压入栈 iconst_0 将int类型常量0压入栈 iconst_1 将int类型常量1压入栈 iconst_2 将int类型常量2压入栈 iconst_3 将int类型常量3压入栈 iconst_4 将int类型常量4压入栈 iconst_5 将int类型常量5压入栈 lconst_0 将long类型常量0压入栈 lconst_1 将long类型常量1压入栈 fconst_0 将float类型常量0压入栈 fconst_1 将float类型常量1压入栈 dconst_0 将double类型常量0压入栈 dconst_1 将double类型常量1压入栈 bipush 将一个8位带符号整数压入栈 sipush 将16位带符号整数压入栈 ldc 把常量池中的项压入栈 ldc_w 把常量池中的项压入栈(使用宽索引) ldc2_w 把常量池中long类型或者double类型的项压入栈(使用宽索引) 从栈中的局部变量中装载值的指令 iload 从局部变量中装载int类型值 lload 从局部变量中装载long类型值 fload 从局部变量中装载float类型值 dload 从局部变量中装载double类型值 aload 从局部变量中装载引用类型值(refernce) iload_0 从局部变量0中装载int类型值 iload_1 从局部变量1中装载int类型值 iload_2 从局部变量2中装载int类型值 iload_3 从局部变量3中装载int类型值 lload_0 从局部变量0中装载long类型值 lload_1 从局部变量1中装载long类型值 lload_2 从局部变量2中装载long类型值 lload_3 从局部变量3中装载long类型值 fload_0 从局部变量0中装载float类型值 fload_1 从局部变量1中装载float类型值 fload_2 从局部变量2中装载float类型值 fload_3 从局部变量3中装载float类型值 dload_0 从局部变量0中装载double类型值 dload_1 从局部变量1中装载double类型值 dload_2 从局部变量2中装载double类型值 dload_3 从局部变量3中装载double类型值 aload_0 从局部变量0中装载引用类型值 aload_1 从局部变量1中装载引用类型值 aload_2 从局部变量2中装载引用类型值 aload_3 从局部变量3中装载引用类型值 iaload 从数组中装载int类型值 laload 从数组中装载long类型值 faload 从数组中装载float类型值 daload 从数组中装载double类型值 aaload 从数组中装载引用类型值 baload 从数组中装载byte类型或boolean类型值 caload 从数组中装载char类型值 saload 从数组中装载short类型值 将栈中的值存入局部变量的指令 istore 将int类型值存入局部变量 lstore 将long类型值存入局部变量 fstore 将float类型值存入局部变量 dstore 将double类型值存入局部变量 astore 将将引用类型或returnAddress类型值存入局部变量 istore_0 将int类型值存入局部变量0 istore_1 将int类型值存入局部变量1 istore_2 将int类型值存入局部变量2 istore_3 将int类型值存入局部变量3 lstore_0 将long类型值存入局部变量0 lstore_1 将long类型值存入局部变量1 lstore_2 将long类型值存入局部变量2 lstore_3 将long类型值存入局部变量3 fstore_0 将float类型值存入局部变量0 fstore_1 将float类型值存入局部变量1 fstore_2 将float类型值存入局部变量2 fstore_3 将float类型值存入局部变量3 dstore_0 将double类型值存入局部变量0 dstore_1 将double类型值存入局部变量1 dstore_2 将double类型值存入局部变量2 dstore_3 将double类型值存入局部变量3 astore_0 将引用类型或returnAddress类型值存入局部变量0 astore_1 将引用类型或returnAddress类型值存入局部变量1 astore_2 将引用类型或returnAddress类型值存入局部变量2 astore_3 将引用类型或returnAddress类型值
一个会写诗的程序员
2020/09/07
6980
Java HelloWorld 學習
每日一博 - 动态编译报错 ClassNotFoundException: com.sun.tools.javac.processing.JavacProcessingEnvironment
错误 java.lang.ClassNotFoundException: com.sun.tools.javac.processing.JavacProcessingEnvironment 表示Java运行时环境无法找到名为 com.sun.tools.javac.processing.JavacProcessingEnvironment 的类。这个类是Java编译器API的一部分,它是用于访问编译器的内部处理环境的。
小小工匠
2024/01/06
1.1K0
每日一博 - 动态编译报错 ClassNotFoundException: com.sun.tools.javac.processing.JavacProcessingEnvironment
JVM
创建相同包目录 mkdir -p 目录 复制文件 cp 文件 指定目录
瑞新
2022/05/09
5460
JVM
Java奇淫巧技之Lombok
高爽
2017/12/28
1.1K0
Java奇淫巧技之Lombok
夯实Java基础系列20:从IDE的实现原理聊起,谈谈那些年我们用过的Java命令
本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看
Java技术江湖
2019/10/08
1.7K0
Fastjson 1.2.47 远程命令执行漏洞
Fastjson是阿里巴巴公司开源的一款json解析器,其性能优越,被广泛应用于各大厂商的Java项目中。fastjson于1.2.24版本后增加了反序列化白名单,而在1.2.48以前的版本中,攻击者可以利用特殊构造的json字符串绕过白名单检测,成功执行任意命令。
黑白天安全
2021/06/16
2.3K0
Fastjson 1.2.47 远程命令执行漏洞
Java基础14:离开IDE,使用java和javac构建项目
这是一位阿里 Java 工程师的技术小站,作者黄小斜,专注 Java 相关技术:SSM、SpringBoot、MySQL、分布式、中间件、集群、Linux、网络、多线程,偶尔讲点Docker、ELK,同时也分享技术干货和学习经验,致力于Java全栈开发!(关注公众号后回复”资料“即可领取 3T 免费技术学习资源以及我我原创的程序员校招指南、Java学习指南等资源)
程序员黄小斜
2019/04/07
1.6K0
Java 给图片加 文字水印
package com.fh.util; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Image; import java.awt.image.BufferedImage; import java.io.File; import javax.imageio.ImageIO; //import java.io.FileOutputStream; //import com.su
FHAdmin
2021/06/15
3.9K0
推荐阅读
相关推荐
100 行 Java 代码实现一个表情包生成器!
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验