我需要使用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
所以问题显然不在你正在编译的代码中。根据堆栈跟踪,它是在加载和初始化编译器时发生的。编译器还没有真正开始编译任何东西。
我唯一能想到的解释是:
>
您的(原始)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开发程序。