提问者:小点点

无法使用openjdk10编译,但可以使用openjdk11和openjdk9编译


我需要使用JDK10来编译一个我必须处理的遗留项目。我知道这是一个生命周期已经结束的短期支持版本。但是在项目更新到较新的Java版本之前,我需要能够在我的开发机器上构建和运行它。

注意:项目确实在其CI管道上正确构建,并且确实在正式生产环境上运行。问题与项目无关,而是与我的机器有关。

我遇到的问题是我不能用JDK10编译任何java代码,但是其他JDK,如8、9、11、12和17可以工作。

为了展示我的问题,我正在尝试编译一个简单的hello world程序Test.java

public class Test {
    public static void main(String[] args) {
        System.out.println("Hello, world!");
    }
}

我使用的是OpenJDK预构建的JDK,但我也尝试过在Zulu发行版中重现这个问题。

我可以始终如一地重现问题:

$ wget https://download.java.net/java/GA/jdk10/10.0.2/19aef61b38124481863b1413dce1855f/13/openjdk-10.0.2_linux-x64_bin.tar.gz
...
2022-10-24 14:10:31 (11,1 MB/s) - ‘openjdk-10.0.2_linux-x64_bin.tar.gz’ saved [204892533/204892533]
$ tar -xzf openjdk-10.0.2_linux-x64_bin.tar.gz
$ jdk-10.0.2/bin/java -version 
openjdk version "10.0.2" 2018-07-17
OpenJDK Runtime Environment 18.3 (build 10.0.2+13)
OpenJDK 64-Bit Server VM 18.3 (build 10.0.2+13, mixed mode)
$ jdk-10.0.2/bin/javac -version                             
javac 10.0.2
$ jdk-10.0.2/bin/javac Test.java
Exception in thread "main" java.lang.ClassFormatError: Ille in class file <Unknown>
    at java.base/jdk.internal.misc.Unsafe.defineAnonymousClass0(Native Method)
    at java.base/jdk.internal.misc.Unsafe.defineAnonymousClass(Unsafe.java:1223)
    at java.base/java.lang.invoke.InnerClassLambdaMetafactory.spinInnerClass(InnerClassLambdaMetafactory.java:320)
    at java.base/java.lang.invoke.InnerClassLambdaMetafactory.buildCallSite(InnerClassLambdaMetafactory.java:188)
    at java.base/java.lang.invoke.LambdaMetafactory.metafactory(LambdaMetafactory.java:317)
    at java.base/java.lang.invoke.CallSite.makeSite(CallSite.java:330)
    at java.base/java.lang.invoke.MethodHandleNatives.linkCallSiteImpl(MethodHandleNatives.java:250)
    at java.base/java.lang.invoke.MethodHandleNatives.linkCallSite(MethodHandleNatives.java:240)
    at jdk.compiler/com.sun.tools.javac.code.Symtab.doEnterClass(Symtab.java:700)
    at jdk.compiler/com.sun.tools.javac.code.Symtab.enterClass(Symtab.java:714)
    at jdk.compiler/com.sun.tools.javac.code.Symtab.enterClass(Symtab.java:275)
    at jdk.compiler/com.sun.tools.javac.code.Symtab.<init>(Symtab.java:485)
    at jdk.compiler/com.sun.tools.javac.code.Symtab.instance(Symtab.java:89)
    at jdk.compiler/com.sun.tools.javac.comp.Attr.<init>(Attr.java:128)
    at jdk.compiler/com.sun.tools.javac.comp.Attr.instance(Attr.java:119)
    at jdk.compiler/com.sun.tools.javac.comp.Annotate.<init>(Annotate.java:109)
    at jdk.compiler/com.sun.tools.javac.comp.Annotate.instance(Annotate.java:84)
    at jdk.compiler/com.sun.tools.javac.jvm.ClassReader.<init>(ClassReader.java:235)
    at jdk.compiler/com.sun.tools.javac.jvm.ClassReader.instance(ClassReader.java:228)
    at jdk.compiler/com.sun.tools.javac.code.ClassFinder.<init>(ClassFinder.java:180)
    at jdk.compiler/com.sun.tools.javac.code.ClassFinder.instance(ClassFinder.java:173)
    at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.<init>(JavaCompiler.java:386)
    at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.instance(JavaCompiler.java:115)
    at jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:291)
    at jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:165)
    at jdk.compiler/com.sun.tools.javac.Main.compile(Main.java:57)
    at jdk.compiler/com.sun.tools.javac.Main.main(Main.java:43)

与java11它的工作原理:

$ wget https://download.java.net/java/GA/jdk11/9/GPL/openjdk-11.0.2_linux-x64_bin.tar.gz
...
2022-10-24 14:08:42 (10,6 MB/s) - ‘openjdk-11.0.2_linux-x64_bin.tar.gz’ saved [187513052/187513052]

$ tar -xzf openjdk-11.0.2_linux-x64_bin.tar.gz
$ jdk-11.0.2/bin/java -version 
openjdk version "11.0.2" 2019-01-15
OpenJDK Runtime Environment 18.9 (build 11.0.2+9)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.2+9, mixed mode)
$ jdk-11.0.2/bin/javac -version                             
javac 11.0.2
$ jdk-11.0.2/bin/javac Test.java
$ jdk-11.0.2/bin/java Test
Hello, world!

它也适用于java9:

$ wget https://download.java.net/java/GA/jdk9/9.0.4/binaries/openjdk-9.0.4_linux-x64_bin.tar.gz
...
2022-10-24 14:31:05 (11,0 MB/s) - ‘openjdk-9.0.4_linux-x64_bin.tar.gz’ saved [206018615/206018615]
$ tar -xzf openjdk-9.0.4_linux-x64_bin.tar.gz
$ jdk-9.0.4/bin/java -version 
openjdk version "9.0.4"
OpenJDK Runtime Environment (build 9.0.4+11)
OpenJDK 64-Bit Server VM (build 9.0.4+11, mixed mode)
$ jdk-9.0.4/bin/javac -version
javac 9.0.4
$ jdk-9.0.4/bin/javac Test.java
$ jdk-9.0.4/bin/java Test     
Hello, world!

java8、12和17也是如此。

我也尝试过祖鲁语发行版。

我尝试过在VirtualBox上安装一个全新的Ubuntu 22.04桌面镜像。问题无法重现。当下载openjdk 10并编译/运行简单的Test.java文件时,它确实按预期工作。它必须与我的机器配置有关。

以下是我OS的一些细节:

$ cat /etc/os-release
PRETTY_NAME="Ubuntu 22.04.1 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.1 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy
$ uname --all                        
Linux Work-Miguel 5.15.0-52-generic #58-Ubuntu SMP Thu Oct 13 08:03:55 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

共3个答案

匿名用户

所以问题显然不在你正在编译的代码中。根据堆栈跟踪,它是在加载和初始化编译器时发生的。编译器还没有真正开始编译任何东西。

我唯一能想到的解释是:

>

  • 您的(原始)Java10下载已损坏1,导致安装了一个微妙损坏的Java编译器;例如编译器中的一个. class文件中的一个翻转。

    系统上的某些关键库被微妙地损坏,或者其中有微妙的bug。

    这是硬件(母板、CPU、RAM)问题。或者固件问题。

    这是被黑客入侵系统的一些奇怪副作用。

    如果这些都没有帮助,就很难追踪到这一点。IMO不值得努力。

    我的建议是从您构建和测试的平台列表中删除Java10。(如果您仍在尝试这样做,请提供“支持”。)如果您真的需要使用Java10构建,请使用不同的机器(具有可靠的硬件),并使用已知的良好下载从头开始重新安装所有内容。

    1-在不太“锡箔帽”的情况下,这种损坏可能是由未检测到的网络传输错误、故障硬件或“深度数据包检测”设备的干扰引起的。重复下载可能会导致同样的损坏。然而,其他人报告他们无法重现这一事实表明,这不仅仅是由于下载服务器上的损坏副本。

  • 匿名用户

    我有理由相信,您的系统上与安全相关的东西正在介入并破坏这个过程。

    原因1

    $ jdk-10.0.2/bin/javac Test.java
    Exception in thread "main" java.lang.ClassFormatError: Ille in class file <Unknown>
    

    Ille非常奇怪,99%的过程试图以非法的一些描述的形式编写消息,但在中间被打断了。

    原因二

    at java.base/jdk.internal.misc.Unsafe.defineAnonymousClass0(Native Method)
        at java.base/jdk.internal.misc.Unsafe.defineAnonymousClass(Unsafe.java:1223)
    

    为什么它在这里甚至提到不安全,不应该有任何理由。

    匿名用户

    对于任何遇到类似问题的人,我都无法解决它。我已经尝试了上面建议的所有解决方案。

    尽管如此,在我们迁移到Java长期支持版本之前,作为一个临时解决方案,我最终使用了一个开发容器。

    我从阿尔卑斯山安装了git、jdk 10和一些其他开发工具,将源代码挂载为卷,并最终在容器内工作。

    目前,我只是用它来构建和运行软件,因为我使用IntelliJ作为IDE。尽管如此,由于它不能正确构建软件,它的智能感知建议还不够好。我最终可能会进入一个成熟的VSCode开发程序。