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



问题

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

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

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

再现问题

为了展示我的问题,我试图编译一个简单的helloworld程序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)

已检查

其他JDK

使用java 11可以工作:

$ 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!

java 8、12和17也是如此。

我也尝试过祖鲁人的分布。

全新安装

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

操作系统信息

以下是关于我的操作系统的一些详细信息:

$ 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

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

我唯一能想到的解释是:

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

  • 你的系统上的一些关键库被微妙地损坏了,或者有一个微妙的错误。

  • 这是一个硬件(主板、CPU、RAM(问题。或者是固件问题。

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

可能值得尝试以另一种方式获取Java 10安装程序的副本,并将其与您正在安装的安装程序进行比较。此外,值得检查下载的校验和(MD5、SHA256(是否与Oracle所说的校验和匹配

如果这些都无济于事,就很难追踪到这一点。国际海事组织不值得付出这样的努力。

我的建议是将Java10从您构建和测试的平台列表中删除。(如果你仍在尝试"支持"。(如果你真的需要用Java 10构建,请使用另一台机器(使用可靠的硬件(,并使用已知的良好下载从头开始重新安装所有东西。


1-不太";锡箔帽";关于它,这种损坏可能是由未检测到的网络传输错误、硬件故障或";深度分组检查";器具重复下载可能会导致相同的损坏。然而,其他人报告他们无法复制这一事实表明这不仅仅是因为下载服务器上的副本损坏

我有理由相信,与系统安全性相关的东西正在参与进来,并破坏了这个过程。

原因1

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

Ille非常奇怪,99%的进程试图以Illegal some description的形式写入消息,但中途被中断

原因2

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

为什么这里甚至提到Unsafe,应该没有任何理由。

自我回答

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

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

在一个alpine中,我安装了git、jdk 10和其他一些开发工具,将源代码作为卷安装,并最终在容器中工作。

目前,我只是使用它来构建和运行软件,就像我使用IntelliJ作为IDE一样。尽管如此,由于它无法正确构建软件,它的Intellisense建议还不够好。我可能最终会进入一个全面的VSCode开发容器。

相关内容

最新更新