Java/JDK的苹果硅芯片

是否需要一个特殊的OpenJDK版本来支持新的苹果硅芯片?

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

384444 次浏览

是的。

在这个页面:AdoptOpenJDK最新版本中,你可以从“操作系统”下拉菜单中选择“macOS”,然后从“架构”中选择,它目前只有x64,但很快就会有AArch64或ARM64(这些通常是64位ARM的短代码)。可能吧,因为苹果无疑在他们的M1设计中内置了一堆扩展,苹果也有自己的扩展。

如果你把操作系统设置为“any”,你会注意到aarch64在那里,这让你进入了ARM处理器的Linux发行版。这(可能)不会在M1硬件上的macOS上运行,但这已经完成了95%的工作。

所以:它还没有实现,但请注意,用于ARM的JDK已经有十多年了,而JDK 15已经放弃了对一堆奇异的操作系统/架构组合的支持(例如Solaris), ARM开发始终至少保持部分相关(即使到目前为止它主要是Oracle商业许可证提供)。也就是说:创建一个在m1上本机运行的adoptopenjdk发行版不应该是一项艰巨的工作,所以可以推测,它将会发生。但是,这是一个开源的成果,所以如果你感到焦虑,无论如何都要阅读并贡献:)

直到2020年11月10日,苹果还没有给出任何关于这个架构的细节,除非你为它买了一个开发工具包(一个带有A14芯片的Mac Mini,这不是M1芯片,但我猜已经足够接近了),并签署了一个大的NDA

作为一个规则,如果你挥舞着NDA,开源项目就会在相反的方向上尽可能快地运行,所以如果你不喜欢这种状态,我认为向adoptopenjdk或其他打包器和开源项目抱怨是不明智的:)

幸运的是,现在它出来了,不再需要保密协议。我的假设是,一旦熟悉OpenJDK源代码的人有一个基于m1的macOS系统来测试它,就可以很容易地将OpenJDK源代码的ARM分支+ macOS x64版本中已经存在的macOS位结合起来,这应该意味着一个月之内就会有一个adoptopenjdk macOS -aarch64版本。

但是,开源。你没有付钱给他们,你没有合同,他们也不欠你的。如果你想让它走得更快,就捐款或贡献一个拉请求。

更新:

  • Azul's M1 OpenJDK构建
  • 微软(是的,真的)GitHub源代码回购用于AArch64上macOS的早期访问OpenJDK16构建。请注意,微软已经在AArch64的OpenJDK分支(用于基于arm的Windows 10)上工作了一段时间,这可以追溯到:很多艰苦的工作已经完成了。

不仅仅是JEP-391。

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

微软和Azul似乎是中391与Windows端口(JEP 388)结合的主要推动者。他们有一个独立的GitHub存储库,实际上有一个macOS-aarch64的EA版本。

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

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

一旦你解包Azul JDK,你必须在它里面翻找,直到你找到zulu-11.jdk目录(假设你已经下载了JDK 11),然后你把它复制到/Library/Java/JavaVirtualMachines

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

配置:

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

请到Azul网站下载。dmg文件:

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

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

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

  • 下载macOS x64版本
  • 在尝试安装该包时,如果Rosetta已经不存在,您将收到安装它的提示
  • 其余的安装步骤与任何其他包相同。

您可以通过打开终端并输入以下命令来验证它是否工作:

java -version

命令行方法(感谢家酿团队以及@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提供的屏幕说明。

您可以从以下网站下载Liberica JDK:

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

在M1的IntelliJ IDEA中,JetBrains运行时也是原生的(ARM64)。

我尝试过Azul JDK 8。

我只是想说,虽然Azul JDK在Apple M1上原生运行,而且速度非常快,但仍然存在一些问题。特别是当一些Java代码需要调用c++代码时。

例如,我是一名大数据开发人员。我开始使用Azul JDK进行开发工作流程。但是我注意到切换后某些测试开始失败。例如,当测试写入拼花/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

我谷歌了一下这个问题,他们说本机库是为火花的后续版本编译的,不幸的是。

这让我非常沮丧,我现在想要一台Windows笔记本电脑,哈哈。在M1芯片上运行Intel JDK有时会很慢,我不希望这样。

小心!

< >强更新: 他们发布了支持M1的库的新版本,我在项目中更新了它们,一切都很正常,感谢上帝。有时这些“原生代码错误”;这是额外的P.I.T.A.,我必须处理,而我使用windows笔记本电脑的同事不需要处理。错误有时可能有点不清楚,但如果您在错误日志中看到一些关于本机代码的内容,或像“;jna"或者“jni”,那么这是M1芯片的问题

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

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

我遵循以下步骤,我能够成功地在MacBook Air (M1)上运行JDK 16:

  1. 访问“甲骨文”网站;
  2. 进入产品软件Java
  3. 点击“立即下载Java”;
  4. 点击“JDK下载”;
  5. 选择“;macOS Installer"
  6. 安装JDK
  7. 尝试任何示例Java程序,这应该适合您。

我成功地在我的MacBook Air (M1)上安装并运行了这个程序。

现在,来自Oracle的OpenJDK 17支持Apple M1芯片。中391的状态为closed & delivered。

你可以从官方网站中下载免费的macOS/AArch64开源JDK版本17。

brew install openjdk

在我的例子中,在MacBook Air (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命令就生效了。

简单地使用转到Java下载,在菜单中选择选项卡“Java 18“;,然后选择选项卡“macOS"。下载Arm 64 DMG安装程序

您可以验证它是否工作 打开终端,输入:

java -version