适用于 Apple M1 芯片的 Java/JDK

Posted

技术标签:

【中文标题】适用于 Apple M1 芯片的 Java/JDK【英文标题】:Java/JDK for the Apple M1 chip 【发布时间】:2021-02-23 12:27:13 【问题描述】:

是否需要特别发布OpenJDK 来支持新的Apple M1 芯片?

我看到目前有适用于 macOS/OS X 的 JDK 下载,但这些似乎只适用于 x86 处理器。那是对的吗?如果是这样,我在哪里可以下载 M1 的 OpenJDK 版本?

【问题讨论】:

我关注了 JDK 安装的 youtube 视频,youtube.com/watch?v=pZjGom2qTEA。它正在工作。 原生 Apple/Arm64 版本现在可在 brew 上使用,因此您应该可以只使用 brew install java,前提是您在不使用 Rosetta 2 的情况下原生安装 brew 【参考方案1】:

是的。

在此页面上:AdoptOpenJDK Latest Releases 您可以从“操作系统”下拉列表中选择“macOS”,然后从“架构”中选择,目前只有 x64,但很快应该有 AArch64 或 ARM64(这些通常是简码对于 64 位 ARM)。可能,因为 Apple 无疑在其 M1 设计中内置了一堆扩展,而 Apple 也有自己的。

如果您将操作系统保留为“任意”,您会注意到其中包含 aarch64,这将使您进入适用于 ARM 处理器的 Linux 版本。这(可能)不会在 M1 硬件上的 macOS 上运行,但已经完成了 95% 的工作。

所以:它还没有,但请注意,用于 ARM 的 JDK 已经推出了十多年,虽然 JDK 15 已经放弃了对一系列奇异的操作系统/架构组合(例如 Solaris)的支持,但 ARM 开发始终保持至少部分相关(即使到目前为止它主要是 Oracle 商业许可产品)。也就是说:创建一个原生在M1s上运行的adoptopenjdk版本不应该是一项艰巨的努力,所以想必它会发生。但是,这是一项开源工作,因此,如果您感到焦虑,请务必阅读并做出贡献:)

直到 2020 年 11 月 10 日,Apple 才提供有关此架构的任何详细信息,除非您为它购买了开发套件盒(Mac Mini,带有 A14 芯片,不是 M1 芯片,但我想足够接近),并签了个大NDA。

作为一项规则,如果你挥动 NDA,开源项目将尽可能快地向相反的方向运行,所以如果你不喜欢这种情况,我认为抱怨采用 openjdk 或其他打包程序是不明智的以及关于它的开源项目:)

幸运的是,现在它已经发布,不再需要 NDA。我的假设是,一旦熟悉 OpenJDK 源代码的人拥有基于 M1 的 macOS 系统进行测试,OpenJDK 源代码的 ARM 分支 + macOS x64 版本中已经存在的 macOS 位可以很容易地组合起来,这意味着adoptopenjdk macos-aarch64 版本应该会在一个月内发布。

但是,开源。你没有付钱给他们,你没有合同,他们也不欠你的。如果您希望它更快地进行,请为这项工作捐款或提供拉取请求。

更新:

Azul's M1 OpenJDK builds Microsoft(是的,真的)GitHub source repo 用于在 AArch64 上为 macOS 提供早期访问 OpenJDK16 版本。请注意,微软一直致力于 AArch64 的 OpenJDK 分支(用于基于 ARM 的 Windows 10),这可以追溯到:很多艰苦的工作已经完成。

【讨论】:

谢谢! ,仅供参考bugs.openjdk.java.net/browse/JDK-8251280 运行 gradle 不适用于 Microsoft 的预览版。在这里举报github.com/openjdk/aarch64-port/issues/8 这篇文章说“很快”,但已经 9 个月了,采用链接并没有比最初发布时更有帮助。 aarch64 的解释很有帮助,因为对于大多数 M1 用户来说,这些术语是同义词并不明显,但是第一个链接仍然没有帮助,应该在 Adoptium 团队能够产生 M1 工件之前将其删除。 请注意,OpenJDK 项目已移至 Eclipse Fondation,现在新网站为:https://adoptium.net “Soonish”终于来了。 Adoptium 项目最近发布了他们的第一个 Java 17 M1 版本。adoptium.net/…。【参考方案2】:

命令行方法(感谢Homebrew 团队以及@vladimir-kempikJEP-391 分支上其他openjdk 贡献者的辛勤工作)

# 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。这是由于 Homebrew 中的stable 打包规则,并且会随着时间的推移进行排序。

【讨论】:

这是正确答案 这也适用于 java 11,没有任何问题 brew install openjdk@11file $(brew --prefix openjdk@11)/bin/java - Apple MacBook Pro 2021 - M1 Pro(10 核) - 对我来说,使用自制软件是比其他方法更可取的选择跨度> OpenJDK 17 是第一个正式支持 M1 架构的 java 版本 $(brew --prefix openjdk)/bin/java --version.这可行,但 java --version 不起作用...我想我需要设置 java home 是吗? @JustinFuruness 如果JAVA_HOME 是硬性要求,您可以执行export JAVA_HOME="$(brew --prefix openjdk)/libexec/openjdk.jdk/Contents/Home" 尽管brew info openjdk 包含配置系统以找到它的说明,引用:For the system Java wrappers to find this JDK, symlink it with...(确切的命令是特定的到您的系统,由 Homebrew 打印)。【参考方案3】:

Azul 在其网站的 下载 部分提供 macOS ARM 版本的 OpenJDK。虽然我还没有尝试过,但 Azul 一直是 JDK 开发人员。

解压 Azul JDK 后,您必须在其中翻找,直到找到 zulu-11.jdk 目录(假设您已下载 JDK 11),然后将其复制到 /Library/Java/JavaVirtualMachines

【讨论】:

我下载了他们的 .dmg 并且它可以正常工作——无需复制 *.dmg 版本不需要复制,您可以下载 *.zip 版本【参考方案4】:

您可以使用 sdkman 安装 Java JDK(参见 sdkman install):

vim .sdkman/etc/config

设置sdkman_rosetta2_compatible=false(见sdkman config)

之后,您将看到与 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

【讨论】:

"compatbile"sdkman_rosetta2_compatbile)看起来像是 "compatible" 的拼写错误(真正的拼写错误)。你确定它是这样拼写的吗? @PeterMortensen 你是对的,这是我的回答中的一个错字,我修复了它【参考方案5】:

现在,Oracle 的 OpenJDK 17 支持 Apple M1 芯片。 JEP 391 的状态是关闭 & delivered。

您可以从official website 下载免费的 macOS/AArch64 开源版本的 JDK 版本 17。

【讨论】:

【参考方案6】:

我正在使用 Azul OpenJDK 和 NetBeans 在新的 Apple M1 芯片上成功开发 Java 应用程序。

配置:

zulu16.0.65-ea-jdk16.0.0-ea.24-macos_aarch64 NetBeans 12.1 和 Maven。

【讨论】:

您好,请问 Jenkins 是否工作正常,您是如何获得对 maven 的支持的?谢谢 您好,现在还处于早期阶段,还有很多不支持芯片的开源包。我目前还没有安装 Jenkins,到目前为止我尝试过的 maven 包都没有出现问题,毫无疑问会有一些问题。我目前和大多数人一样只是在探索; 你在使用 docker 吗?我找不到 arm64 的 Azul OpenJDK docker 映像。 开发环境我没用过Docker。 安装 Azul OpenJDK 后,如何运行 jnlp 文件?似乎不可能,因为没有 javaws 二进制文件?【参考方案7】:
brew install openjdk

就我而言,在 Mac M1 上成功安装 openjdk 后,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命令工作

【讨论】:

【参考方案8】:

按照以下步骤,我能够在 Mac M1 上成功运行 JDK 16:

    转到“Oracle.com” 转到产品软件Java 点击“立即下载 Java” 点击“JDK下载” 选择“macOS 安装程序” 安装 JDK 尝试使用任何示例 Java 程序,这应该适合您。

我能够在我的 Mac M1 上安装并成功运行它。

【讨论】:

哪个型号? MacBook Pro? 我有带 M1 芯片的 Mac air【参考方案9】:

请访问 Azul 网站并下载 .dmg 文件:

https://www.azul.com/downloads/zulu-community/?os=macos&architecture=arm-64-bit&package=jdk

这将被放置在一个库中,一旦 IntelliJ IDEA 识别它,就可以运行了。

【讨论】:

【参考方案10】:

我已经尝试过 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 的新版本库,我在项目中更新了它们,一切正常,感谢上帝。有时这些“本机代码错误”会以不同的异常表现出来,这是额外的 P.I.T.A.我必须处理,而我在 Windows 笔记本电脑上的同事不需要处理它。错误有时可能有点不清楚,但如果您在错误日志中看到有关本机代码的内容,或者诸如“jna”或“jni”之类的字眼,那么这是 M1 芯片问题。

【讨论】:

如果某个特定的库具有本机绑定并且不提供aarch64 (ARM64) 端口,您应该向他们提交错误报告。 Java 开发人员需要与他们所依赖的项目合作,以确保添加 ARM64 支持,尤其是当您依赖志愿者主导的项目时。所以我认为不要“小心”,而是“要有耐心”,或者更好......“积极主动”并发送这些项目pull requests,或者在你的情况下,update your library。 你想让我为每个有这个问题的图书馆做这个吗?人们在使用这个 jdk 时应该非常小心,因为他们可能会浪费数小时甚至数天时间来试图理解为什么他们的项目没有被构建并在谷歌上搜索由此产生的错误。只使用英特尔 JDK 会更容易。 是的,这绝对是社区的义务,它依赖于开源库来帮助提交错误报告并跟踪有效的方法。这就是开源的工作方式。用户或开发人员找出问题所在,参与其中,让合适的人知道并提供帮助。在您的错误的特定情况下,提供了一个修复链接。记录此过程将使其他人受益。更新这种依赖关系可能并不明显,并且会因项目而异,但为其他人记录这一点将有助于社区向前发展。开源是众包的努力。 :// 在您的特定用例中,一个很好的起点是询问如何让您的工具在 M1 CPU 上本地工作并交叉链接此错误报告的问题(例如关于堆栈溢出)。尽管我们可能不完全了解我们所依赖的工具的基础,但在涉及开源库时,为自己和他人设定期望是非常重要的。 M1 CPU 暴露了很多需要更新的原生项目。幸运的是,大多数已经打了补丁,但是将这些补丁加入我们的项目是在这样的网站上提问的一个很好的理由。 :) 如果有人关心,kafka-clients:3.0.0 我也遇到了同样的问题。我排除了随附的snappy 版本,并升级到了最新版本 - 支持 M1 臂【参考方案11】:

不仅仅是 JEP-391。

有一个预览分支,https://github.com/openjdk/jdk-sandbox/tree/JEP-391-branch,可以在 Intel Mac 上或直接在 ARM Mac 上使用交叉编译构建 JDK 16 early-access (EA)。而且运行良好。

【讨论】:

【参考方案12】:

Microsoft 和 Azul 似乎是 JEP 391 与 Windows 端口 (JEP 388) 结合使用的主要推动者。他们有 a separate GitHub repository,实际上有一个用于 macOS-aarch64 的 EA 版本。

我不确定与 OpenJDK 存储库的确切关系。

【讨论】:

【参考方案13】:

您可以从以下位置下载 Liberica JDK:

https://bell-sw.com/pages/downloads/?os=macOS&architecture=ARM

在 M1 的 IntelliJ IDEA 中,JetBrains Runtime 也是本机 (ARM64)。

【讨论】:

IDEA jre 的路径示例:/Users/o_o/Library/Application Support/JetBrains/Toolbox/apps/PyCharm-P/ch-0/211.7628.24/PyCharm.app/Contents/jbr/Contents/Home【参考方案14】:

以下是安装 Oracle JDK 8 并从 Rosetta - https://www.oracle.com/in/java/technologies/javase/javase-jdk8-downloads.html 运行它的步骤

下载 macOS x64 版本 尝试安装软件包时,如果 Rosetta 不存在,您将收到安装提示 其余安装步骤与任何其他软件包一样。

您可以通过打开终端并输入来验证它是否有效:

java -version

【讨论】:

JDK 8 在本文发布时已经 7 岁。最新版本是JDK 16,可以在这里下载:oracle.com/java/technologies/javase-downloads.html#JDK16 最新的LTS版本是JDK 11,可以在这里下载:oracle.com/java/technologies/javase-jdk11-downloads.html 链接已损坏:“我们找到了密钥。但您要查找的页面仍然丢失。” 请注意,原始帖子要求的解决方案不适用于 x86。也就是原帖想要一个ARM JDK。

以上是关于适用于 Apple M1 芯片的 Java/JDK的主要内容,如果未能解决你的问题,请参考以下文章

注册期间未在 Macbook Pro 2020 M1 上检测到适用于 iOS 的 Apple Configurator

如何在 Apple M1 芯片上导入 Pandas

在 M1 芯片上运行 rails 时出错(Apple Silicon)

虚拟环境 Apple M1 芯片上的错误架构问题

Apple M系列芯片时代即将来临

Apple M1 芯片上的随机“断言失败”错误