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/macuninstalljava.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