Mac OS X and OpenJDK
These are notes for compiling OpenJDK from source. If you simply want to install OpenJDK, use MacPorts or download from AdoptOpenJDK or Zulu Community.
$ sudo port install openjdk11
OpenJDK
These notes relate to installing OpenJDK 8 on Mac OS X 10.11 (El Capitan). Unfortunately, the process of building OpenJDK on Mac OS X seems to rarely be straight-forward. Be prepared to debug the build process. Alternatively, see under ‘See also’ at the end of this document for links to binary downloads of the OpenJDK.
If you don’t have Mercurial installed, it can be
installed using macports with
sudo port install mercurial.
Get the code as described in JDK 8 Update Releases
page. It seems the jdk8u-dev is a better version to use
as it has tags that seem to relate to releases. Browse other repository
choices at http://hg.openjdk.java.net/jdk8u/
$ hg clone http://hg.openjdk.java.net/jdk8u/jdk8u-dev openjdk8u-dev
In the OpenJDK source folder, run the get_source.sh
script:
$ bash get_source.sh
Optionally, select a tag to build from:
$ hg tags | grep jdk8u111
$ sh ./common/bin/hgforest.sh update jdk8u111-b14
View README-builds.html in the downloaded source. It
describes which version of Xcode to install for the build.
Although the instructions state to use JDK 1.7 to perform the build, it worked successfully for me using a 1.8 JDK.
Download the relevant .dmg package from https://developer.apple.com/download/more/. In this
example it is Xcode 4.5.2 with a release date of
Nov 1, 2012.
Create a new directory to keep this version of Xcode separate from any others. E.g.
$ sudo mkdir /Applications/Xcode4.5.2
$ sudo chgrp wheel /Applications/Xcode4.5.2
Open the downloaded Xcode .dmg package and copy the
Xcode.app folder to the
/Applications/Xcode4.5.2 folder using finder, so that it
resides at /Applications/Xcode4.5.2/Xcode.app.
Switch the current version of Xcode:
$ sudo xcode-select --switch /Applications/Xcode4.5.2/Xcode.app
Optionally, confirm the switch
$ xcode-select --print-path
/Applications/Xcode4.5.2/Xcode.app/Contents/Developer
Run Xcode through the launcher and when prompted to
Install additional required components? select the
Install option.
Optionally, install ccache to improve C++ compiler
performance. E.g. with macports
sudo port install ccache.
If the version of ccache is greater than 3.1.9, you may need to apply
the following patch as the existing test fails with higher versions.
However, using ccache results in segmentation faults during the build,
so I had to disable it by passing --disable-ccache to
configure.
Patch with, e.g.:
$ patch -p1 <~/tmp/build-performance-m4.patch
diff -r 07c7b5880ac3 common/autoconf/build-performance.m4
--- a/common/autoconf/build-performance.m4 Wed Sep 21 13:39:51 2016 -0700
+++ b/common/autoconf/build-performance.m4 Wed Jan 11 15:03:16 2017 +0000
@@ -199,7 +199,7 @@
# Only use ccache if it is 3.1.4 or later, which supports
# precompiled headers.
AC_MSG_CHECKING([if ccache supports precompiled headers])
- HAS_GOOD_CCACHE=`($CCACHE --version | head -n 1 | grep -E 3.1.@<:@456789@:>@) 2> /dev/null`
+ HAS_GOOD_CCACHE=`($CCACHE --version | head -n 1 | grep -E 3.\(@<:@2-9@:>@\|1.@<:@456789@:>@\)) 2> /dev/null`
if test "x$HAS_GOOD_CCACHE" = x; then
AC_MSG_RESULT([no, disabling ccache])
CCACHE=
diff -r 07c7b5880ac3 common/autoconf/generated-configure.sh
--- a/common/autoconf/generated-configure.sh Wed Sep 21 13:39:51 2016 -0700
+++ b/common/autoconf/generated-configure.sh Wed Jan 11 15:03:16 2017 +0000
@@ -3672,7 +3672,7 @@
#
-# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -3880,7 +3880,7 @@
#CUSTOM_AUTOCONF_INCLUDE
# Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1449096260
+DATE_WHEN_GENERATED=1484146859
###############################################################################
#
@@ -36093,7 +36093,7 @@
# precompiled headers.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if ccache supports precompiled headers" >&5
$as_echo_n "checking if ccache supports precompiled headers... " >&6; }
- HAS_GOOD_CCACHE=`($CCACHE --version | head -n 1 | grep -E 3.1.[456789]) 2> /dev/null`
+ HAS_GOOD_CCACHE=`($CCACHE --version | head -n 1 | grep -E 3.\([2-9]\|1.[456789]\)) 2> /dev/null`
if test "x$HAS_GOOD_CCACHE" = x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no, disabling ccache" >&5
$as_echo "no, disabling ccache" >&6; }
Change to the project directory:
$ cd openjdk8u-dev
Then run configure:
$ bash configure
or include the path to Xcode if you haven’t or don’t wish to switch
Xcode versions with xcode-select (as described above).
$ bash configure --with-xcode-path=/Applications/Xcode4.5.2/Xcode.app
or specify a specific “boot” JDK:
$ bash configure --with-xcode-path=/Applications/Xcode4.5.2/Xcode.app \
--with-boot-jdk=/Library/Java/JavaVirtualMachines/jdk1.7.0_80.jdk/Contents/Home
and set the update version etc. appropriately, e.g. jdk8u111-b14
$ bash configure --with-update-version=111 --with-build-number=b14
There is a comment above the acceptable_simple_element
function in
./openjdk8u-dev/jdk/src/share/bin/version_comp.c stating
that Java Web Start may not consider a JRE as a match, depending on the
version string. Something to consider if your Java Web Start
applications won’t run.
If configure fails, refer to the various options that
can be passed to configure in
README-builds.html.
Build:
$ make all
make help shows a list of targets. E.g.
make bootcycle-images, which presumably ensures the built
JDK is at least able to be used as a boot JDK to build itself and
hopefully the next new version too.
If the build fails, use the following to show the shell commands being executed:
$ make LOG=trace JOBS=1 all
If you see the error couldn't understandkern.osversion
during the build, export the following variable before building:
$ export MACOSX_DEPLOYMENT_TARGET=10.9
I found that make always hung on a dtrace command
leaving the CPUs busy. Normally, there is more-or-less continual output
from the build process, so if output stops, be suspicious the build has
hung. You can further confirm it’s hung by running
du -s build periodically to see if there is anything being
written to the build folder. If the disk usage stays static over a
reasonable period of time (say a few minutes), it’s undoubtedly
hung.
I disabled dtrace with the following patch in the
hotspot sub-project, e.g.:
$ cd hotspot
$ patch --dry-run -p1 <~/tmp/dtrace-make.patch
$ cd -
diff -r 05a6a5823aa5 make/bsd/makefiles/dtrace.make
--- a/make/bsd/makefiles/dtrace.make Wed Sep 21 13:40:37 2016 -0700
+++ b/make/bsd/makefiles/dtrace.make Wed Jan 11 11:20:13 2017 +0000
@@ -356,11 +356,11 @@
#DTRACE_PROG=$(PATCH_DTRACE_PROG)
#DTRACE_INCL=-I/opt/SUNWdtrd/include
#else
-ifneq ("$(systemDtraceFound)", "")
-DTRACE_PROG=$(SYSTEM_DTRACE_PROG)
-else
+#ifneq ("$(systemDtraceFound)", "")
+#DTRACE_PROG=$(SYSTEM_DTRACE_PROG)
+#else
-endif # ifneq ("$(systemDtraceFound)", "")
+#endif # ifneq ("$(systemDtraceFound)", "")
#endif # ifneq ("$(patchDtraceFound)", "")
ifneq ("${DTRACE_PROG}", "")
If you see output similar to the following:
/usr/bin/make: invalid option -- '8'
/usr/bin/make: invalid option -- '/'
/usr/bin/make: invalid option -- 'a'
/usr/bin/make: invalid option -- '/'
/usr/bin/make: invalid option -- 'c'
The build script is trying to rewrite some -j arguments
to a command line, but can rewrite paths which contain the letter j.
Applying the following patch in the hotspot sub-project
should fix it, e.g.:
$ patch -p1 ~/tmp/adjust-mflags-sh.patch
diff -r 87ee5ee27509 make/bsd/makefiles/adjust-mflags.sh
--- a/make/bsd/makefiles/adjust-mflags.sh Tue Mar 04 11:51:03 2014 -0800
+++ b/make/bsd/makefiles/adjust-mflags.sh Tue Jan 10 18:13:58 2017 +0000
@@ -64,7 +64,7 @@
echo "$MFLAGS" \
| sed '
s/^-/ -/
- s/ -\([^ ][^ ]*\)j/ -\1 -j/
+ s/ -\([^ ][^ ]*\)-j/ -\1 -j/
s/ -j[0-9][0-9]*/ -j/
s/ -j\([^ ]\)/ -j -\1/
s/ -j/ -j'${HOTSPOT_BUILD_JOBS:-${default_build_jobs}}'/
diff -r 87ee5ee27509 make/bsd/makefiles/gcc.make
--- a/make/bsd/makefiles/gcc.make Tue Mar 04 11:51:03 2014 -0800
+++ b/make/bsd/makefiles/gcc.make Tue Jan 10 18:13:58 2017 +0000
@@ -349,7 +349,7 @@
# The macro takes the version with no dots, ex: 1070
CFLAGS += -DMAC_OS_X_VERSION_MAX_ALLOWED=$(subst .,,$(MACOSX_VERSION_MIN)) \
-mmacosx-version-min=$(MACOSX_VERSION_MIN)
- LDFLAGS += -mmacosx-version-min=$(MACOSX_VERSION_MIN)
+ LFLAGS += -mmacosx-version-min=$(MACOSX_VERSION_MIN)
endif
Images are built under
./build/macosx-x86_64-normal-server-release/images/ and can
be symlinked from, or copied to, either
~/Libraray/Java/JavaVirtualMachines or
/Libraray/Java/JavaVirtualMachines. E.g.
$ cd /Library/Java/JavaVirtualMachines
$ sudo ln -s /usr/local/src/openjdk8u-dev/build/macosx-x86_64-normal-server-release/images/j2sdk-bundle/jdk1.8.0_112.jdk
See Installing & Using the Mac OS X Port
The makefile’s install target installs the binaries by
default to /usr/local/. It can be changed with
configure --prefix=/opt/local etc. Alternatively, instead
of running the install target, copy the bundle image(s) to
the /Library/Java/JavaVirtualMachines and use
/usr/libexec/java_home (see man java_home). e.g.
$ export JAVA_HOME=`/usr/libexec/java_home '1.8+'`
$ java -version
or
$ /usr/libexec/java_home -exec java -version
Note that the install target creates objects under the build
directory, even after a single make all. These end up with
root ownership which is probably not desireable. Either running
make all again, or make install as a non-root
user first seems to avoid this conflict. Presumably there is a
dependency ordering issue in the make scripts.
$ make install
$ sudo make install
The observed install process created a jvm folder under
the specified prefix folder name, with the JDK home folder named after
the version number within the jvm folder. Symlinks were
created in the bin folder under the specified prefix
soft-linking to the relevant binaries within the JDK home bin
folder.
There doesn’t appear to be an uninstall target, but the following
should list all the broken symlinks after deleting the JDK home folder
(under /usr/local/jvm).
$ find /usr/local/bin -type l -not -exec test -e '{}' \; -print
Obviously, after installing a new version, there shouldn’t be any broken symlinks.
References:
- https://github.com/manasthakur/tech/wiki/Building-OpenJDK-8-on-Mac-OS-X-Yosemite
- http://stackoverflow.com/questions/21246042/scrambled-arguments-when-building-openjdk
- http://iosdevelopertips.com/xcode/install-multiple-versions-of-xcode.html
- http://mail.openjdk.java.net/pipermail/core-libs-dev/2013-July/019246.html
Embedding JRE in a Mac app
See https://wiki.openjdk.java.net/display/MacOSXPort/How+to+embed+a+.jre+bundle+in+your+Mac+app
Uninstalling Oracle JRE/JDK on Mac
https://www.java.com/en/download/help/mac_uninstall_java.xml
Trouble-Shooting
java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
E.g. if a standard JRE is installed, you could reference it’s certificate file when executing java.
$ java -Djavax.net.ssl.trustStore=/Library/Internet\ Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/lib/security/cacerts -jar MY.jar
– Frank Dean - 10 Jan 2017
See also:
- AdoptOpenJDK - Prebuilt OpenJDK Binaries
- Azul - Zulu
- Java Development Kit builds, from Oracle
- Wikipedia - Comparison of Java Virtual Machines
Related Topics: InstallingMacPorts, MacOSXTips, Xcode