How to build a JDK on ARM-based Mac

I was exploring how to build a slimmer non-JIT JDK to be embedded in a Desktop app on Apple Silicons Mac.

To conclude, it doesn't seem we can completely disable JIT... or at least the JIT definition by Apple. There is a zero variant JDK [1], which will disable the JVM features: compiler1 and compiler2 and these 2 features are JIT compilers. However, it seems Apple has a different definition of JIT. In essence, Apple wants to forbid invoking pthread_jit_write_protect_np(0), which can be used for granting the access to write code "on-the-fly". JDK invokes pthread_jit_write_protect_np(0) regardless of the variant and will crash if com.apple.security.cs.allow-jit isn't enabled.

However, the journey of building an old JDK on a new Mac and MacOS is quite challenging, so I wanted summarize the steps in case it is useful for anyone else.

1: Install an older XCode/Clang

The first thing to understand is that an old JDK requires an old Clang. Here's the reference page: https://wiki.openjdk.org/display/Build/Supported+Build+Platforms

If I want to build a JDK 21, then I will need XCode/Clang 13.1. Note that XCode/Clang 12.4 doesn't work on Mac 15.6 anymore.

You can go download older XCode/Clangs here: https://developer.apple.com/download/all/?q=13.4

Here are the steps:

  1. Rename Applications/Xcode.app to /Applications/Xcode_orig.app for safe-keeping.
  2. Download Xcode 13.4.1.xip, unzip, rename Xcode.app to Xcode_13.app, and move Xcode.app to /Applications.
  3. Open Terminal and runs: sudo xcode-select --switch /Applications/Xcode_13.app/Contents/Developer.
  4. Run clang --version to verify that we are using the version 13.

If you don't downgrade Xcode/Clang, you might encounter tons of compilation errors that are obscure. Because Clang 17 (the current version as of now) uses a different standard from Clang 13. Here's one of the error you may encounter:

/Users/tanin/projects/jdk/src/java.base/share/native/libzip/zlib/zutil.h:194:11: error: 'OS_CODE' macro redefined [-Werror,-Wmacro-redefined]
  194 | #  define OS_CODE 19
      |           ^
/Users/tanin/projects/jdk/src/java.base/share/native/libzip/zlib/zutil.h:165:11: note: previous definition is here
  165 | #  define OS_CODE  7
      |           ^
1 error generated.

This is because a newer Clang decides that macro-redefined is now not ok.

2: Get JDK and compile

Here's official guide: https://github.com/openjdk/jdk/blob/jdk-22-ga/doc/building.md

You can get the JDK source code by cloning: https://github.com/openjdk/jdk.git

You can switch to the version that you want. For example, 21 would be jdk-21-ga, so I would run git checkout jdk-21-ga.

Now you can run bash configure --with-jvm-variants=zero. This is configured to build the zero variant.

Next you will run make images in order to build the JDK.

At this step, you might encounter another obscure error:

xattr: [Errno 13] Permission denied: '/Users/tanin/projects/jdk/build/macosx-aarch64-zero-release/jdk/conf/management/jmxremote.password.template'

I have no idea why this happens but hey let's solve it the hacky way by getting the file from somewhere, and here's how you do it:

cp src/jdk.management.agent/share/conf/jmxremote.password.template build/macosx-aarch64-zero-release/jdk/conf/management/jmxremote.password.template

Now you will run make images again. It will run for a while and fail with the below error:

xattr: [Errno 13] Permission denied: '/Users/tanin/projects/jdk/build/macosx-aarch64-zero-release/images/jdk-bundle/jdk-21.jdk/Contents/Home/legal/java.base/LICENSE'
xattr: [Errno 13] Permission denied: '/Users/tanin/projects/jdk/build/macosx-aarch64-zero-release/images/jdk-bundle/jdk-21.jdk/Contents/Home/legal/java.base/ADDITIONAL_LICENSE_INFO'
xattr: [Errno 13] Permission denied: '/Users/tanin/projects/jdk/build/macosx-aarch64-zero-release/images/jdk-bundle/jdk-21.jdk/Contents/Home/legal/java.base/ASSEMBLY_EXCEPTION'

This error doesn't seem to matter because your JDK would already be built at ./build/macosx-aarch64-zero-release/jdk.

If you are using SDKMan, you can install your custom JDK with: sdk install java jdk-21-zero ./build/macosx-aarch64-zero-release/jdk.

And that's how you build a JDK on an Apple Silicon Mac.

[1] Here's some explanation on JDK variants: https://metebalci.com/blog/demystifying-the-jvm-jvm-variants-cppinterpreter-and-templateinterpreter/

Subscribe to tanin

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe