Custom OpenJDK 10 Builds on Ubuntu 16.04

May 01, 2018

I wrote before about building OpenJDK 9, this post is an update for OpenJDK 10.

Note: I usually use a linux container for experiments. If you do not already use them, I highly recommend you to check it out. Here is a tutorial: https://linuxcontainers.org/lxd/introduction/.

This post summarizes the information from <OpenJDK 10 repo>/doc/building.md document and gives some hints specifically for Ubuntu 16.04.

We need mercurial to clone the repo.

$ sudo apt-get update
$ sudo apt-get install mercurial

Now lets clone the OpenJDK 10 repo. This will take some time.

$ hg clone http://hg.openjdk.java.net/jdk-updates/jdk10u/

The OpenJDK 9 repo was only a super/meta repo and after cloning it we need to pull all other dependent projects. However, this has changed in OpenJDK 10 and its repo now contains all relevant source code -that is why it takes a long time to clone it-.

The tag for 10.0.1 GA release is jdk-10.0.1+10.

$ cd jdk10u/
$ hg update jdk-10.0.1+10

We need to install the toolchain to build the source code, but lets check what it says:

$ bash configure
<... omitting the output before ...>
configure: error: Cannot find GNU make 3.81 or newer! Please put it in the path, or add e.g. MAKE=/opt/gmake3.81/make as argument to configure.
configure exiting with result code 1

Lets install the native compilers:

sudo apt-get install build-essential

Now try again:

$ bash configure
<... omitting the output before ...>
configure: error: Could not find required tool for UNZIP

So:

sudo apt-get install unzip

Now:

$ bash configure
<... omitting the output before ...>
configure: error: Could not find required tool for ZIPEXE

So:

sudo apt-get install zip

Now:

$ bash configure
<... omitting the output before ...>
configure: Could not find a valid Boot JDK. You might be able to fix this by running 'sudo apt-get install openjdk-8-jdk'.

In order to build the OpenJDK, we need a boot JDK. Typically if you are building the version N of JDK, you need version N-1 of JDK installed. The output here says openjdk-8-jdk but it is an error and it should be openjdk-9-jdk. Actually if you install openjdk-8-jdk, then bash configure will also raise an error say you need either 9 or 10 as boot jdk. Also, there is another problem that if you install openjdk-9-jdk in Ubuntu 16.04, it is a pre-GA release (b114), so it is not working properly (bash configure says nothing but when you build it raises errors regarding to some flags which are not supported with this build whereas it is supported in GA release). So instead of using this, I will download a GA build from OpenJDK (from http://jdk.java.net/archive/) and use that instead:

$ cd ..
$ wget https://download.java.net/java/GA/jdk9/9.0.4/binaries/openjdk-9.0.4_linux-x64_bin.tar.gz
$ tar xvf openjdk-9.0.4_linux-x64_bin.tar.gz

Let see the status again:

$ bash configure --with-boot-jdk=../jdk-9.0.4
<... omitting the output before ...>
configure: error: Could not find all X11 headers (shape.h Xrender.h XTest.h Intrinsic.h). You might be able to fix this by running 'sudo apt-get install libx11-dev libxext-dev libxrender-dev libxtst-dev libxt-dev'.

So I do what it says:

$ sudo apt-get install libx11-dev libxext-dev libxrender-dev libxtst-dev libxt-dev

Now:

$ bash configure --with-boot-jdk=../jdk-9.0.4
<... omitting the output before ...>
configure: error: Could not find cups! You might be able to fix this by running 'sudo apt-get install libcups2-dev'.

Again doing what it says:

$ sudo apt-get install libcups2-dev

Now:

$ bash configure --with-boot-jdk=../jdk-9.0.4
<... omitting the output before ...>
configure: error: Could not find fontconfig! You might be able to fix this by running 'sudo apt-get install libfontconfig1-dev'.

Again doing what it says:

$ sudo apt-get install libfontconfig1-dev

Now:

$ bash configure --with-boot-jdk=../jdk-9.0.4
<... omitting the output before ...>
configure: error: Could not find alsa! You might be able to fix this by running 'sudo apt-get install libasound2-dev'.

Again doing what it says:

$ sudo apt-get install libasound2-dev

Now:

$ bash configure --with-boot-jdk=../jdk-9.0.4
<... omitting the output before ...>
checking is ccache enabled... no
checking if build directory is on local disk... yes
checking JVM features for JVM variant 'server'... all-gcs aot cds compiler1 compiler2 graal jni-check jvmci jvmti management nmt services vm-structs
configure: creating /home/ubuntu/jdk10u/build/linux-x86_64-normal-server-release/configure-support/config.status
config.status: creating /home/ubuntu/jdk10u/build/linux-x86_64-normal-server-release/spec.gmk
config.status: creating /home/ubuntu/jdk10u/build/linux-x86_64-normal-server-release/bootcycle-spec.gmk
config.status: creating /home/ubuntu/jdk10u/build/linux-x86_64-normal-server-release/buildjdk-spec.gmk
config.status: creating /home/ubuntu/jdk10u/build/linux-x86_64-normal-server-release/compare.sh
config.status: creating /home/ubuntu/jdk10u/build/linux-x86_64-normal-server-release/Makefile
====================================================
A new configuration has been successfully created in
/home/ubuntu/jdk10u/build/linux-x86_64-normal-server-release
using configure arguments '--with-boot-jdk=../jdk-9.0.4'.
Configuration summary:
* Debug level:    release
* HS debug level: product
* JDK variant:    normal
* JVM variants:   server
* OpenJDK target: OS: linux, CPU architecture: x86, address length: 64
* Version string: 10.0.1-internal+0-adhoc.ubuntu.jdk10u (10.0.1-internal)
Tools summary:
* Boot JDK:       openjdk version "9.0.4" OpenJDK Runtime Environment (build 9.0.4+11) OpenJDK 64-Bit Server VM (build 9.0.4+11, mixed mode)  (at /home/ubuntu/jdk-9.0.4)
* Toolchain:      gcc (GNU Compiler Collection)
* C Compiler:     Version 5.4.0 (at /usr/bin/gcc)
* C++ Compiler:   Version 5.4.0 (at /usr/bin/g++)
Build performance summary:
* Cores to use:   8
* Memory limit:   31929 MB

Finally everything is OK. By default, we are building:

debug level: release (possible debug levels: release, fastdebug, slowdebug, optimized)
JDK variant: normal
JVM variants: server (possible variants: server, client, minimal, core, zero, custom)
JVM features: all-gcs aot cds compiler1 compiler2 graal jni-check jvmci jvmti management nmt services vm-structs (possible features: compiler1 compiler2 zero minimal dtrace jvmti jvmci graal vm-structs jni-check services management all-gcs nmt cds static-build link-time-opt aot)

I wrote about what debug level, variant and feature mean for OpenJDK in my other posts, check them if you are interested.

I may need to run build multiple times so it is a good idea to enable ccache. Lets first clean the configuration (make target dist-clean) and enable ccache:

$ make dist-clean
$ bash configure --with-boot-jdk=../jdk-9.0.4 --enable-ccache
<... omitting the output before ...>
configure: error: Could not find required tool for CCACHE

Not surprisingly we got error. We need to install ccache first.

$ sudo apt-get install ccache
$ bash configure --with-boot-jdk=../jdk-9.0.4 --enable-cache
<... omitting the output before ...>
checking is ccache enabled... yes
<... omitting the output after ...>

So it is enabled now. Lets try a build.

$ make
<... omitting the output before ...>
Finished building target 'default (exploded-image)' in configuration 'linux-x86_64-normal-server-release'

It is a success.

$ ./build/linux-x86_64-normal-server-release/jdk/bin/java --version
openjdk 10.0.1-internal 2018-04-17
OpenJDK Runtime Environment (build 10.0.1-internal+0-adhoc.ubuntu.jdk10u)
OpenJDK 64-Bit Server VM (build 10.0.1-internal+0-adhoc.ubuntu.jdk10u, mixed mode)

After this point, you can experiment with other build options such as different debug levels, variants and features. Also, you can use the make target images to build jdk and jre images as in official installers.