是否需要特别发布OpenJDK来支持新的Apple M1芯片?
我看到目前有 macOS/OS X 的 JDK 下载,但这些似乎只适用于 x86 处理器。那是对的吗?如果是这样,我在哪里可以下载 M1 的 OpenJDK 版本?
是的。
在此页面上:AdoptOpenJDK 最新版本,您可以从“操作系统”下拉列表中选择“macOS”,然后从“架构”中选择,目前只有 x64,但很快应该有 AArch64 或 ARM64(这些通常是 64 的简码-位臂)。可能,因为苹果无疑在他们的 M1 设计中内置了一堆扩展,而苹果也有自己的。
如果您将操作系统保留为“任意”,您会注意到 aarch64 在那里,这将使您进入 ARM 处理器的 Linux 版本。这(可能)不会在 M1 硬件上的 macOS 上运行,但已经完成了 95% 的工作。
所以:它还没有,但请注意,用于 ARM 的 JDK 已经推出了十多年,虽然 JDK 15 已经放弃了对一系列奇异的操作系统/架构组合(例如Solaris)的支持,但 ARM 开发一直至少保持不变部分相关(即使到目前为止它主要是 Oracle 商业许可产品)。也就是说:创建一个原生运行在M1s上的adoptopenjdk版本不应该是一项艰巨的努力,所以想必它会发生。但是,这是一项开源工作,因此,如果您感到焦虑,请务必阅读并做出贡献:)
直到 2020 年 11 月 10 日,Apple 才提供有关此架构的任何详细信息,除非您为其购买了开发套件盒(带有 A14 芯片的Mac Mini,它不是 M1 芯片,但我猜它足够接近),并签署一个大的保密协议。
通常,如果您挥动 NDA,开源项目将尽可能快地向相反的方向运行,因此,如果您不喜欢这种情况,我认为抱怨采用 openjdk 或其他打包程序和开源是不明智的关于它的项目:)
幸运的是,现在它已经发布,不再需要 NDA。我的假设是,一旦熟悉 OpenJDK 源代码的人拥有基于 M1 的 macOS 系统进行测试,OpenJDK 源代码的 ARM 分支 + macOS x64 版本已经存在的 macOS 位可以相当容易地组合起来,这意味着应该在一个月内发布一个采用openjdk macos-aarch64 的版本。
但是,开源。你没有付钱给他们,你没有合同,他们也不欠你的。如果您希望它更快地进行,请为这项工作捐款或提供拉取请求。
更新:
命令行方法(感谢Homebrew团队以及分支@vladimir-kempik
上其他 openjdk 贡献者的辛勤工作)JEP-391
# Install Homebrew
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Install OpenJDK
brew install openjdk
验证它是否已安装:
$(brew --prefix openjdk)/bin/java --version
验证它是否适用于 arm64 硬件:
file $(brew --prefix openjdk)/bin/java
# /opt/homebrew/opt/openjdk/bin/java: Mach-O 64-bit executable arm64
注意:要在系统范围内安装 openjdk,请按照 Homebrew 提供的屏幕说明进行操作。
注意:在撰写本文时,Homebrew 可能声称它正在 M1 上安装不同版本的 OpenJDK。这是由于stable
Homebrew 中的包装规则造成的,并且会随着时间的推移进行排序。
Azul在其网站的下载部分提供了 OpenJDK 的 macOS ARM 版本。虽然我还没有尝试过它们,但是 Azul 一直是 JDK 开发人员。
解压缩 Azul JDK 后,您必须在其中翻找,直到找到zulu-11.jdk
目录(假设您已下载 JDK 11),然后将其复制到/Library/Java/JavaVirtualMachines
.
您可以使用 sdkman 安装 Java JDK(请参阅sdkman install):
vim .sdkman/etc/config
设置sdkman_rosetta2_compatible=false
(见sdkman 配置)
之后,您将看到与 M1 JDK 兼容的列表:
sdk list java
================================================================================
Available Java Versions
================================================================================
Vendor | Use | Version | Dist | Status | Identifier
--------------------------------------------------------------------------------
Azul Zulu | | 16.0.1 | zulu | | 16.0.1-zulu
| | 11.0.11 | zulu | | 11.0.11-zulu
| | 8.0.292 | zulu | | 8.0.292-zulu
BellSoft | | 16.0.1 | librca | | 16.0.1-librca
| | 11.0.11 | librca | | 11.0.11-librca
| | 8.0.292 | librca | | 8.0.292-librca
Java.net | | 18.ea.3 | open | | 18.ea.3-open
| | 18.ea.2 | open | | 18.ea.2-open
| | 18.ea.1 | open | | 18.ea.1-open
| | 17.ea.28 | open | | 17.ea.28-open
| | 17.ea.27 | open | | 17.ea.27-open
| | 17.ea.26 | open | | 17.ea.26-open
| | 17.ea.25 | open | | 17.ea.25-open
================================================================================
选择一个并使用命令安装它sdk install java IDENTIFIER
,即:
sdk install java 8.0.292-zulu
我正在使用 Azul OpenJDK 和 NetBeans 在新的 Apple M1 芯片上成功开发 Java 应用程序。
配置:
brew install openjdk
就我而言,openjdk
在 Mac M1 上成功安装后,该java
命令仍然不起作用。我修复它
brew info openjdk
然后有一个命令
For the system Java wrappers to find this JDK, symlink it with
sudo ln -sfn /opt/homebrew/opt/openjdk/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk.jdk
执行这个命令和java命令工作
我按照以下步骤操作,并且能够在 Mac M1 上成功运行 JDK 16:
我能够在我的 Mac M1 上安装并成功运行它。
我已经尝试过 Azul JDK 8。
我只想说,虽然 Azul JDK 在 Apple M1 上原生运行并且速度非常快,但仍然存在问题。尤其是一些Java代码需要调用C++代码的时候。
例如,我是一名大数据开发人员。我开始在我的开发工作流程中使用 Azul JDK。但我注意到某些测试在切换后开始失败。例如,当测试写入Parquet / Avro文件时,它会失败。我认为那是因为有一些用 C++ 为 Parquet/Avro 编写的原生东西,它们不是为 M1 编译的。
由于这个特定的原因,我被迫使用速度很慢的非 M1 JDK。那里没有问题。
以下是我在使用 Azul 时遇到的错误示例,而我在使用非 M1 JDK 时没有遇到:
- convert Base64 JSON back to rpo Avro *** FAILED ***
org.apache.spark.SparkException: Job aborted due to stage failure: Task 0 in stage 10.0 failed 1 times, most recent failure: Lost task 0.0 in stage 10.0 (TID 14, localhost, executor driver): org.xerial.snappy.SnappyError: [FAILED_TO_LOAD_NATIVE_LIBRARY] no native library is found for os.name=Mac and os.arch=aarch64
at org.xerial.snappy.SnappyLoader.findNativeLibrary(SnappyLoader.java:331)
at org.xerial.snappy.SnappyLoader.loadNativeLibrary(SnappyLoader.java:171)
at org.xerial.snappy.SnappyLoader.load(SnappyLoader.java:152)
at org.xerial.snappy.Snappy.<clinit>(Snappy.java:47)
at org.apache.avro.file.SnappyCodec.compress(SnappyCodec.java:43)
at org.apache.avro.file.DataFileStream$DataBlock.compressUsing(DataFileStream.java:358)
at org.apache.avro.file.DataFileWriter.writeBlock(DataFileWriter.java:382)
at org.apache.avro.file.DataFileWriter.sync(DataFileWriter.java:401)
at org.apache.avro.file.DataFileWriter.flush(DataFileWriter.java:410)
at org.apache.avro.file.DataFileWriter.close(DataFileWriter.java:433)
at org.apache.avro.mapred.AvroOutputFormat$1.close(AvroOutputFormat.java:170)
at org.apache.spark.internal.io.SparkHadoopWriter.close(SparkHadoopWriter.scala:101)
at org.apache.spark.rdd.PairRDDFunctions$$anonfun$saveAsHadoopDataset$1$$anonfun$12$$anonfun$apply$5.apply$mcV$sp(PairRDDFunctions.scala:1145)
at org.apache.spark.util.Utils$.tryWithSafeFinallyAndFailureCallbacks(Utils.scala:1393)
at org.apache.spark.rdd.PairRDDFunctions$$anonfun$saveAsHadoopDataset$1$$anonfun$12.apply(PairRDDFunctions.scala:1145)
at org.apache.spark.rdd.PairRDDFunctions$$anonfun$saveAsHadoopDataset$1$$anonfun$12.apply(PairRDDFunctions.scala:1125)
at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:87)
at org.apache.spark.scheduler.Task.run(Task.scala:108)
at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:335)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Driver stacktrace:
at org.apache.spark.scheduler.DAGScheduler.org$apache$spark$scheduler$DAGScheduler$$failJobAndIndependentStages(DAGScheduler.scala:1499)
at org.apache.spark.scheduler.DAGScheduler$$anonfun$abortStage$1.apply(DAGScheduler.scala:1487)
at org.apache.spark.scheduler.DAGScheduler$$anonfun$abortStage$1.apply(DAGScheduler.scala:1486)
at scala.collection.mutable.ResizableArray$class.foreach(ResizableArray.scala:59)
at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:48)
at org.apache.spark.scheduler.DAGScheduler.abortStage(DAGScheduler.scala:1486)
at org.apache.spark.scheduler.DAGScheduler$$anonfun$handleTaskSetFailed$1.apply(DAGScheduler.scala:814)
at org.apache.spark.scheduler.DAGScheduler$$anonfun$handleTaskSetFailed$1.apply(DAGScheduler.scala:814)
at scala.Option.foreach(Option.scala:257)
at org.apache.spark.scheduler.DAGScheduler.handleTaskSetFailed(DAGScheduler.scala:814)
...
Cause: org.xerial.snappy.SnappyError: [FAILED_TO_LOAD_NATIVE_LIBRARY] no native library is found for os.name=Mac and os.arch=aarch64
at org.xerial.snappy.SnappyLoader.findNativeLibrary(SnappyLoader.java:331)
at org.xerial.snappy.SnappyLoader.loadNativeLibrary(SnappyLoader.java:171)
at org.xerial.snappy.SnappyLoader.load(SnappyLoader.java:152)
at org.xerial.snappy.Snappy.<clinit>(Snappy.java:47)
at org.apache.avro.file.SnappyCodec.compress(SnappyCodec.java:43)
at org.apache.avro.file.DataFileStream$DataBlock.compressUsing(DataFileStream.java:358)
at org.apache.avro.file.DataFileWriter.writeBlock(DataFileWriter.java:382)
at org.apache.avro.file.DataFileWriter.sync(DataFileWriter.java:401)
at org.apache.avro.file.DataFileWriter.flush(DataFileWriter.java:410)
at org.apache.avro.file.DataFileWriter.close(DataFileWriter.java:433)
如您所见,它说: Cause: org.xerial.snappy.SnappyError: [FAILED_TO_LOAD_NATIVE_LIBRARY] no native library is found for os.name=Mac and os.arch=aarch64
我用谷歌搜索了这个问题,不幸的是,他们说本机库是为更高版本的Spark编译的。
这让我非常沮丧,我现在想要一台 Windows 笔记本电脑,哈哈。在 M1 芯片上运行 Intel JDK 有时会很慢,我不希望这样。
当心!
更新: 他们发布了支持 M1 的新版本库,我在项目中更新了它们,一切正常,感谢上帝。有时这些“本机代码错误”会以不同的异常表现出来,这是我必须处理的额外 PITA,而我在 Windows 笔记本电脑上的同事不需要处理它。错误有时可能有点不清楚,但如果您在错误日志中看到有关本机代码的内容,或者诸如“jna”或“jni”之类的词,那么这是 M1 芯片问题。
请访问 Azul 站点并下载 .dmg 文件:
https://www.azul.com/downloads/zulu-community/?os=macos&architecture=arm-64-bit&package=jdk
这将被放置在一个库中,一旦 IntelliJ IDEA 识别它,它应该可以很好地运行。
这不仅仅是 JEP-391。
有一个预览分支,https://github.com/openjdk/jdk-sandbox/tree/JEP-391-branch,可以在 Intel Mac 或直接在 ARM 上使用交叉编译构建 JDK 16 early-access (EA)苹果电脑。它运行良好。
您可以从以下位置下载 Liberica JDK:
https://bell-sw.com/pages/downloads/?os=macOS&architecture=ARM
在IntelliJ IDEA for M1 中,JetBrains Runtime 也是原生的 (ARM64)。
Microsoft 和Azul似乎是JEP 391与 Windows 端口 (JEP 388) 结合的主要推动者。他们有一个单独的 GitHub 存储库,实际上有一个macOS-aarch64 的EA版本。
我不确定与 OpenJDK 存储库的确切关系。
以下是安装 Oracle JDK 8 并从Rosetta运行它的步骤- https://www.oracle.com/in/java/technologies/javase/javase-jdk8-downloads.html
您可以通过打开终端并输入以下内容来验证它是否有效:
java -version