我正在尝试使用Maven(3.8.0)创建一个multi-release jar。我们称sun.misc.Unsafe
在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会失败;这是正常的,因为它是a java9 feature。问题在于它在java11中也会失败。
我认为问题是sun.misc
软件包已在java8和java9之间移动。但是,release
标志的用途是,用java8可以很好地编译的代码也应该可以用java11很好地编译。
我误会了如何使用release
标志?我需要手动链接sun.misc
软件包才能使其正常工作吗?
答案 0 :(得分:0)
首先,如评论中所述,不建议我构建多重发行版jar的方式(遵循我提供的链接)。使用nullpointer给出的示例,
我更喜欢使用https://github.com/meterware/multirelease-parent/blob/master/pom.xml
我使用了Maven toolchains,它可以使用不同的JDK进行编译。这样,我的问题就消失了。
第二,为什么我用--release 8
在jdk11中编译时出现编译错误的答案实际上是由khmarbaise指出的,他指向https://stackoverflow.com/a/43103038/296328:
javac提供了两个命令行选项-source和-target,它们可用于分别选择编译器接受的Java语言版本和生成的类文件版本。但是,默认情况下,javac会根据最新版本的平台API进行编译。因此,编译后的程序可能会意外地使用仅在平台的当前版本中可用的API。不管传递给-source和`-target的值如何,此类程序都不能在平台的较旧版本上运行。选项。这是一个长期的可用性难题,因为用户希望通过使用这些选项,他们将获得可以在指定平台版本上运行的类文件。
尽管如此,似乎有解决方法:例如,请参见Maven: javac: source release 1.6 requires target release 1.6。