Introduction to OpenJDK and IcedTea
        
        
          IcedTea provides a build harness
          for the OpenJDK package, Oracle's
          open-sourced Java development
          environment. In order to provide a completely free runtime
          environment, similar to Oracle's closed distribution, the
          IcedTea build harness also
          provides free, and arguably better versions of parts of the JDK
          which have not been open-sourced to date. OpenJDK is useful for developing Java programs and provides a complete runtime
          environment to run Java programs.
        
        
          This package is known to build and work properly using an LFS-7.6
          systemd platform.
        
        
          
          
            Note
          
          
            The browser plugin and webstart implementation have been split
            off into a separate project. To provide a complete
            implementation, you will need to later install IcedTea-Web-1.5.1.
          
         
        
          OpenJDK is GPL'd code, however, it should be explained that there
          has been a special exception made for non-free projects to use
          these classes in their proprietary products. In similar fashion to
          the LGPL, which allows non-free programs to link to libraries
          provided by free software, the GNU General Public
          License, version 2, with the Classpath Exception allows third
          party programs to use classes provided by free software without the
          requirement that the third party software also be free. As with the
          LGPL, any modifications made to the free software portions of a
          third party application, must also be made freely available.
        
        
          
          
            Note
          
          
            The IcedTea build environment includes a very thorough, open
            source test suite titled JTreg.
            JTreg is intended to test the
            just built JDK for reasonable compatibility with the closed
            Oracle JDK. However, in order for an independent implementation
            to claim compatibility, including the Oracle sponsored
            OpenJDK project, it must pass a
            closed JCK/TCK test suite. No
            claims of compatibility, even partial compatibility, may be made
            without passing an approved test suite.
          
          
            Oracle does provide free community access, on a case by case
            basis, to a closed toolkit to ensure 100% compatibility with its
            proprietary JDK. The binary version provided here has not been
            tested against the 
            TCK. Any version that is built using the instructions given,
            cannot claim to be compatible with the proprietary JDK, without
            the user applying for, and completing the compatibility tests
            themselves.
          
          
            With that in mind, the binaries produced using this build method
            are regularly tested against the TCK by the members listed on the
            site above. In addition to the community license above, an
            educational, non-commercial license for the TCK can be obtained
            from here.
          
         
        
          Source Package Information
        
        
        
          The following may be downladed separately or be done as a part of
          the make process. For
          convenience the BLFS editors have made the files available in an
          LFS website. The files are not distributed with versions, but
          extracted from the OpenJDK version control system at specified
          (tagged) points.
        
        
        
          Additional Downloads
        
        
          Required Patches
        
        
        
          Required JAR
        
        
        
          OpenJDK Dependencies
        
        
          Required Dependencies
        
        
          An existing binary ( java-1.7.0.65 or an earlier built version of
          this package), alsa-lib-1.0.28, apache-ant-1.9.4,
          Certificate Authority
          Certificates, cpio-2.11, Cups-1.7.5, GTK+-2.24.24, giflib-5.1.0,
          UnZip-6.0,
          Wget-1.15, Which-2.20, Xorg Libraries, and
          Zip-3.0
        
        
          Recommended
        
        
          JUnit-4.11
          and NSS-3.17
        
        
          Optional
        
        
          IcedTea-Web-1.5.1 (to obtain icon file for
          the policytool menu
          entry), libxslt-1.1.28, lsb_release-1.4, Mercurial-3.1.1,
          MIT Kerberos V5-1.12.2, and Xorg-Server-1.16.0 (for the tests)
        
        
          User Notes: http://wiki.linuxfromscratch.org/blfs/wiki/openjdk
        
       
      
        
          Installation of OpenJDK
        
        
          
          
            Note
          
          
            The source build of OpenJDK requires apache-ant-1.9.4.
            You'll need to build that first to satisfy the circular
            dependency, and return to this section to continue building
            OpenJDK.
          
         
        
          Unlike other packages in BLFS, the OpenJDK source packages are distributed in
          multiple downloads. Since the IcedTea build harness will be used to
          build OpenJDK, begin by extracting
          the IcedTea package and changing into the extracted directory.
        
        
          The IcedTea OpenJDK distribution
          requires that js.jar (from the Rhino
          package) be in place in order to provide a java-script
          implementation for the free JDK. If you have not installed the
          js.jar file in another way, do so with the following commands as
          the root user:
        
        
unzip ../rhino1_7R4.zip             &&
install -v -d -m755 /usr/share/java &&
install -v -m755 rhino1_7R4/*.jar /usr/share/java
        
          As mentioned previously, OpenJDK
          is composed of several individual projects of the proprietary
          JDK that have been relicensed
          under an open source license. If you have already downloaded all of
          the individual components, place them into the source tree with the
          following commands:
        
        
cp -v ../corba.tar.bz2     . &&
cp -v ../hotspot.tar.bz2   . &&
cp -v ../jaxp.tar.bz2      . &&
cp -v ../jaxws.tar.bz2     . &&
cp -v ../jdk.tar.bz2       . &&
cp -v ../langtools.tar.bz2 . &&
cp -v ../openjdk.tar.bz2   .
        
          Apply a patch to generate a valid cacerts file using the system CA
          certificates:
        
        
patch -Np1 -i ../icedtea-2.5.2-add_cacerts-1.patch
        
          Apply a patch to replace fixed paths with ones appropriate for
          BLFS:
        
        
patch -Np1 -i ../icedtea-2.5.2-fixed_paths-1.patch
        
          Apply a patch to adapt the code to the new giflib API:
        
        
patch -Np1 -i ../icedtea-2.5.2-fix_new_giflib-1.patch
        
          Apply a patch to exclude known broken tests from the test suite:
        
        
patch -Np1 -i ../icedtea-2.5.2-fix_tests-1.patch
        
          Configure and build the package with the following commands
          (--with-pkgversion and --with-version-suffix values can be modified
          to fit user preferences):
        
        
unset JAVA_HOME                                               &&
./autogen.sh                                                  &&
./configure --with-jdk-home=/opt/OpenJDK-1.7.0.65-bin         \
            --with-version-suffix=BLFS                        \
            --enable-nss                                      \
            --disable-system-kerberos                         \
            --with-parallel-jobs                              &&
make
        
          
          
            Note
          
          
            If you have not installed the tarballs specified above, they will
            be automatically downloaded here.
          
         
        
          To test the results, issue: make
          jtregcheck. The included version of jtreg is old, and the test suite is also very
          dependent on the host system and the environment that it is run in.
          You should expect to see anywhere between 40 and 100 failures in
          jdk with up to 10 errors in the tests themselves. The majority of
          the 6000+ tests should pass. The reason for the greatly varying
          results is due to how stringent the testing environment must be.
          Varying architectures, different versions of dependent libraries,
          unexpected X Window environment and window managers, the CA
          certificates used to generate the cacerts file, and even any user input or power
          management or screen saver interruptions during the testing can
          lead to various failures. While the known broken tests have been
          removed, with the fix_tests patch above, the graphics tests
          failures cannot be pre-determined (short of removing them all). The
          best bet for the minimal number of failures is to run the test
          suite in a framebuffer on a different screen (Xvfb). Even still,
          disk I/O can cause failures.
        
        
export DISPLAY=:20     &&
Xvfb :20 -screen 0 1x1x24 -ac&
echo $!>  Xvfb.pid     &&
make -k jtregcheck     &&
kill -9 `cat Xvfb.pid` &&
unset DISPLAY          &&
rm -f Xvfb.pid
        
          Install the package with the following commands as the root user:
        
        
chmod 0644 openjdk.build/j2sdk-image/lib/sa-jdi.jar   &&
cp -R openjdk.build/j2sdk-image /opt/OpenJDK-1.7.0.65 &&
chown -R root:root /opt/OpenJDK-1.7.0.65
        
          If desired, you may install a .desktop file so policytool can be accessed from a
          desktop menu. First, you need to obtain an icon from the IcedTea-Web-1.5.1 tarball:
        
        
tar -xf icedtea-web-1.5.1.tar.gz     \
        icedtea-web-1.5.1/javaws.png \
        --strip-components=1
        
          Now, as root user:
        
        
cat ;> /usr/share/applications/openjdk-7-policytool.desktop << "EOF" &&
[Desktop Entry]
Name=OpenJDK Java 7 Policy Tool
Name[pt_BR]=OpenJDK Java 7 - Ferramenta de Política
Comment=OpenJDK Java 7 Policy Tool
Comment[pt_BR]=OpenJDK Java 7 - Ferramenta de Política
Exec=/opt/jdk/bin/policytool
Terminal=false
Type=Application
Icon=javaws
Categories=Settings;
EOF
install -v -Dm644 javaws.png /usr/share/pixmaps/javaws.png
        
          The choice of pt_BR is just an example. You can delete those lines
          or replace them by corresponding ones in your locale, e.g. fr_FR,
          with the "Name[fr_FR]" and "Comment[fr_FR]" values given by your
          translations.
        
       
      
        
          Command Explanations
        
        
          ./autogen.sh: This
          command forces rebuilding of auto-generated files to account for
          new options added to configure.
        
        
          --with-jdk-home: This
          switch provides the location of the temporary JDK.
        
        
          --with-pkgversion: This switch can be
          used to modify the version string in addition to "IcedTea".
        
        
          --with-version-suffix: This
          switch appends the given text to the JDK version string.
        
        
          --enable-nss: Enable
          inclusion of NSS security provider.
        
        
          --disable-system-kerberos:
          Remove this switch if MIT Kerberos V5-1.12.2 is
          installed.
        
        
          --with-parallel-jobs:
          Allows to set the number of jobs for make equal to the number of
          processors plus one. Note that the default is 2 if this option is
          not specified. You have to explicitely set --with-parallel-jobs=1 to disable parallel jobs.
          The SBU given above are with parallel jobs disabled.
        
        
          chmod -v 0644
          ...sa-jdi.jar: Fix permissions in a generated file
          so all users can access it.
        
       
      
        
          Configuring
          OpenJDK
        
        
          
            Configuration Information
          
          
            There are now two OpenJDK SDKs
            installed in /opt. You should
            decide on which one you would like to use as the default. For
            example if you decide to use the precompiled OpenJDK, do the following as the
            root user:
          
          
ln -sfv OpenJDK-1.7.0.65-bin /opt/jdk
          
            The information below assumes your system is set up using the
            instructions found in “The Bash Shell Startup
            Files”. You may need to extract the relevant
            information below and incorporate it into your system's startup
            files if your system is set up differently.
          
          
            Add the following openjdk.sh shell
            startup file to the /etc/profile.d
            directory with the following commands as the root user:
          
          
cat >> /etc/profile.d/openjdk.sh << "EOF"
# Begin /etc/profile.d/openjdk.sh
# Set JAVA_HOME directory
JAVA_HOME=/opt/jdk
# Adjust PATH
pathappend $JAVA_HOME/bin PATH
pathappend $JAVA_HOME/include       C_INCLUDE_PATH
pathappend $JAVA_HOME/include/linux C_INCLUDE_PATH
pathappend $JAVA_HOME/include       CPLUS_INCLUDE_PATH
pathappend $JAVA_HOME/include/linux CPLUS_INCLUDE_PATH
# Auto Java CLASSPATH
# Copy jar files to, or create symlinks in this directory
AUTO_CLASSPATH_DIR=/usr/share/java
pathprepend . CLASSPATH
for dir in `find ${AUTO_CLASSPATH_DIR} -type d 2>/dev/null`; do
    pathappend $dir CLASSPATH
done
for jar in `find ${AUTO_CLASSPATH_DIR} -name "*.jar" 2>/dev/null`; do
    pathappend $jar CLASSPATH
done
export JAVA_HOME CLASSPATH C_INCLUDE_PATH CPLUS_INCLUDE_PATH
unset AUTO_CLASSPATH_DIR dir jar
# End /etc/profile.d/openjdk.sh
EOF
          
            Finally, add the man pages to man_db's configuration. As the root user:
          
          
cat >> /etc/profile.d/extrapaths.sh << "EOF" &&
# Begin Java addition
pathappend /opt/jdk/man       MANPATH
# End Java addition
EOF
cat >> /etc/man_db.conf << "EOF" &&
# Begin Java addition
MANDATORY_MANPATH     /opt/jdk/man
MANPATH_MAP           /opt/jdk/bin     /opt/jdk/man
MANDB_MAP             /opt/jdk/man     /var/cache/man/jdk
# End Java addition
EOF
mandb -c /opt/jdk/man
          
            To test the man pages are correctly installed, issue source /etc/profile and
            man java to display
            the respective man page.
          
         
        
          
            Install or update the
            JRE Certificate Authority Certificates (cacerts) file
          
          
            Use the following procedure to check if the cacerts file was successfully installed during
            the OpenJDK build. Also, if the Certificate Authority
            Certificates have been updated, the following instructions
            will generate a new JRE cacerts
            file. First, check if the cacerts
            have been successfully installed:
          
          
cd /opt/jdk
bin/keytool -list -keystore jre/lib/security/cacerts
          
            At the prompt "Enter keystore password:", press the "Enter" key
            if there is no keystore password defined. If the cacerts were installed correctly, you will see
            a list of the certificates with related information for each one.
            If not, you need to manually install them. First, generate the
            mkcacerts script as
            the root user:
          
          
cat > /opt/jdk/bin/mkcacerts << "EOF"
#!/bin/sh
# Simple script to extract x509 certificates and create a JRE cacerts file.
function get_args()
    {
        if test -z "${1}" ; then
            showhelp
            exit 1
        fi
        while test -n "${1}" ; do
            case "${1}" in
                -f | --cafile)
                    check_arg $1 $2
                    CAFILE="${2}"
                    shift 2
                    ;;
                -d | --cadir)
                    check_arg $1 $2
                    CADIR="${2}"
                    shift 2
                    ;;
                -o | --outfile)
                    check_arg $1 $2
                    OUTFILE="${2}"
                    shift 2
                    ;;
                -k | --keytool)
                    check_arg $1 $2
                    KEYTOOL="${2}"
                    shift 2
                    ;;
                -s | --openssl)
                    check_arg $1 $2
                    OPENSSL="${2}"
                    shift 2
                    ;;
                -h | --help)
                    showhelp
                    exit 0
                    ;;
                *)
                    showhelp
                    exit 1
                    ;;
            esac
        done
    }
function check_arg()
    {
        echo "${2}" | grep -v "^-" > /dev/null
        if [ -z "$?" -o ! -n "$2" ]; then
            echo "Error:  $1 requires a valid argument."
            exit 1
        fi
    }
# The date binary is not reliable on 32bit systems for dates after 2038
function mydate()
    {
        local y=$( echo $1 | cut -d" " -f4 )
        local M=$( echo $1 | cut -d" " -f1 )
        local d=$( echo $1 | cut -d" " -f2 )
        local m
        if [ ${d} -lt 10 ]; then d="0${d}"; fi
        case $M in
            Jan) m="01";;
            Feb) m="02";;
            Mar) m="03";;
            Apr) m="04";;
            May) m="05";;
            Jun) m="06";;
            Jul) m="07";;
            Aug) m="08";;
            Sep) m="09";;
            Oct) m="10";;
            Nov) m="11";;
            Dec) m="12";;
        esac
        certdate="${y}${m}${d}"
    }
function showhelp()
    {
        echo "`basename ${0}` creates a valid cacerts file for use with IcedTea."
        echo ""
        echo "        -f  --cafile        The path to a file containing PEM formated CA"
        echo "                            certificates.  May not be used with -d/--cadir."
        echo "        -d  --cadir         The path to a diectory of PEM formatted CA"
        echo "                            certificates.  May not be used with -f/--cafile."
        echo "        -o  --outfile       The path to the output file."
        echo ""
        echo "        -k  --keytool       The path to the java keytool utility."
        echo ""
        echo "        -s  --openssl       The path to the openssl utility."
        echo ""
        echo "        -h  --help          Show this help message and exit."
        echo ""
        echo ""
    }
# Initialize empty variables so that the shell does not pollute the script
CAFILE=""
CADIR=""
OUTFILE=""
OPENSSL=""
KEYTOOL=""
certdate=""
date=""
today=$( date +%Y%m%d )
# Process command line arguments
get_args ${@}
# Handle common errors
if test "${CAFILE}x" == "x" -a "${CADIR}x" == "x" ; then
    echo "ERROR!  You must provide an x509 certificate store!"
    echo "\'$(basename ${0}) --help\' for more info."
    echo ""
    exit 1
fi
if test "${CAFILE}x" != "x" -a "${CADIR}x" != "x" ; then
    echo "ERROR!  You cannot provide two x509 certificate stores!"
    echo "\'$(basename ${0}) --help\' for more info."
    echo ""
    exit 1
fi
if test "${KEYTOOL}x" == "x" ; then
    echo "ERROR!  You must provide a valid keytool program!"
    echo "\'$(basename ${0}) --help\' for more info."
    echo ""
    exit 1
fi
if test "${OPENSSL}x" == "x" ; then
    echo "ERROR!  You must provide a valid path to openssl!"
    echo "\'$(basename ${0}) --help\' for more info."
    echo ""
    exit 1
fi
if test "${OUTFILE}x" == "x" ; then
    echo "ERROR!  You must provide a valid output file!"
    echo "\'$(basename ${0}) --help\' for more info."
    echo ""
    exit 1
fi
# Get on with the work
# If using a CAFILE, split it into individual files in a temp directory
if test "${CAFILE}x" != "x" ; then
    TEMPDIR=`mktemp -d`
    CADIR="${TEMPDIR}"
    # Get a list of staring lines for each cert
    CERTLIST=`grep -n "^-----BEGIN" "${CAFILE}" | cut -d ":" -f 1`
    # Get a list of ending lines for each cert
    ENDCERTLIST=`grep -n "^-----END" "${CAFILE}" | cut -d ":" -f 1`
    # Start a loop
    for certbegin in `echo "${CERTLIST}"` ; do
        for certend in `echo "${ENDCERTLIST}"` ; do
            if test "${certend}" -gt "${certbegin}"; then
                break
            fi
        done
        sed -n "${certbegin},${certend}p" "${CAFILE}" > "${CADIR}/${certbegin}.pem"
        keyhash=`${OPENSSL} x509 -noout -in "${CADIR}/${certbegin}.pem" -hash`
        echo "Generated PEM file with hash:  ${keyhash}."
    done
fi
# Write the output file
for cert in `find "${CADIR}" -type f -name "*.pem" -o -name "*.crt"`
do
    # Make sure the certificate date is valid...
    date=$( ${OPENSSL} x509 -enddate -in "${cert}" -noout | sed 's/^notAfter=//' )
    mydate "${date}"
    if test "${certdate}" -lt "${today}" ; then
        echo "${cert} expired on ${certdate}! Skipping..."
        unset date certdate
        continue
    fi
    unset date certdate
    ls "${cert}"
    tempfile=`mktemp`
    certbegin=`grep -n "^-----BEGIN" "${cert}" | cut -d ":" -f 1`
    certend=`grep -n "^-----END" "${cert}" | cut -d ":" -f 1`
    sed -n "${certbegin},${certend}p" "${cert}" > "${tempfile}"
    echo yes | env LC_ALL=C "${KEYTOOL}" -import -alias `basename "${cert}"` -keystore \
                   "${OUTFILE}" -storepass 'changeit' -file "${tempfile}"
    rm "${tempfile}"
done
if test "${TEMPDIR}x" != "x" ; then
    rm -rf "${TEMPDIR}"
fi
exit 0
EOF
chmod -c 0755 /opt/jdk/bin/mkcacerts
          
            
            
              Note
            
            
              Doing a very large copy/paste directly to a terminal may result
              in a corrupted file. Copying to an editor may overcome this
              issue.
            
           
          
            If you need to generate a cacerts
            file, and there is already one in /opt/jdk/jre/lib/security, it is better to make
            a backup. Then, you can create a new one, as the root user:
          
          
/opt/jdk/bin/mkcacerts -d "/etc/ssl/certs/"  -k "/opt/jdk/bin/keytool" \
                       -s "/usr/bin/openssl" -o "/opt/jdk/jre/lib/security/cacerts"