This page last changed on Aug 20, 2009 by stepheneb.

Building the BSD port of OpenJDK, Java 1.7 on Max OS X 10.5.8

These instructions are lightly adapted from Landon Fuller's post here.

If you plan on working with OpenJDK on a Mac you should probably join OpenJDK bsd-port-dev mailing list.

Dependencies

SoyLatte 32-bit Java 1.6 binaries

I'm using Landon Fuller's SoyLatte 32-bit Java 1.6 binaries to build the OpenJDK bsd port:

After downloading the binaries I copied the whole directory to:

/usr/local/soylatte16-i386-1.0.3

Test the SoyLatte install:

$ /usr/local/soylatte16-i386-1.0.3/bin/java -version
java version "1.6.0_03-p3"
Java(TM) SE Runtime Environment (build 1.6.0_03-p3-landonf_19_aug_2008_14_55-b00)
Java HotSpot(TM) Server VM (build 1.6.0_03-p3-landonf_19_aug_2008_14_55-b00, mixed mode)

Mercurial

Assuming you have macports installed:

sudo port install mercurial +bash_completion

Test the mercurial install:

$ hg --version
Mercurial Distributed SCM (version 1.1.2)

Copyright (C) 2005-2008 Matt Mackall <mpm@selenic.com> and others
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Forest extension to Mercurial

This is the cannonical source for the Forest extension:

hg clone http://hg.akoha.org/hgforest

But ... I'm actually using Patrick M├ęzard's clone of hgforest instead (just a couple of fixes to Simon's work):

hg clone http://bitbucket.org/pmezard/hgforest-crew

After cloning hgforest-crew add an hgext.forest item with the path to hgforest-crew/forest.py in the extensions section in your ~/.hgrc file.

Here's my ~/.hgrc file:

$ cat ~/.hgrc
[ui]
username = Stephen Bannasch <stephen.bannasch@gmail.com>
[extensions]
hgext.forest=/Users/stephen/dev/mercurial/hgforest-crew/forest.py
mq=
hgk=
fetch=
[hgk]
path=/opt/local/share/mercurial/contrib/hgk
[diff]
nodates=1
git=1

JiBX v1.1.5

The JiBX library (Binding XML to Java Code) is a prerequisite for building.
Install v1.1.5 of the JiBX: Binding XML to Java Code: downloads.

Checkout the code using hg/forest

hg fclone http://hg.openjdk.java.net/bsd-port/bsd-port

Here's what my bsd-port dir looks like:

$ cd bsd-port/

$ ls -l
total 528
-rw-r--r--   1 stephen  staff    1503 Dec 15 12:29 ASSEMBLY_EXCEPTION
-rw-r--r--   1 stephen  staff   19241 Dec 15 12:29 LICENSE
-rw-r--r--   1 stephen  staff   16336 Dec 15 12:29 Makefile
-rw-r--r--   1 stephen  staff    1207 Dec 15 12:29 README
-rw-r--r--   1 stephen  staff   87215 Jan 25 23:04 README-builds.html
-rw-r--r--   1 stephen  staff  127532 Dec 15 12:29 THIRD_PARTY_README
drwxr-xr-x   4 stephen  staff     136 Jan 26 00:51 build
-rwxr--r--@  1 stephen  staff     373 Jan 26 03:00 build.sh
drwxr-xr-x  11 stephen  staff     374 Jan 25 23:06 corba
drwxr-xr-x  13 stephen  staff     442 Jan 25 23:06 hotspot
drwxr-xr-x  11 stephen  staff     374 Jan 25 23:06 jaxp
drwxr-xr-x  11 stephen  staff     374 Jan 25 23:06 jaxws
drwxr-xr-x  12 stephen  staff     408 Jan 25 23:07 jdk
drwxr-xr-x  12 stephen  staff     408 Jan 25 23:07 langtools
drwxr-xr-x  18 stephen  staff     612 Dec 15 12:29 make

Build OpenJDK

I added the script build.sh to keep track of the correct build invocation. The version below is adapted from Kurt Millers email here.

Edit the paths to fit your dir structure. This script needs to be run with the source command.

build.sh

build.sh
$ cat build.sh
# source build.sh
env -i PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin \
 make \
 ALT_BOOTDIR=/usr/local/soylatte16-i386-1.0.3/ \
 ALT_FREETYPE_HEADERS_PATH=/usr/X11R6/include \
 ALT_FREETYPE_LIB_PATH=/usr/X11R6/lib \
 ALT_JIBX_LIBS_PATH=/Users/stephen/dev/java/jibx/lib \
 ANT_HOME=/usr/share/ant \
 NO_DOCS=true \
 HOTSPOT_BUILD_JOBS=1

Build openjdk like this:

source build.sh

This takes about 10m on my 2.5 GHz Intel Core 2 Duo MacBook Pro.

Try cleaning if you get errors

Some errors when compiling are fixed by cleaning. You can temporarily add the clean command to the end of build.sh and source it to clean the build products.

Or you can try this suggestion from Kurt Miller:

mv build build.del; rm -rf build.del &

Smoketest

If the build completes do a simple test by asking the JVM to print its version info. It should look something like this:

./build/bsd-i586/j2sdk-image/bin/java -version
openjdk version "1.7.0-internal"
OpenJDK Runtime Environment (build 1.7.0-internal-stephen_2009_01_25_23_54-b00)
OpenJDK Server VM (build 14.0-b10, mixed mode)

Copy the new Java build to /usr/local and update a symbolic link

Copy the entire ./build/bsd-i586/j2sdk-image dir to /usr/local/java-1.7.0-internal and add a suffix with the date:

sudo mv build/bsd-i586/j2sdk-image /usr/local/java-1.7.0-internal-`date "+%Y_%m_%d"`

Link /usr/local/java-1.7.0 to the latest build:

$ cd /usr/local
$ sudo ln -s java-1.7.0-internal-`date "+%Y_%m_%d"` java-1.7.0

I encapsulated these functions in the script update-usr-local.sh:

update-usr-local.sh

update-usr-local.sh
#!/bin/sh
buildname=java-1.7.0-internal-`date "+%Y_%m_%d"`
sudo rm -rf /usr/local/$buildname
sudo mkdir /usr/local/$buildname
sudo cp -r build/bsd-i586/j2sdk-image/* /usr/local/$buildname
cd /usr/local
sudo rm -f java-1.7.0
sudo ln -s $buildname java-1.7.0

This results in a new JVM:

$ ls -l /usr/local
...
lrwxr-xr-x    1 root  wheel    38 Jan 31 20:58 java-1.7.0 -> java-1.7.0-internal-2009_01_31
drwxr-xr-x   15 root  wheel   510 Jan 31 21:37 java-1.7.0-internal-2009_01_31

$ /usr/local/java-1.7.0/bin/java -version
openjdk version "1.7.0-internal"
OpenJDK Runtime Environment (build 1.7.0-internal-stephen_2009_01_25_23_54-b00)
OpenJDK Server VM (build 14.0-b10, mixed mode)

Generating the Javadoc

This script will generate the Javadoc for jdk, jaxws, jaxp, corba, and langtools in a javadoc/ directory.

You need to run javadoc under jdk1.7 to be able to correctly process some or the source code files in the jdk dir – so make sure tyou are using the correct java:

$ java -version
openjdk version "1.7.0-internal"
OpenJDK Runtime Environment (build 1.7.0-internal-stephen_2009_08_19_16_32-b00)
OpenJDK Server VM (build 16.0-b06, mixed mode)

You can use the pickjdk bash function described later to easily switch which default java you are using.

generate_javadoc.sh

#!/bin/sh
javadoc -J-Xmx1024m  -d ./javadoc/jdk -sourcepath ./jdk/src/share/classes -subpackages com:java:javax:org:sun:sunw
javadoc -J-Xmx1024m  -d ./javadoc/jaxws -sourcepath ./jaxws/src/share/classes -subpackages com:javax
javadoc -J-Xmx1024m  -d ./javadoc/jaxp -sourcepath ./jaxp/src/share/classes -subpackages com:java:javax
javadoc -J-Xmx1024m  -d ./javadoc/corba -sourcepath ./corba/src/share/classes -subpackages com:javax:org:sun
javadoc -J-Xmx1024m  -d ./javadoc/langtools -sourcepath ./langtools/src/share/classes -subpackages com:javax:sun

Opening the Javadoc in five tabbed windows in Safari

This script will open all five index.html files in separate tabs in Safari on a Mac. This is helpful if you want to save all five files in a bookmark folder for the Java 1.7.0 Javadoc.

open_javadoc_in_safari.sh

# edit the value of this variable to refer to the destination directory 
JAVADOC_LOCATION=~/dev/java/src/bsd-port/javadoc

# open 1.7.0 javadoc index pages in Safari 
osascript -e "tell application \"Safari\" to make new document with properties {URL:\"$JAVADOC_LOCATION/jdk/index.html\"}"
cd $JAVADOC_LOCATION 
open -a Safari jaxws/index.html jaxp/index-all.html corba/index.html langtools/index.html
osascript -e 'tell front window of app "Safari" to set current tab to tab 1'

Update and rebuild OpenJDK

$ cd bsd-port
$ hg fpull -u
$ source build.sh
$ sudo ./update-usr-local.sh

Using pickjdk to switch JVMs from a shell on Mac OS X

I've modified a bash shell function named pickjdk in my ~./bash_profile to add java 1.7.0. The result is a function that allows me to easily switch between any installed JVM from the shell:

$ pickjdk
 1) 1.3.1
 2) 1.4.2
 3) 1.5.0
 4) 1.6.0
 5) Soylatte-amd64
 6) Soylatte16-i386-1.0.3
 7) 1.7.0
 8) None
Choose one of the above [1-8]:7

Here's the pickjdk function:

pickjdk

#
# pickjdk: for switching between Java versions:
# From Nick Sieger: http://pastie.org/170326
#   "I just symlink soylatte to:
#    /System/Library/Frameworks/JavaVM.framework/Versions/1.6.0-soylatte/System/Library/Frameworks/JavaVM.framework/Versions/1.6.0-soylatte"
#
_macosx()
{
    if [ $(uname -s) = Darwin ]; then
        return 0
    else
        return 1
    fi
}

JDKS_ROOT=
if [ $(uname -s) = Darwin ]; then
    JDKS_ROOT=/System/Library/Frameworks/JavaVM.framework/Versions
fi

SOYLATTE_HOME=${HOME}/dev/java/src/soylatte/control/build/bsd-amd64
SOYLATTE_32_HOME=/usr/local/soylatte16-i386-1.0.3
JAVA_1_7_0_HOME=/usr/local/java-1.7.0

pickjdk()
{
    if [ -z "$JDKS_ROOT" ]; then
        return 1
    fi

    declare -a JDKS
    local n=1 jdk total_jdks choice=0 currjdk=$JAVA_HOME explicit_jdk
    for jdk in $JDKS_ROOT/[0-9]*; do
        if [ -d $jdk -a ! -L $jdk ]; then
            echo -n " $n) $(basename $jdk)"
            if _macosx; then
                jdk=$jdk/Home
            fi
            if [ $jdk = "$currjdk" ]; then
                echo " < CURRENT"
            else
                echo
            fi
            JDKS[$n]=$jdk
            total_jdks=$n
            n=$[ $n + 1 ]
        fi
    done
    echo " $n) Soylatte-amd64"
    JDKS[$n]=$SOYLATTE_HOME
    n=$[ $n + 1 ]
    echo " $n) Soylatte16-i386-1.0.3"
    JDKS[$n]=$SOYLATTE_32_HOME
    n=$[ $n + 1 ]
    echo " $n) 1.7.0"
    JDKS[$n]=$JAVA_1_7_0_HOME
    n=$[ $n + 1 ]
    echo " $n) None"
    JDKS[$n]=None
    total_jdks=$n

    if [ $total_jdks -gt 1 ]; then
        while [ -z "${JDKS[$choice]}" ]; do
            echo -n "Choose one of the above [1-$total_jdks]: "
            read choice
        done
        else
        choice=1
    fi

    if [ -z "$currjdk" ]; then
        currjdk=$(dirname $(dirname $(type -path java)))
    fi

    if [ ${JDKS[$choice]} != None ]; then
        export JAVA_HOME=${JDKS[$choice]}
    else
        unset JAVA_HOME
    fi

    explicit_jdk=
    for jdk in ${JDKS[*]}; do
        if [ "$currjdk" = "$jdk" ]; then
            explicit_jdk=$jdk
            break
        fi
    done

    if [ "$explicit_jdk" ]; then
        if [ -z "$JAVA_HOME" ]; then
            PATH=$(echo $PATH | sed "s|$explicit_jdk/bin:*||g")
        else
            PATH=$(echo $PATH | sed "s|$explicit_jdk|$JAVA_HOME|g")
        fi
    elif [ "$JAVA_HOME" ]; then
        PATH="$JAVA_HOME/bin:$PATH"
    fi

    hash -r
    unset JDKS
}

Building the Java Multi Language Virtual Machine (MLVM)

The MLVM, also known as the Da Vinci Machine project, are a set of modifications the the Java language to better support implementing dynamic languages in Java.

Document generated by Confluence on Jan 27, 2014 16:56