java 9 中介绍的方法是使用编译器目标 java 8 编译的

Method introduced in java 9 is compiled using compiler target java 8

我在 maven 和 eclipse 本身中遇到了一个奇怪的行为。 即使我将我的项目配置为在 Java 1.8 中编译,我也可以编译和 运行 (eclipse) 在 Java 9

中引入的一段代码
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>

有问题的代码行:

LocalTime.ofInstant(cal.toInstant(), cal.getTimeZone().toZoneId());

我在本地使用 Oracle 的 JDK 11 进行编译,并在 eclipse 中 运行ning 没有任何错误。当我使用 openjdk:8-jdk-alpine 将它打包到 docker 容器中时,它会启动,但是当我调用该方法时抛出以下异常:

java.lang.NoSuchMethodError: java.time.LocalTime.ofInstant(Ljava/time/Instant;Ljava/time/ZoneId;)Ljava/time/LocalTime

如何在测试前避免和识别这些情况?我做错了什么,还是构建系统或 JDK11 中的错误?

提前致谢

如果您使用的是 JDK 11,请像这样配置您的 Maven pom.xml

 <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-release-plugin</artifactId>
                <version>2.5.3</version>
            </plugin>
        </plugins>
</build>

source选项指定源代码必须兼容Java8,target选项指定classes应该兼容Java8。但是,你会如果您使用 Java 11 构建,仍然使用 Java 11 class 库进行编译,然后您可能会遇到类似的错误。

有两个很好的解决方案。一种是使用 Maven 工具链插件并使用 Java 8 构建。然后您可以安装多个 Java 版本,Maven 将在每个项目的基础上使用配置的版本。

另一种是使用新的release和testRelease选项。他们将使用给定版本的 API classes 进行构建。只需添加 <release>1.8</release>.