[Hacking the JVM] First Steps – Building OpenJDK on macOS

I have been coding in Java like forever and was always intrigued about JVM implementation. Having unsuccessfully tried several times in past to dive deeper, decided to adopt a different way this time. What prompted this exploration was some mysterious production issues that were not easy to resolve without diving deeper. So, here comes the 1st step of building the JVM locally and setting up the environment locally. Finally for the motivation part, the words from Sia’s Cheap Thrills song are spot on “But I don’t need no money. As long as I can feel the beat

For this series, I will use Java 17 as base of all exploration on macOS, unless specified. Join along the journey. In this post we shall build JDK locally and configure code base in CLion to explore further.

Setup

Following things are needed for build,

  • Xcode – (version 16.2)
  • autoconf
  • sdkman – for managing Java versions, if you install more than one
  • Java – going to use Java 17 for the purpose of this exploration, as we do need java to build java
    ❯ sdk use java 17.0.15-zulu

Clone the repository

The main-line development repository is at https://github.com/openjdk/jdk. However, once after release projects are maintained per release. You can find more details at JDK Update Releases.
For Java 17, we will clone https://github.com/openjdk/jdk17u

NOTE: The dev repo for JDK17 is hosted at jdk17u-dev and changes are merged to main jdk17-u repo

git clone https://github.com/openjdk/jdk17u

Building the code

Move to the cloned folder and run following commands

bash configure
make images

Once the steps are completed, we have a working JDK build and test it via command

./build/*/images/jdk/bin/java -version

Note: At this step, I ran into build issues using Xcode 16.4. The error is due to more strict checking and error message is like below. If such a issue happens follow instructions here

jdk17u/src/hotspot/os/posix/signals_posix.cpp:1673:20: error: cast from 'void (*)(int, siginfo_t *, ucontext_t *)' (aka 'void (*)(int, __siginfo *, __darwin_ucontext *)') to 'void (*)(int)' converts to incompatible function type [-Werror,-Wcast-function-type-mismatch]

 1673 |   act.sa_handler = (void (*)(int)) SR_handler;

      |                    ^~~~~~~~~~~~~~~~~~~~~~~~~~

1 error generated.

Now that we have successfully built JDK, it’s time to configure the codebase in CLion for exploration.

Configuring CLion

Execute the following commands to create compilation database

make compile-commands

This will generate compile_commands.json in ./build/macosx-aarch64-server-release/ folder

Open the compile_commands.json in CLion (and open as project)

File -> Open -> compile_commands.json

We have our code configured in CLion ready to be explored. The code looks something like this

We did not configure the project for debugging in this post, as our focus is solely on code exploration and making minor updates. The IntelliJ blog has excellent steps for achieving debugging within the IDE.

Before we wrap up this post, let’s make a small, custom change to the JDK’s version string as a tangible first step.

Customizing the Version

Updating the Version String

As a simple change, I aimed to modify the version string to a custom format. While it seemed straightforward initially, it took more time than expected. During this process, I found an interesting conversation about JDK Versions. Although these settings can often be changed with build parameters (as mentioned in the JDK build documentation), I wanted to demonstrate a direct source code modification without relying on additional command-line parameters.

Updating the Patch number

The version can be modified in file make/conf/version-numbers.conf. For simplicity, only incremented patch as 1

Update Product name

I updated the product name to OpenJDK-Jarvis in make/conf/branding.conf

Update name format

I updated the name format to remove the username and add a hardcoded string in make/autoconf/jdk-version.m4

After following usual build procedure of `bash configure’make clean;make images`, we get a customized version string

References

And the final feelings

Leave a Reply

Your email address will not be published. Required fields are marked *