Maven sun专用API警告

本文解决Maven编译时因使用Sun专用API产生的警告问题,通过配置Maven-compiler-plugin忽略警告,最终实现警告显示但编译成功。并提供了Maven-compiler-plugin版本升级后的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如果你用maven编译项目,而且在项目中用了SUN的专用API,你会得到警告信息,然后Maven会报告编译失败,像这个样子:


[ERROR] \workspaces\mvn\javac-warning-test\src\main\java\com\juvenxu\TestJavacWarning.java:[7,32] 警告:sun.misc.BASE64Decoder 是 Sun 的专用
API,可能会在未来版本中删除
[INFO] ————————————————————-
[INFO] BUILD FAILURE


这当然是不合理的,javac只是警告而已,maven凭什么就直接报失败呢?

其实最好的解决办法是避免用到这些SUN专用的API,这些API都有现成的替代品,不过本文要讨论的不是这个,如果你用了某个依赖,该依赖用了SUN专用API,你往往会束手无策。

第一反应是Maven肯定可以提供一些配置点,允许我们忽略这种警告,嗯,当初我也是这么想的,一次培训的时候,一同学问到这个问题,我想当然的回 答,“这个配置javac忽略警告就可以啦,不是Maven的问题”,我自己根本没有试过,这么不负责任的回答我现在想想都脸红。后来和 linux_china 又讨论到这个问题,然后我动手尝试了下,折腾了几乎所有maven-compiler-plugin的配置,到最后竟然是无解!(其实也不算完全无解,至少我们可以配置maven-compiler-plugin忽略编译错误,不过这个解决办法连我自己都觉得太恶心)

无解归无解,至少我找到了这个问题的根本原因, 其实不是我找到的,是Hudson之父Kohsuke Kawaguchi发现的。事情是这样的,Maven的commiter基本都是欧美的,人家的系统基本是英文的,那么他们使用Sun专用API的时候, 遇到的警告信息是英语,以”WARNING“开头的,我们知道,Maven是用maven-compiler-plugin执行编译工作的,而默认情况 maven-compiler-plugin是通过调用javac完成编译的,那么当javac给出”WARNING”的时候,他们根据这个关键字做个 if判断就把事情搞定了。

可是,他们忘了这个世界还有日本中国等国家啦,虽然Kohsuke Kawaguchi基本在美国混,但在日本肯定有不少朋友的,可能他朋友用日文系统遇到这问题了(当然,他自己也可能有日文系统),更不用提广大的中国 IT群众了。之前,如果你在Google搜索“javac maven 警告”,那是大量的信息,可没一篇有真正的解决方法。直到最近我在阿里的技术博客看到一篇文章讲到了这个问题,并给出了一个patch,方法是强制设定javac使用英文的Locale,其实呢,这么做有点暴力,如果用户比较在意本地化的信息怎么办呢?

Kohsuke Kawaguchi的建议显然更合理啦,他说别用javac的输出来判断警告,而是用javac命令行的返回值来判断,这样就能避免这个问题。

方案虽好,但他没有实现,这点可以理解,人家是大牛,而且估计系统都是英文的,没空管这小事。

我基本也在英文系统上跑,实际中也没遇到这问题,也没太大激情去修这个bug,但偶尔的机会和同事Benjamin Bentmann抱怨了几句,无非就是说这个问题困扰大量中国用户啥的,他是Maven 3最主要的commiter,相当给面子啊,没过一周,就修好了,然后让我测试下。

嗯,义不容辞,我就建了个空项目,用了个sun.misc.BASE64Decoder,先简单跑一遍,不出所料报错了。接着我再加入如下的配置:



view plaincopy to clipboardprint?
1.<plugin>
2. <groupId>org.apache.maven.plugins</groupId>
3. <artifactId>maven-compiler-plugin</artifactId>
4. <version>2.3.1</version>
5. <dependencies>
6. <dependency>
7. <groupId>org.codehaus.plexus</groupId>
8. <artifactId>plexus-compiler-javac</artifactId>
9. <version>1.8.1</version>
10. </dependency>
11. </dependencies>
12.</plugin>



这个问题是在plexus-compiler-javac 1.8.1中修复的,因此强制让maven-compiler-plugin依赖这个版本就可以了,照理说maven-compiler-plugin应 该升级一下版本,那样就只要配置插件版本,而不是插件依赖,可是目前新版本的maven-compiler-plugin还没有发布,只能凑活使用上面的 配置啦。

再用maven编译,会看到这样的输出:


[INFO] Compiling 1 source file to D:\workspaces\ws-maven-book\javac-warning-test\target\classes
[WARNING] \workspaces\ws-maven-book\javac-warning-test\src\main\java\com\juvenxu\TestJavacWarning.java:[3,15] 警告:sun.misc.BASE64Decoder 是 Sun 的专
用 API,可能会在未来版本中删除
[WARNING] \workspaces\ws-maven-book\javac-warning-test\src\main\java\com\juvenxu\TestJavacWarning.java:[7,4] 警告:sun.misc.BASE64Decoder 是 Sun 的专
用 API,可能会在未来版本中删除
[WARNING] \workspaces\ws-maven-book\javac-warning-test\src\main\java\com\juvenxu\TestJavacWarning.java:[7,32] 警告:sun.misc.BASE64Decoder 是 Sun 的专
用 API,可能会在未来版本中删除
[INFO] ————————————————————————
[INFO] BUILD SUCCESS
[INFO] ————————————————————————

警告仍然打印出来了,但Build成功了,问题解决啦!

最后的感触是,国内搞开源还需要加勒个油啊!其实这不是什么大的bug,但由于社区中缺少国内的积极分子,才导致这bug一拖再拖没人理,大家一问再问,没人解决。

大家一起加勒个油!

————————– 2010-09-10,教师节,更新 ——————————————————-

maven-compiler-plugin 2.3.2 发布了,因此只需要配置使用该版本就ok了



view plaincopy to clipboardprint?
1.<plugin>
2. <groupId>org.apache.maven.plugins</groupId>
3. <artifactId>maven-compiler-plugin</artifactId>
4. <version>2.3.2</version>
5.</plugin>


或者

01.<plugin>
02. <groupId>org.apache.maven.plugins</groupId>
03. <artifactId>maven-compiler-plugin</artifactId>
04. <version>2.3.2</version>
05. <configuration>
06. <source>1.6</source>
07. <target>1.6</target>
08. <encoding>UTF-8</encoding>
09. <compilerArguments>
10. <verbose />
11. <bootclasspath>${java.home}/lib/rt.jar</bootclasspath>
12. </compilerArguments>
13. </configuration>
14.</plugin>
### 编译错误 'E0020 未定义标识符 sun' 的分析 编译器报告的 `E0020 undefined identifier sun` 错误表明在代码中使用了一个名为 `sun` 的标识符,但在当前作用域内并未找到该标识符的声明或定义。这种类型的错误通常发生在以下几个场景: - 使用了不属于标准库或者特定平台特有的类、方法或变量名称。 - 尝试访问已被移除或重命名的功能。 #### 可能的原因及解决方案 1. **Java 版本差异** 如果项目依赖于某些旧版 Java 中存在但现在已经被废弃或移动到其他包中的 API,可能会遇到此类问题。例如,“Sun”的一些内部工具和实用程序曾经被广泛用于早期版本的应用开发,但随着 Oracle 收购 Sun 并逐步清理这些遗留接口,直接引用它们会导致兼容性问题[^1]。 对策:检查是否有对非公开API(如 com.sun.* 下的内容)进行了硬编码式的调用;考虑替换为官方推荐的标准替代品或是第三方开源库来实现相同功能。 2. **缺少必要的导入语句** 当开发者忘记添加相应的 import 声明时也会触发此警告/报错。确保所有使用的外部资源都已通过合法途径引入工程之中。 3. **环境配置不当** 如提示信息所暗示那样,可能是由于运行环境中只有 JRE 而无JDK 导致无法完成源码级别的构建操作。确认本地安装的是完整的 JDK 发行版而非仅仅包含运行时组件的 JRE,并设置好 PATH 和 JAVA_HOME 环境变量指向正确的路径。 4. **拼写错误或其他逻辑失误** 不小心打错了单词或者是误解了某个框架的工作原理也可能造成同样的现象。仔细审查涉及 “sun” 字样的那一部分代码片段,排查是否存在笔误等情况。 ```java // 正确做法应该是避免直接引用com.sun.* import java.util.*; public class Example { public static void main(String[] args){ // Your Code Here... } } ``` 5. **IDE 插件冲突** 某些情况下 IDE 自带插件可能会影响项目的解析过程进而引发不必要的告警。尝试禁用那些不是特别需要的服务端扩展并重新同步整个工作区看看能否解决问题。 6. **Maven 或 Gradle 构建文件配置有误** 若采用自动化构建工具管理依赖关系,则需核查 pom.xml 或 build.gradle 文件里是否遗漏了关键性的坐标项,特别是当涉及到跨模块协作的时候更要格外留意这一点。 7. **安全策略限制** 部分企业级应用出于安全性考量会严格控制所能加载的字节码范围,这同样会影响到最终产物能否顺利组装起来。查阅相关文档了解如何调整 JVM 启动参数以适应不同的应用场景需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值