使用Java14的javac交叉编译至Java7时sun.rmi API编译报错求助
解决Java14交叉编译到Java7时找不到sun.rmi.transport的问题
我完全懂你的需求——做RMI调用插桩必须依赖这些内部API,所以咱们直接说可行的解决方案:
为什么会报错?
当你用javac -release 7时,编译器会严格只暴露Java 7的公共标准API,而sun.rmi.transport属于Oracle JDK的内部私有API,不在-release管控的公共API范围内,所以编译时会提示包不存在。
两种可行的解决办法
方法1:改用-source/-target搭配-bootclasspath
放弃-release参数,转而用传统的-source和-target指定版本,同时必须通过-bootclasspath指定Java 7的rt.jar路径,确保编译时依赖的是Java 7的完整类库(包括内部API):
javac -source 7 -target 7 -bootclasspath /path/to/your/jdk7/jre/lib/rt.jar YourRMIAgentClass.java
⚠️ 重要提醒:一定要加-bootclasspath!如果省略它,编译器会默认用Java14的类库,可能会引入Java7不存在的方法,导致编译出的字节码在Java7环境运行时抛出NoSuchMethodError这类异常。
方法2:保留-release 7并添加--add-exports参数
如果你更倾向于用-release来严格管控公共API的兼容性,可以结合Java9+编译器提供的--add-exports参数,让JDK模块把内部的sun.rmi.transport包开放给你的非模块化代码(属于未命名模块):
javac -release 7 --add-exports jdk.rmi/sun.rmi.transport=ALL-UNNAMED YourRMIAgentClass.java
这个命令的作用是:让jdk.rmi模块把sun.rmi.transport包开放给所有未命名模块,这样编译器就能找到这个内部包,同时-release 7依然会确保你的代码不会使用Java7之后才有的公共API。
额外提示
两种方法都能解决你的编译问题,你可以根据构建流程选择:
- 如果你的环境容易获取Java7的
rt.jar,方法1更贴近传统交叉编译方式; - 如果想利用
-release的严格性,且用的是Java9+编译器(你用的Java14完全符合),方法2更简洁。
内容的提问来源于stack exchange,提问作者Nikem
相关产品推荐
相关产品推荐

