Friday, February 10, 2017

How the NumericalChameleon Installer obtains the latest JRE for Windows

Today I will explain how the NumericalChameleon installer obtains the latest Java Runtime Environment (JRE) for Microsoft Windows.

The NumericalChameleon (http://numericalchameleon.net) is written in Java and it relies on a JRE that is installed on your system. The NumericalChameleon installer checks at first whether a JRE is installed. If there is one, everything is fine and the installer will continue with a normal installation. If there is none, the installer downloads the latest JRE offline installer from Oracle and launches it. The offline installer installs the JRE on your system and once it is installed, it will give back the control to the NumericalChameleon installer that continues with the installation until the NumericalChameleon software package is installed as well.

Below you find a screenshot of the NumericalChameleon installer, localized in German, running on Windows 10 x64 while downloading the latest JRE offline installer:



Since the actual locations of the JRE offline exe installers are different for each Java version, and those locations are both unpredictable and volatile, it is important for the NumericalChameleon installer to rely on well known static URIs, because the installer binary cannot be changed/patched anymore once it is deployed on the web.

Those well known URIs are redirects in the .htaccess file on my Apache server actually, and the redirects are being updated every day. I create those redirects by parsing the website that has the locations of the Windows JRE offline installers.

$ cat bin/update_htaccess
#!/bin/bash
HTACCESS="$HOME/numericalchameleon/.htaccess"
STATIC="$HOME/numericalchameleon/.htaccess.static"

cat $STATIC > $HTACCESS

# the locations of the JRE offline installers
URL="https://www.java.com/en/download/manual.jsp"
CONTENT=$(curl -s "$URL")

IDENTIFIER="Windows Offline</a>"
if [[ "$CONTENT" =~ BundleId=([^\"]+)\"\>[[:space:]]*"$IDENTIFIER" ]]; then
    printf "Redirect /get_java_win32bit http://javadl.oracle.com/webapps/download/AutoDL?BundleId=%s\n" ${BASH_REMATCH[1]} >> $HTACCESS
fi

IDENTIFIER="Windows Offline (64-bit)</a>"
if [[ "$CONTENT" =~ BundleId=([^\"]+)\"\>[[:space:]]*"$IDENTIFIER" ]]; then
    printf "Redirect /get_java_win64bit http://javadl.oracle.com/webapps/download/AutoDL?BundleId=%s\n" ${BASH_REMATCH[1]} >> $HTACCESS
fi

The .htaccess.static file just contains entries that never change. The update_htaccess script runs by cron periodically on the server in order to have entries that are up to date.

$ crontab -l | tail -1

9 3 * * * cd bin; ./update_htaccess

After the cron was running, updated redirects can be found in the .htaccess file. In the example below the redirects are from Java 8u121:

$ tail -2 .htaccess

Redirect /get_java_win32bit http://javadl.oracle.com/webapps/download/AutoDL?BundleId=218831_e9e7ea248e2c4826b92b3f075a80e441
Redirect /get_java_win64bit http://javadl.oracle.com/webapps/download/AutoDL?BundleId=218833_e9e7ea248e2c4826b92b3f075a80e441

The installer can now rely on the fixed addresses below, dependent whether a 32 bit or a 64 bit system has been found:
Now you know how the NumericalChameleon installer gets the latest JRE on Windows.

Hint: if the approach above should ever fail and the redirects are not being created, the current installer will fail with a 404. In that case you can simply install the JRE manually before you start the NumericalChameleon installer. In that case the installer won't even go to the internet, because the condition is met already that a JRE has to be installed.