Build OpenJDK 12 On Fedora 29

JDK 12 reached General Availability on 19 March 2019. Production-ready binaries under the GPL are available from Oracle; followed by binaries from other vendors. We also can create for ourself, a custom build of OpenJDK 12 (or another versions as well).

In this article, I'll I attempt to perform custom build for OpenJDK in Linux Fedora 29 that I installed before. The Fedora has "Development Tools" installed.

Instructions for the Impatient

You can find this instruction from this link. If you are eager to try out building the JDK, these simple steps works most of the time. They assume that you have installed Mercurial and cloned the top-level JDK repository that you want to build.

  1. Get the complete source code:
    $ hg clone http://hg.openjdk.java.net/jdk/jdk
  2. Run configure:
    $ bash configure
    If configure fails due to missing dependencies (to either the toolchain, build tools, external libraries or the boot JDK), most of the time it prints a suggestion on how to resolve the situation on your platform. Follow the instructions, and try running bash configure again.
  3. Run make:
    $ make images
  4. Verify your newly built JDK:
    $ ./build/*/images/jdk/bin/java -version
  5. Run basic tests:
    $ make run-test-tier1

Let's drill down those steps one-by-one

Get OpenJDK 12 Source Code

You can clone the OpenJDK 12 repo or get a snapshot. The repo is quite big so it takes some time to clone.

dariawan@localhost ~]$ hg clone https://hg.openjdk.java.net/jdk/jdk12/
destination directory: jdk12
requesting all changes
adding changesets
adding manifests
adding file changes
added 53221 changesets with 461143 changes to 181811 files
new changesets fd16c54261b3:06222165c35f
updating to branch default
(warning: large working directory being used without fsmonitor enabled; enable fsmonitor to improve performance; see "hg help -e fsmonitor")

Cloned repo at the time of writing this post is 2.5G

[dariawan@localhost jdk12]$ du -sh /home/dariawan/jdk12/
2.5G    /home/dariawan/jdk12/

Run Configure

[dariawan@localhost ~]$ cd jdk12
[dariawan@localhost jdk12]$ ls
ADDITIONAL_LICENSE_INFO  ASSEMBLY_EXCEPTION  bin  configure  doc  LICENSE  make  Makefile  README  src  test
[dariawan@localhost jdk12]$ bash configure
Runnable configure script is not present
Generating runnable configure script at /home/dariawan/jdk12/build/.configure-support/generated-configure.sh

Autoconf is not found on the PATH, and AUTOCONF is not set.
You need autoconf to be able to generate a runnable configure script.
You might be able to fix this by running 'sudo yum install autoconf'.
Error: Cannot find autoconf

As stated in the error, we need autoconf to be able to generate a runnable configure script.

[dariawan@localhost jdk12]$ sudo yum install autoconf

Re-run bash configure:

[dariawan@localhost jdk12]$ bash configure
Runnable configure script is not present
Generating runnable configure script at /home/dariawan/jdk12/build/.configure-support/generated-configure.sh
Using autoconf at /usr/bin/autoconf [autoconf (GNU Autoconf) 2.69]
configure: Configuration created at Fri Apr 19 23:16:46 +08 2019.
...
... purposely truncated
...
checking for javac... no
checking for java... no
configure: Could not find a valid Boot JDK. You might be able to fix this by running 'sudo yum install java-1.8.0-openjdk-devel'.
configure: This might be fixed by explicitly setting --with-boot-jdk
configure: error: Cannot continue
configure exiting with result code 1

This time, we need a valid Boot JDK. As the error suggest, I'll install java-1.8.0-openjdk-devel.

[dariawan@localhost jdk12]$ sudo yum install java-1.8.0-openjdk-devel
Last metadata expiration check: 0:07:18 ago on Fri 19 Apr 2019 11:26:59 PM +08.
Dependencies resolved.
=================================================================================================================================
 Package                                   Architecture         Version                              Repository             Size
=================================================================================================================================
Installing:
 java-1.8.0-openjdk-devel                  x86_64               1:1.8.0.201.b09-6.fc29               updates               9.8 M
Installing dependencies:
 java-1.8.0-openjdk                        x86_64               1:1.8.0.201.b09-6.fc29               updates               239 k
 java-1.8.0-openjdk-headless               x86_64               1:1.8.0.201.b09-6.fc29               updates                32 M
 lua                                       x86_64               5.3.5-3.fc29                         updates               178 k
 tzdata-java                               noarch               2019a-1.fc29                         updates               152 k
 copy-jdk-configs                          noarch               3.7-2.fc29                           fedora                 25 k
 javapackages-filesystem                   noarch               5.3.0-1.fc29                         fedora                 12 k
 lksctp-tools                              x86_64               1.0.16-10.fc29                       fedora                 92 k
 lua-posix                                 x86_64               33.3.1-11.fc29                       fedora                173 k
 ttmkfdir                                  x86_64               3.0.9-55.fc29                        fedora                 53 k
 xorg-x11-fonts-Type1                      noarch               7.5-20.fc29                          fedora                517 k

Transaction Summary
=================================================================================================================================
Install  11 Packages

Total download size: 43 M
Installed size: 152 M
Is this ok [y/N]: y
...
... purposely truncated
...

Installed:
  java-1.8.0-openjdk-devel-1:1.8.0.201.b09-6.fc29.x86_64              java-1.8.0-openjdk-1:1.8.0.201.b09-6.fc29.x86_64
  java-1.8.0-openjdk-headless-1:1.8.0.201.b09-6.fc29.x86_64           lua-5.3.5-3.fc29.x86_64
  tzdata-java-2019a-1.fc29.noarch                                     copy-jdk-configs-3.7-2.fc29.noarch
  javapackages-filesystem-5.3.0-1.fc29.noarch                         lksctp-tools-1.0.16-10.fc29.x86_64
  lua-posix-33.3.1-11.fc29.x86_64                                     ttmkfdir-3.0.9-55.fc29.x86_64
  xorg-x11-fonts-Type1-7.5-20.fc29.noarch

Complete!

Now, re-run bash configure using --with-boot-jdk={} option

[dariawan@localhost jdk12]$ bash configure --with-boot-jdk=/usr/lib/jvm/java-1.8.0
configure: Configuration created at Fri Apr 19 23:32:07 +08 2019.
...
... purposely truncated
...
configure: Found potential Boot JDK using configure arguments
configure: Potential Boot JDK found at /usr/lib/jvm/java-1.8.0 is incorrect JDK version (openjdk version "1.8.0_201"); ignoring
configure: (Your Boot JDK version must be one of: 11 12)
configure: error: The path given by --with-boot-jdk does not contain a valid Boot JDK
configure exiting with result code 1

Uh, ok... Now the error mention that Our Boot JDK version must be one of: 11 12. Why in the first place they suggest java-1.8.0-openjdk-devel... We'll install java-11-openjdk-devel this time.

[dariawan@localhost jdk12]$ sudo yum install java-11-openjdk-devel
Last metadata expiration check: 0:12:08 ago on Fri 19 Apr 2019 11:26:59 PM +08.
Dependencies resolved.
=================================================================================================================================
 Package                                  Architecture           Version                           Repository               Size
=================================================================================================================================
Installing:
 java-11-openjdk-devel                    x86_64                 1:11.0.2.7-7.fc29                 updates                 3.3 M
Installing dependencies:
 java-11-openjdk                          x86_64                 1:11.0.2.7-7.fc29                 updates                 219 k
 java-11-openjdk-headless                 x86_64                 1:11.0.2.7-7.fc29                 updates                  39 M

Transaction Summary
=================================================================================================================================
Install  3 Packages

Total download size: 42 M
Installed size: 169 M
Is this ok [y/N]: y
Downloading Packages:
(1/3): java-11-openjdk-11.0.2.7-7.fc29.x86_64.rpm                                                1.1 MB/s | 219 kB     00:00
(2/3): java-11-openjdk-devel-11.0.2.7-7.fc29.x86_64.rpm                                          3.6 MB/s | 3.3 MB     00:00
(3/3): java-11-openjdk-headless-11.0.2.7-7.fc29.x86_64.rpm                                       2.3 MB/s |  39 MB     00:16
---------------------------------------------------------------------------------------------------------------------------------
Total                                                                                            2.4 MB/s |  42 MB     00:17
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Running scriptlet: java-11-openjdk-headless-1:11.0.2.7-7.fc29.x86_64                                                       1/1
  Preparing        :                                                                                                         1/1
  Installing       : java-11-openjdk-headless-1:11.0.2.7-7.fc29.x86_64                                                       1/3
  Running scriptlet: java-11-openjdk-headless-1:11.0.2.7-7.fc29.x86_64                                                       1/3
  Installing       : java-11-openjdk-1:11.0.2.7-7.fc29.x86_64                                                                2/3
  Running scriptlet: java-11-openjdk-1:11.0.2.7-7.fc29.x86_64                                                                2/3
  Installing       : java-11-openjdk-devel-1:11.0.2.7-7.fc29.x86_64                                                          3/3
  Running scriptlet: java-11-openjdk-devel-1:11.0.2.7-7.fc29.x86_64                                                          3/3
  Running scriptlet: java-11-openjdk-1:11.0.2.7-7.fc29.x86_64                                                                3/3
  Running scriptlet: java-11-openjdk-devel-1:11.0.2.7-7.fc29.x86_64                                                          3/3
  Verifying        : java-11-openjdk-1:11.0.2.7-7.fc29.x86_64                                                                1/3
  Verifying        : java-11-openjdk-devel-1:11.0.2.7-7.fc29.x86_64                                                          2/3
  Verifying        : java-11-openjdk-headless-1:11.0.2.7-7.fc29.x86_64                                                       3/3

Installed:
  java-11-openjdk-devel-1:11.0.2.7-7.fc29.x86_64                      java-11-openjdk-1:11.0.2.7-7.fc29.x86_64
  java-11-openjdk-headless-1:11.0.2.7-7.fc29.x86_64

Complete!

And re-configure

[dariawan@localhost jdk12]$ bash configure --with-boot-jdk=/usr/lib/jvm/java-11
configure: Configuration created at Fri Apr 19 23:42:10 +08 2019.
...
... purposely truncated
...
checking for g++... no
configure: error: Could not find a C++ compiler. You might be able to fix this by running 'sudo yum groupinstall "Development Tools"'.
configure exiting with result code 1

Pretty strange. I thought I already have all "Development Tools" installed. At the end, I found out that I need gcc-c++, and this package is not part of "Development Tools" group.

[dariawan@localhost bin]$ sudo yum install gcc-c++

Again re-configure...

[dariawan@localhost jdk12]$ bash configure --with-boot-jdk=/usr/lib/jvm/java-11
configure: Configuration created at Sat Apr 20 00:02:08 +08 2019.
...
... purposely truncated
...
checking for X... no
configure: error: Could not find X11 libraries. You might be able to fix this by running 'sudo yum install libXtst-devel libXt-devel libXrender-devel libXrandr-devel libXi-devel'.
configure exiting with result code 1

This time, could not find X11 libraries. As per suggestion, I install:

[dariawan@localhost jdk12]$ sudo yum install libXtst-devel libXt-devel libXrender-devel libXrandr-devel libXi-devel

Another re-configure...

[dariawan@localhost jdk12]$ bash configure --with-boot-jdk=/usr/lib/jvm/java-11
configure: Configuration created at Sat Apr 20 00:09:03 +08 2019.
...
... purposely truncated
...
checking cups/cups.h usability... no
checking cups/cups.h presence... no
checking for cups/cups.h... no
checking cups/ppd.h usability... no
checking cups/ppd.h presence... no
checking for cups/ppd.h... no
configure: error: Could not find cups! You might be able to fix this by running 'sudo yum install cups-devel'.
configure exiting with result code 1

Now we need install 'cups-devel'

[dariawan@localhost jdk12]$ sudo yum install cups-devel

Re-configure...

[dariawan@localhost jdk12]$ bash configure --with-boot-jdk=/usr/lib/jvm/java-11
configure: Configuration created at Sat Apr 20 00:35:07 +08 2019.
...
... purposely truncated
...
checking fontconfig/fontconfig.h usability... no
checking fontconfig/fontconfig.h presence... no
checking for fontconfig/fontconfig.h... no
configure: error: Could not find fontconfig! You might be able to fix this by running 'sudo yum install fontconfig-devel'.
configure exiting with result code 1

Install 'fontconfig-devel'

[dariawan@localhost jdk12]$ sudo yum install fontconfig-devel

Re-configure...

[dariawan@localhost jdk12]$ bash configure --with-boot-jdk=/usr/lib/jvm/java-11
configure: Configuration created at Sat Apr 20 00:43:11 +08 2019.
...
... purposely truncated
...
checking for ALSA... no
checking alsa/asoundlib.h usability... no
checking alsa/asoundlib.h presence... no
checking for alsa/asoundlib.h... configure: error: Could not find alsa! You might be able to fix this by running 'sudo yum install alsa-lib-devel'.
no
configure exiting with result code 1

Install 'alsa-lib-devel':

[dariawan@localhost jdk12]$ sudo yum install alsa-lib-devel

Re-configure again:

[dariawan@localhost jdk12]$ bash configure --with-boot-jdk=/usr/lib/jvm/java-11
configure: Configuration created at Sat Apr 20 01:25:07 +08 2019.
...
... purposely truncated
...

====================================================
A new configuration has been successfully created in
/home/dariawan/jdk12/build/linux-x86_64-server-release
using configure arguments '--with-boot-jdk=/usr/lib/jvm/java-11'.

Configuration summary:
* Debug level:    release
* HS debug level: product
* JVM variants:   server
* JVM features:   server: 'aot cds cmsgc compiler1 compiler2 epsilongc g1gc graal jfr jni-check jvmci jvmti management nmt parallelgc serialgc services shenandoahgc vm-structs zgc'
* OpenJDK target: OS: linux, CPU architecture: x86, address length: 64
* Version string: 12-internal+0-adhoc.dariawan.jdk12 (12-internal)

Tools summary:
* Boot JDK:       openjdk version "11.0.2" 2019-01-15 OpenJDK Runtime Environment 18.9 (build 11.0.2+7) OpenJDK 64-Bit Server VM 18.9 (build 11.0.2+7, mixed mode, sharing)  (at /usr/lib/jvm/java-11)
* Toolchain:      gcc (GNU Compiler Collection)
* C Compiler:     Version 8.3.1 (at /usr/bin/gcc)
* C++ Compiler:   Version 8.3.1 (at /usr/bin/g++)

Build performance summary:
* Cores to use:   1
* Memory limit:   1990 MB

Use 'dist-clean' to remove all files, including configuration

[dariawan@localhost jdk12]$ make dist-clean
Building target 'dist-clean' in configuration 'linux-x86_64-server-release'
Cleaning hotspot build artifacts ... done
Cleaning jdk build artifacts ... done
Cleaning bootcycle-build build artifacts ... done
Cleaning test-results build artifacts ... done
Cleaning test-support build artifacts ... done
Cleaning test build artifacts ... done
Cleaning buildtools build artifacts ... done
Cleaning support build artifacts ... done
Cleaning images build artifacts ... done
Cleaning make-support build artifacts ... done
Cleaning test-make build artifacts ... done
Cleaning bundles build artifacts ... done
Cleaning buildjdk build artifacts ... done
Cleaned all build artifacts.
Removing configuration directory for 'linux-x86_64-server-release'
Cleaned everything, you will have to re-run configure.
Finished building target 'dist-clean' in configuration 'linux-x86_64-server-release'

The JDK build supports building with ccache when using gcc or clang. Using ccache can radically speed up compilation of native code if you often rebuild the same sources. Your milage may vary however, so we recommend evaluating it for yourself. To enable it, make sure it's on the path and configure with '--enable-ccache'.

First, you need to install ccache:

[dariawan@localhost jdk12]$ sudo yum install ccache
[dariawan@localhost jdk12]$ bash configure --with-boot-jdk=/usr/lib/jvm/java-11 --enable-ccache
configure: Configuration created at Sat Apr 20 02:00:20 +08 2019.
...
... purposely truncated
...

====================================================
A new configuration has been successfully created in
/home/dariawan/jdk12/build/linux-x86_64-server-release
using configure arguments '--with-boot-jdk=/usr/lib/jvm/java-11 --enable-ccache'.

Configuration summary:
* Debug level:    release
* HS debug level: product
* JVM variants:   server
* JVM features:   server: 'aot cds cmsgc compiler1 compiler2 epsilongc g1gc graal jfr jni-check jvmci jvmti management nmt parallelgc serialgc services shenandoahgc vm-structs zgc'
* OpenJDK target: OS: linux, CPU architecture: x86, address length: 64
* Version string: 12-internal+0-adhoc.dariawan.jdk12 (12-internal)

Tools summary:
* Boot JDK:       openjdk version "11.0.2" 2019-01-15 OpenJDK Runtime Environment 18.9 (build 11.0.2+7) OpenJDK 64-Bit Server VM 18.9 (build 11.0.2+7, mixed mode, sharing)  (at /usr/lib/jvm/java-11)
* Toolchain:      gcc (GNU Compiler Collection)
* C Compiler:     Version 8.3.1 (at /usr/bin/gcc)
* C++ Compiler:   Version 8.3.1 (at /usr/bin/g++)

Build performance summary:
* Cores to use:   1
* Memory limit:   1990 MB
* ccache status:  Active (3.4.2)

Run make

Use 'images' or 'product-images' - Build the JDK image

[dariawan@localhost jdk12]$ make images
Building target 'images' in configuration 'linux-x86_64-server-release'
...
... purposely truncated
...
Creating support/modules_libs/java.base/server/libjvm.so from 987 file(s)
../../src/hotspot/share/runtime/arguments.cpp: In static member function ‘static jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs*, bool*, JVMFlag::Flags)’:
../../src/hotspot/share/runtime/arguments.cpp:2472:29: error: ‘char* strncpy(char*, const char*, size_t)’ output truncated before terminating nul copying as many bytes from a string as its length [-Werror=stringop-truncation]
         char* name = strncpy(NEW_C_HEAP_ARRAY(char, len + 1, mtArguments), tail, len);
                      ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../src/hotspot/share/runtime/arguments.cpp:2471:44: note: length computed here
         size_t len = (pos == NULL) ? strlen(tail) : pos - tail;
                                      ~~~~~~^~~~~~
cc1plus: all warnings being treated as errors
gmake[3]: *** [lib/CompileJvm.gmk:174: /home/dariawan/jdk12/build/linux-x86_64-server-release/hotspot/variant-server/libjvm/objs/arguments.o] Error 1
gmake[2]: *** [make/Main.gmk:257: hotspot-server-libs] Error 2

ERROR: Build failed for target 'images' in configuration 'linux-x86_64-server-release' (exit code 2)
Stopping sjavac server

=== Output from failing command(s) repeated here ===
* For target hotspot_variant-server_libjvm_objs_arguments.o:
../../src/hotspot/share/runtime/arguments.cpp: In static member function ‘static jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs*, bool*, JVMFlag::Flags)’:
../../src/hotspot/share/runtime/arguments.cpp:2472:29: error: ‘char* strncpy(char*, const char*, size_t)’ output truncated before terminating nul copying as many bytes from a string as its length [-Werror=stringop-truncation]
         char* name = strncpy(NEW_C_HEAP_ARRAY(char, len + 1, mtArguments), tail, len);
                      ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../src/hotspot/share/runtime/arguments.cpp:2471:44: note: length computed here
         size_t len = (pos == NULL) ? strlen(tail) : pos - tail;
                                      ~~~~~~^~~~~~
cc1plus: all warnings being treated as errors

* All command lines available in /home/dariawan/jdk12/build/linux-x86_64-server-release/make-support/failure-logs.
=== End of repeated output ===

No indication of failed target found.
Hint: Try searching the build log for '] Error'.
Hint: See doc/building.html#troubleshooting for assistance.

make[1]: *** [/home/dariawan/jdk12/make/Init.gmk:310: main] Error 2
make: *** [/home/dariawan/jdk12/make/Init.gmk:186: images] Error 2

Ooops, another problem. This is because all warnings being treated as errors. Since I'll not fixing all those warnings, what I can do is to '--disable-warnings-as-errors'. Before doing another configure, we'll need to clean our previous build and configurations. I done it using

  • make dist-clean
  • rm -Rf build/

Yes, I even remove 'build' folder. Now, re-configure

[dariawan@localhost jdk12]$ bash configure --with-boot-jdk=/usr/lib/jvm/java-11 --enable-ccache --disable-warnings-as-errors
Runnable configure script is not present
Generating runnable configure script at /home/dariawan/jdk12/build/.configure-support/generated-configure.sh
Using autoconf at /usr/bin/autoconf [autoconf (GNU Autoconf) 2.69]
configure: Configuration created at Sat Apr 20 05:22:11 +08 2019.
...
... purposely truncated
...

====================================================
A new configuration has been successfully created in
/home/dariawan/jdk12/build/linux-x86_64-server-release
using configure arguments '--with-boot-jdk=/usr/lib/jvm/java-11 --enable-ccache --disable-warnings-as-errors'.

Configuration summary:
* Debug level:    release
* HS debug level: product
* JVM variants:   server
* JVM features:   server: 'aot cds cmsgc compiler1 compiler2 epsilongc g1gc graal jfr jni-check jvmci jvmti management nmt parallelgc serialgc services shenandoahgc vm-structs zgc'
* OpenJDK target: OS: linux, CPU architecture: x86, address length: 64
* Version string: 12-internal+0-adhoc.dariawan.jdk12 (12-internal)

Tools summary:
* Boot JDK:       openjdk version "11.0.2" 2019-01-15 OpenJDK Runtime Environment 18.9 (build 11.0.2+7) OpenJDK 64-Bit Server VM 18.9 (build 11.0.2+7, mixed mode, sharing)  (at /usr/lib/jvm/java-11)
* Toolchain:      gcc (GNU Compiler Collection)
* C Compiler:     Version 8.3.1 (at /usr/bin/gcc)
* C++ Compiler:   Version 8.3.1 (at /usr/bin/g++)

Build performance summary:
* Cores to use:   1
* Memory limit:   1990 MB
* ccache status:  Active (3.4.2)

And another make images

[dariawan@localhost jdk12]$ make images
Building target 'images' in configuration 'linux-x86_64-server-release'
...
... purposely truncated
...
Creating jdk image
Creating CDS archive for jdk image
Updating images/sec-bin.zip
Stopping sjavac server
Finished building target 'images' in configuration 'linux-x86_64-server-release'

This time, build success...

Verify Our Newly Built JDK

Verify it by simply check java version

[dariawan@localhost jdk12]$ ./build/*/images/jdk/bin/java -version
openjdk version "12-internal" 2019-03-19
OpenJDK Runtime Environment (build 12-internal+0-adhoc.dariawan.jdk12)
OpenJDK 64-Bit Server VM (build 12-internal+0-adhoc.dariawan.jdk12, mixed mode, sharing)

when you try to run 'make run-test-tier1', you may encounter error because of jtreg.

...
... purposely truncated
...
Test selection 'tier1', will run:
* jtreg:test/hotspot/jtreg:tier1
* jtreg:test/jdk:tier1
* jtreg:test/langtools:tier1
* jtreg:test/nashorn:tier1
* jtreg:test/jaxp:tier1
Error: jtreg framework is not found.
Please run configure using --with-jtreg.
RunTests.gmk:1011: *** Cannot continue.  Stop.
gmake[2]: *** [make/Main.gmk:491: test-tier1] Error 2

ERROR: Build failed for target 'run-test-tier1' in configuration 'linux-x86_64-server-release' (exit code 2)

No indication of failed target found.
Hint: Try searching the build log for '] Error'.
Hint: See doc/building.html#troubleshooting for assistance.

make[1]: *** [/home/dariawan/jdk12/make/Init.gmk:310: main] Error 2
make: *** [/home/dariawan/jdk12/make/Init.gmk:186: run-test-tier1] Error 2

This is because jtreg framework is not 'installed' in your machine. But this is completely out of this article scope. So, for today... Enjoy your custom build OpenJDK!