具有内部软件包的Java9'-release 8'(例如sun.misc.Unsafe)

时间:2018-11-30 15:39:37

标签: java maven multi-release-jar

我正在尝试使用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软件包才能使其正常工作吗?

1 个答案:

答案 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