Introduction to OpenJDK
        
        
          OpenJDK is an open-source
          implementation of Oracle's Java Standard Edition platform.
          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.10
          platform.
        
        
          ![[Note]](../images/note.png) 
          
            Note
          
          
            A browser plugin and webstart implementation, as well as a
            pulseaudio sound backend are provided by the Icedtea project. To
            provide a complete implementation, you will need to later install
            IcedTea-Web-1.6.2 and IcedTea-Sound-1.0.1.
          
         
        
          OpenJDK is GPL'd code, with 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]](../images/note.png) 
          
            Note
          
          
            The OpenJDK source includes a
            very thorough, open source test suite using the JTreg test harness. The testing instructions
            below allow to test the just built JDK for reasonable
            compatibility with the proprietary Oracle JDK. However, in order
            for an independent implementation to claim compatibility, it must
            pass a proprietary 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. Neither the binary version provided on the
            Java-1.8.0.102 page nor the JVM built with
            the instructions below have 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
        
        
          
            - 
              
                OpenJDK Root Package
 Download: 
                http://hg.openjdk.java.net/jdk8u/jdk8u/archive/jdk8u102-b14.tar.bz2
 Download MD5 sum: 04ecdce899eb3d6de9d5aadc438998c0
 Download Size: 400 KB
 
 
- 
              
                In addition to the root package, the instructions below first
                download seven subproject tarballs, whose total size is 63
                MB.
               
- 
              
                Estimated disk space required: 3.5 GB (additional 410 MB for
                tests)
               
- 
              
                Estimated build time: 4 SBU with 4 jobs in parallel
                (additional 63 SBU for tests)
               
 
        
          Additional Downloads
        
        
        
          OpenJDK Dependencies
        
        
          Required Dependencies
        
        
          An existing binary (Java-1.8.0.102 or an earlier built version of
          this package. The instructions below assume that you are using
          Configuring the JAVA
          environment), alsa-lib-1.1.2, cpio-2.12, Cups-2.1.4, UnZip-6.0, Which-2.21, Xorg Libraries, and
          Zip-3.0
        
        
          Recommended
        
        
          Certificate Authority
          Certificates, giflib-5.1.4, and Wget-1.18
        
        
          Optional
        
        
          Mercurial-3.9 and an X Window manager such as
          twm-1.0.9 (for the tests)
        
        
          User Notes: http://wiki.linuxfromscratch.org/blfs/wiki/openjdk
        
       
      
        
          Installation of OpenJDK
        
        
          Unlike other packages in BLFS, the OpenJDK source packages are distributed in
          multiple tar balls. You need to first extract the source root from
          jdk8u102-b14.tar.bz2, change into the
          extracted directory, then proceed with the following instructions:
        
        
cat > subprojects.md5 << EOF &&
6ea4a074a80d0ee4b6dcd50398835c49  corba.tar.bz2
27b9e7e94fc6a47f452e8a94ba156395  hotspot.tar.bz2
da82a91df3eb4c98ebaab4e71cbbcc4d  jaxp.tar.bz2
8a91561bbc04f50a92032d82b78960e0  jaxws.tar.bz2
61c645dbacfb925944f716ec50474821  langtools.tar.bz2
e65f6d029808a8b523e07d818c8ac9ad  jdk.tar.bz2
2c981235c1cbaba58197fd9b7ffd00e1  nashorn.tar.bz2
EOF
for subproject in corba hotspot jaxp jaxws langtools jdk nashorn; do
  wget -c http://hg.openjdk.java.net/jdk8u/jdk8u/${subproject}/archive/jdk8u102-b14.tar.bz2 \
       -O ${subproject}.tar.bz2
done &&
md5sum -c subprojects.md5 &&
for subproject in corba hotspot jaxp jaxws langtools jdk nashorn; do
  mkdir -pv ${subproject} &&
  tar -xf ${subproject}.tar.bz2 --strip-components=1 -C ${subproject}
done
        
          If you have downloaded the optional test harness, unpack it too:
        
        
tar -xf ../jtreg-4.2-b03-639.tar.gz
        
          ![[Note]](../images/note.png) 
          
            Note
          
          
            Before proceeding, you should ensure that your environment
            PATH variable contains the location of
            the Java compilers used for bootstrapping OpenJDK. This is the only requirement for
            the environment. Modern Java installations do not need
            JAVA_HOME and CLASSPATH is not used here. Furthermore, OpenJDK
            developers recommend to unset JAVA_HOME.
          
          
            The build system does not support the -j switch in MAKEFLAGS.
          
         
        
          Configure and build the package with the following commands
          (--with-milestone value can be modified to fit user preferences):
        
        
unset JAVA_HOME               &&
sh ./configure                \
   --with-update-version=102   \
   --with-build-number=b14    \
   --with-milestone=BLFS      \
   --enable-unlimited-crypto  \
   --with-zlib=system         \
   --with-giflib=system       \
   --with-extra-cflags="-std=c++98 -Wno-error -fno-delete-null-pointer-checks -fno-lifetime-dse" \
   --with-extra-cxxflags="-std=c++98 -fno-delete-null-pointer-checks -fno-lifetime-dse" &&
make DEBUG_BINARIES=true SCTP_WERROR= all  &&
find build/*/images/j2sdk-image -iname \*.diz -delete
        
          ![[Note]](../images/note.png) 
          
            Note
          
          
            Testing will involve the interplay of pairs of JVMs using the
            networking interface, so networking must be started. If it isn't,
            not only will these tests fail, but the test cleanup will leave
            orphaned JVMs running. There will be many of them. Rebooting may
            be the easiest recovery.
          
         
        
          Testing the newly built JVM involves several steps. First, it is
          better to run the test suite in a frame buffer on a different
          display, using Xvfb:
        
        
if [ -n "$DISPLAY" ]; then
  OLD_DISP=$DISPLAY
fi
export DISPLAY=:20
nohup Xvfb $DISPLAY                              \
           -fbdir $(pwd)                         \
           -pixdepths 8 16 24 32 > Xvfb.out 2>&1 &
echo $! > Xvfb.pid
echo Waiting for Xvfb to initialize; sleep 1
nohup twm -display $DISPLAY \
          -f /dev/null > twm.out 2>&1            &
echo $! > twm.pid
echo Waiting for twm to initialize; sleep 1
xhost +
        
          Then, it is necessary to modify some files:
        
        
echo -e "
jdk_all = :jdk_core           \\
          :jdk_svc            \\
          :jdk_beans          \\
          :jdk_imageio        \\
          :jdk_sound          \\
          :jdk_sctp           \\
          com/sun/awt         \\
          javax/accessibility \\
          javax/print         \\
          sun/pisces          \\
          com/sun/java/swing" >> jdk/test/TEST.groups &&
sed -e 's/all:.*jck.*/all: jtreg/'      \
    -e '/^JTREG /s@\$(JT_PLATFORM)/@@'  \
    -i langtools/test/Makefile
        
          Some variables have to be set:
        
        
JT_JAVA=$(type -p javac | sed 's@/bin.*@@') &&
JT_HOME=$(pwd)/jtreg                        &&
PRODUCT_HOME=$(echo $(pwd)/build/*/images/j2sdk-image)
        
          The tests are run as follows:
        
        
LANG=C make -k -C test                      \
            JT_HOME=${JT_HOME}              \
            JT_JAVA=${JT_JAVA}              \
            PRODUCT_HOME=${PRODUCT_HOME} all
LANG=C ${JT_HOME}/bin/jtreg -a -v:fail,error \
                -dir:$(pwd)/hotspot/test     \
                -k:\!ignore                  \
                -jdk:${PRODUCT_HOME}         \
                :jdk
        
          The test results can be compared to these
          results, although they usually are run on a newer version. Some
          failures can be expected, the number of which depends on various
          conditions, like whether the computer is connected to network.
          Also, some tests may timeout if the machine is under load. Those
          are the reasons for considering the tests optional, although we
          would rather recommend them.
        
        
          Next some cleanup has to be done. The instructions below only stop
          the frame buffer, but it has been reported that some java VM may be
          left running after the tests, so it is necessary to check orphaned
          processes:
        
        
kill -9 `cat twm.pid`  &&
kill -9 `cat Xvfb.pid` &&
rm -f Xvfb.out twm.out &&
rm -f Xvfb.pid twm.pid &&
if [ -n "$OLD_DISP" ]; then
  DISPLAY=$OLD_DISP
fi
        
          Install the package with the following commands as the root user:
        
        
cp -RT build/*/images/j2sdk-image /opt/OpenJDK-1.8.0.102 &&
chown -R root:root /opt/OpenJDK-1.8.0.102
        
          There are now two OpenJDK SDKs
          installed in /opt. You should decide
          on which one you would like to use as the default. Normally, you
          would opt for the just installed OpenJDK. If so, do the following as the
          root user:
        
        
ln -v -nsf OpenJDK-1.8.0.102 /opt/jdk
        
          If desired, you may install a .desktop file corresponding to an
          entry in a desktop menu for policytool. First, you need to
          obtain an icon from IcedTea-Web-1.6.2:
        
        
tar -xf ../icedtea-web-1.6.2.tar.gz  \
        icedtea-web-1.6.2/javaws.png \
        --strip-components=1
        
          Now, as root user:
        
        
mkdir -pv /usr/share/applications &&
cat > /usr/share/applications/openjdk-8-policytool.desktop << "EOF" &&
[Desktop Entry]
Name=OpenJDK Java Policy Tool
Name[pt_BR]=OpenJDK Java - Ferramenta de Política
Comment=OpenJDK Java Policy Tool
Comment[pt_BR]=OpenJDK Java - Ferramenta de Política
Exec=/opt/jdk/bin/policytool
Terminal=false
Type=Application
Icon=javaws
Categories=Settings;
EOF
install -v -Dm0644 javaws.png /usr/share/pixmaps/javaws.png
        
          The choice of pt_BR is just an example. You can add any translation
          by adding lines corresponding to your locale, e.g. for fr_FR,
          “Name[fr_FR]=” and
          “Comment[fr_FR]=” with the
          appropriate text as values.
        
       
      
        
          Command Explanations
        
        
          sh configure...: the
          top level configure is a wrapper
          around the autotools one. It is not executable and must be run
          through sh.
        
        
          --with-boot-jdk: This switch provides
          the location of the temporary JDK.
          It is normally not needed if java is found in the PATH.
        
        
          --with-update-version:
          Currently, the build system does not include the update number in
          the version string. It has to be specified here.
        
        
          --with-build-number: Again,
          the build system does not include the build number in the version
          string. It has to be specified here too.
        
        
          --with-milestone: Used to
          customize the version string.
        
        
          --enable-unlimited-crypto:
          Because of limitations on the usage of cryptography in some
          countries, there is the possibility to limit the size of encryption
          keys and the use of some algorithms in a policy file. This switch
          allows to ship a policy file with no restriction. It is the
          responsibility of the user to ensure proper adherence to the law.
        
        
          --with-zlib=system,
          --with-giflib=system: Allows to use the system
          libraries instead of the bundled ones.
        
        
          --with-extra-cflags=...
          --with-extra-cxxflags=...: Works around some defects in
          the code brought to light by the GCC 6 more rigorous checking of
          the C/C++ constructs. Remove those switches if compiling with GCC
          5.
        
        
          --with-jobs=N: Allows setting the
          number of jobs for make equal to N. The default is
          the result of a calculation involving the available memory and the
          number of processors. Note that even if you specify N=1, some
          parallelization may be used during the build. The SBU given above
          are with N=4, on a single processor, 4-core, virtual machine, with
          4 GB of memory.
        
        
          --with-cacerts-file=...: Specifies
          where to find a cacerts file,
          typically /opt/jdk/jre/lib/security.
          Otherwise, an empty one is created. You can get it from an earlier
          version of the package, or use the script below to generate one.
        
        
          make DEBUG_BINARIES=true SCTP_WERROR=
          all: The build fails on 32 bit machines if
          DEBUG_BINARIES is not set to true. Unsetting SCTP_WERROR is part of
          the workarounds needed to use GCC 6. You may omit that part of the
          command if using GCC 5.
        
        
          find ... -iname '*.diz'
          -delete: This command removes redundant files.
        
       
      
        
          Configuring
          OpenJDK
        
        
          
            Configuration Information
          
          
            Normally, the JAVA environment has been configured after
            installing the binary version, and can be used with the just
            built package as well. Review Configuring the JAVA
            environment in case you want to modify something.
          
          
            To test if 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
          
          
            OpenJDK uses its own format for
            the CA certificates. Those certificates are located in a file
            named /opt/jdk/jre/lib/security/cacerts. That file
            may be generated from the one installed using the instructions on
            the Certificate Authority
            Certificates page, with the following procedure. 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"
        echo "                         formated CA certificates. May not be"
        echo "                         used with -d/--cadir."
        echo ""
        echo "        -d  --cadir      The path to a directory of PEM formatted"
        echo "                         CA certificates. May not be used with"
        echo "                         -f/--cafile."
        echo ""
        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]](../images/note.png) 
            
              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.
            
           
          
            Generate the OpenJDK
            cacerts file as the root user:
          
          
if [ -f /opt/jdk/jre/lib/security/cacerts ]; then
  mv /opt/jdk/jre/lib/security/cacerts \
     /opt/jdk/jre/lib/security/cacerts.bak
fi &&
/opt/jdk/bin/mkcacerts                 \
        -d "/etc/ssl/certs/"           \
        -k "/opt/jdk/bin/keytool"      \
        -s "/usr/bin/openssl"          \
        -o "/opt/jdk/jre/lib/security/cacerts"
          
            Use the following commands to check if the cacerts file has 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 file was installed correctly, you will
            see a list of the certificates with related information for each
            one. If not, you need to reinstall them.