java - java9 '-release 8' 带有内部包(例如 sun.misc.Unsafe)
问题描述
我正在尝试使用 Maven (3.8.0)创建一个多版本 jar 。我们调用sun.misc.Unsafe
which 在 java8 和 java11 中编译得很好。但是,使用编译java11 --release 8
会引发Compilation failure: package sun.misc does not exist
.
以下是如何重现错误:
一个简单的类调用Unsafe
:
public class ChangeableObjects {
sun.misc.Unsafe unsafe;
}
一个简单的pom:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<release>8</release>
</configuration>
</plugin>
</plugins>
</build>
如果我们注释该<release>8</release>
行,它在 java8 和 java11 上运行良好。
如果我们按原样编译代码,java8 会失败;这是正常的,因为它是java9 功能。问题是java11也失败了。
我认为问题是sun.misc
包已在 java8 和 java9 之间移动。但是,该release
标志的目的仍然是使用 java8 编译良好的代码也应该使用 java11 编译良好。
我是否误解了如何使用release
标志?我需要sun.misc
手动链接包以使其工作吗?
解决方案
首先,如评论中所述,不推荐我构建多版本 jar 的方式(按照我提供的链接)。使用 nullpointer 给出的示例,
我更喜欢使用类似https://github.com/meterware/multirelease-parent/blob/master/pom.xml
我使用了Maven 工具链,它可以使用不同的 JDK 进行编译。这样,我的问题就消失了。
其次,为什么我在 jdk11 中编译时出现编译错误的答案--release 8
实际上是由指向https://stackoverflow.com/a/43103038/296328的 khmarbaise 给出的:
javac 提供了两个命令行选项,-source 和 -target,可以分别用来选择编译器接受的 Java 语言版本和生成的类文件的版本。然而,默认情况下,javac 针对最新版本的平台 API 进行编译。因此,编译后的程序可能会意外使用仅在当前平台版本中可用的 API。无论传递给 -source 和 `-target 的值如何,此类程序都无法在旧版本的平台上运行。选项。这是一个长期的可用性痛点,因为用户希望通过使用这些选项,他们将获得可以在指定平台版本上运行的类文件。
Nevertheless, it seems there are workarounds: see Maven: javac: source release 1.6 requires target release 1.6 for example.
推荐阅读
- javascript - 用变量名声明动态局部变量
- javascript - 将 Node.js 输出传递到 Web 界面
- python-3.x - 每次在字符串中找到特定单词时,Python如何打印字符串?
- ios - 在有限的文本字段长度上剪切粘贴的文本
- java - 请求哪些有效,哪些无效
- entity-framework-core-2.1 - 如何在 EF Core 中多次使用 GroupBy
- python - 为什么我的文本解析不正确?
- python - 熊猫如何根据过去的表现选择股票进行投资(动量、趋势跟踪)
- vba - 运行时错误 1004 使用两个索引/匹配时无法获取匹配属性
- c++ - 如何比较两个经过的时间?