Java/JDK for the Apple M1 chip

JavaMacosApple M1

Java Problem Overview


Will there need to be a special release of OpenJDK to support the new Apple M1 chip?

I see that there are currently downloads of the JDK for macOS/OS X, but these seem to only be for x86 processors. Is that correct? If so, where can I download a version of OpenJDK for the M1?

Java Solutions


Solution 1 - Java

Yes.

On this page: AdoptOpenJDK Latest Releases you can select 'macOS' from the 'Operating System' dropdown, and then from 'Architecture', it's currently only x64, but soonish there should be AArch64 or ARM64 (those are usually the shortcodes for 64-bit ARM). Possibly, as Apple no doubt has a bunch of extensions built into their M1 designs, and Apple gets its own.

If you instead leave Operation System on 'any', you'll note aarch64 is in there, and this gets you to a Linux release for ARM processors. That (probably) won't run on macOS on M1 hardware, but that's 95% of the work already done.

So: It's not there yet, but note that JDKs for ARM have been available for more than decade, and whilst JDK 15 has dropped support for a bunch of exotic OS/architecture combinations (such as Solaris), ARM development has always remained at least partially relevant (even if so far it's mostly an Oracle commercial license offering). That is to say: It should not be a herculean effort to create an adoptopenjdk release that runs on M1s natively, so presumably, it will happen. But, it's an open source effort, so if you're anxious, by all means, read up and contribute :)

Apple has not given any details on this architecture whatsoever until November 10th 2020, unless you bought a development kit box for it (a Mac Mini with an A14 chip, which isn't an M1 chip, but close enough I guess), and signed a big NDA.

As a rule, open source projects will run as fast as possible in the opposite direction if you wave an NDA around, so if you dislike this state of affairs, I don't think it's wise to complain to adoptopenjdk or other packagers and open source projects about it :)

Fortunately, now it's out, and an NDA is no longer required. My assumption is that the ARM branch of the OpenJDK source code + the macOS bits that already exist for the macOS x64 release can be combined rather easily once someone with some familiarity with the OpenJDK source code has an M1-based macOS system to test it on, which should mean an adoptopenjdk macos-aarch64 release should be here within the month.

But, open source. You didn't pay them, you have no contract, and they don't owe it to you. Donate to the effort or contribute a pull request if you want it to go faster.

UPDATE:

  • Azul's M1 OpenJDK builds

  • Microsoft's (yes, really) GitHub source repo for an early access OpenJDK16 build for macOS on AArch64. Note that Microsoft's been working on the OpenJDK branch of AArch64 (for ARM-based Windows 10) for a while, which goes back to: A lot of the hard work was already done.

Solution 2 - Java

A command line approach (thanks to the Homebrew team and the hard work of @vladimir-kempik and other openjdk contributors on the JEP-391 branch)

# Install Homebrew
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

# Install OpenJDK
brew install openjdk

Verify it's installed:

$(brew --prefix openjdk)/bin/java --version

Verify it's for the arm64 hardware:

file $(brew --prefix openjdk)/bin/java     
# /opt/homebrew/opt/openjdk/bin/java: Mach-O 64-bit executable arm64

Note: To install openjdk system-wide, follow the on-screen instructions provided by Homebrew.

Solution 3 - Java

Azul is offering macOS ARM builds of OpenJDK on their website in the Downloads section. I haven’t tried them out yet though, but Azul have been long-time JDK developers.

Once you unpack the Azul JDK, you have to rummage around inside of it until you find the zulu-11.jdk directory (assuming you've downloaded JDK 11), which you then copy to /Library/Java/JavaVirtualMachines.

Solution 4 - Java

You can install the Java JDK using sdkman (see sdkman install):

vim .sdkman/etc/config

Set sdkman_rosetta2_compatible=false (see sdkman config)

After that, you will see a list of compatible with M1 JDKs:

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
================================================================================

Choose one and install it using the command sdk install java IDENTIFIER, i.e.:

sdk install java 8.0.292-zulu

Solution 5 - Java

brew install openjdk

In my case, after install openjdk successfully on Mac M1, the java command still not work. I fix it by

brew info openjdk

then there is a command like

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

Execute this command and java command work

Solution 6 - Java

Now, OpenJDK 17 from Oracle supports the Apple M1 chip. The status of the JEP 391 is closed & delivered.

You can download the free, macOS/AArch64 open-source build of the JDK, version 17 from the official website.

Solution 7 - Java

I am successfully developing Java applications on the new Apple M1 Chip with Azul OpenJDK and NetBeans.

Configuration:

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

Solution 8 - Java

I've tried the Azul JDK 8.

I just wanted to say that, while the Azul JDK works natively on Apple M1 and its speed is great, there are still issues. Especially when some Java code needs to call C++ code.

For example, I am a big data developer. And I started using the Azul JDK for my development workflow. But I noticed that certain tests started failing after the switch. For example, when the test writes to a Parquet/Avro file, it fails. I think that is because there are some native things written in C++ for Parquet/Avro, and they are not compiled for M1.

For this specific reason I am forced to use the non-M1 JDK, which is slow. There are no issues there.

Here's an example of the error that I get with Azul that I don't get with non-M1 JDKs:

- 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)

As you can see, it says: Cause: org.xerial.snappy.SnappyError: [FAILED_TO_LOAD_NATIVE_LIBRARY] no native library is found for os.name=Mac and os.arch=aarch64

I googled this issue and they said that the native library is compiled for a later version of Spark, unfortunately.

This frustrated me tremendously, and I want a Windows laptop now, LOL. Running an Intel JDK on the M1 chip can be slow at times, and I don't want that.

Be careful!

Update: They released new versions of their libraries with support for M1, I updated them in the projects and everything works, thank God. Sometimes these "native code errors" manifest themselves with different exceptions and this is additional P.I.T.A. that I have to deal with while my colleagues on windows laptops don't need to deal with it. The errors can be a bit unclear sometimes, but if you see something about native code in the error log, or words like "jna" or "jni", then it's an M1 chip problem.

Solution 9 - Java

I followed the below steps and I was able to successfully run JDK 16 on Mac M1:

  1. Go to "Oracle.com"
  2. Go to ProductsSoftwareJava
  3. Click on "Download Java Now"
  4. Click on "JDK Download"
  5. Select "macOS Installer"
  6. Install JDK
  7. Try with any sample Java program and this should work for you.

I was able to install and successfully run this on my Mac M1.

Solution 10 - Java

Please go to the Azul site and download the .dmg file:

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

This will be placed in a library and once IntelliJ IDEA identifies it, it should be good to run.

Solution 11 - Java

It's not just JEP-391.

There is a preview branch, https://github.com/openjdk/jdk-sandbox/tree/JEP-391-branch, one can build JDK 16 early-access (EA) using cross-compilation on Intel Mac or directly on ARM Mac. And it runs fine.

Solution 12 - Java

You can download the Liberica JDK from:

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

In IntelliJ IDEA for M1, the JetBrains Runtime is also native (ARM64).

Solution 13 - Java

Microsoft and Azul appear to be prime movers on JEP 391 in combination with the Windows port (JEP 388). They have a separate GitHub repository that actually has an EA release for macOS-aarch64.

I am not sure what exact relationship is with the OpenJDK repository.

Solution 14 - Java

The latest build for Mac M1's are available now

https://www.oracle.com/java/technologies/downloads/#jdk18-mac

enter image description here

Solution 15 - Java

Here are steps to install Oracle JDK 8 and run it from Rosetta - https://www.oracle.com/in/java/technologies/javase/javase-jdk8-downloads.html

  • Download the macOS x64 version
  • While attempting to install the package, you will receive a prompt to install Rosetta if it already doesn't exist
  • The rest of the installation steps are as any other package.

You can verify it has worked or not by opening up terminal and typing:

java -version

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTharView Question on Stackoverflow
Solution 1 - JavarzwitserlootView Answer on Stackoverflow
Solution 2 - JavatresfView Answer on Stackoverflow
Solution 3 - JavaMing-Yee IuView Answer on Stackoverflow
Solution 4 - JavaBoris AzanovView Answer on Stackoverflow
Solution 5 - JavaLinhView Answer on Stackoverflow
Solution 6 - JavaHamza BelmelloukiView Answer on Stackoverflow
Solution 7 - Javauser14679771View Answer on Stackoverflow
Solution 8 - Javapavel_orekhovView Answer on Stackoverflow
Solution 9 - JavaAnuragView Answer on Stackoverflow
Solution 10 - JavaMadhav7890View Answer on Stackoverflow
Solution 11 - JavaVladimir KempikView Answer on Stackoverflow
Solution 12 - JavaDmitryView Answer on Stackoverflow
Solution 13 - JavaPeterView Answer on Stackoverflow
Solution 14 - JavaWaqasView Answer on Stackoverflow
Solution 15 - JavaSaideep UllalView Answer on Stackoverflow