Advertisement
khongi

install-jdk.sh

Nov 24th, 2020
1,080
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 9.25 KB | None | 0 0
  1. #!/usr/bin/env bash
  2.  
  3. #
  4. # Install JDK for Linux and Mac OS
  5. #
  6. # This script determines the most recent early-access build number,
  7. # downloads the JDK archive to the user home directory and extracts
  8. # it there.
  9. #
  10. # Exported environment variables (when sourcing this script)
  11. #
  12. #   JAVA_HOME is set to the extracted JDK directory
  13. #   PATH is prepended with ${JAVA_HOME}/bin
  14. #
  15. # (C) 2020 Christian Stein
  16. #
  17. # https://github.com/sormuras/bach/blob/master/install-jdk.sh
  18. #
  19.  
  20. set -o errexit
  21. #set -o nounset # https://github.com/travis-ci/travis-ci/issues/5434
  22. #set -o xtrace
  23.  
  24. function initialize() {
  25.     readonly script_name="$(basename "${BASH_SOURCE[0]}")"
  26.     readonly script_version='2020-06-02'
  27.  
  28.     dry=false
  29.     silent=false
  30.     verbose=false
  31.     emit_java_home=false
  32.     emit_url=false
  33.  
  34.     feature='ea'
  35.     license='GPL' # Force GPLv2+CE
  36.     os='?'
  37.     url='?'
  38.     workspace="${HOME}"
  39.     target='?'
  40.     cacerts=false
  41. }
  42.  
  43. function usage() {
  44. cat << EOF
  45. Usage: ${script_name} [OPTION]...
  46. Download and extract latest-and-greatest JDK from https://jdk.java.net
  47.  
  48. Version: ${script_version}
  49. Options:
  50.   -h|--help                 Displays this help
  51.   -d|--dry-run              Activates dry-run mode
  52.   -s|--silent               Displays no output
  53.   -e|--emit-java-home       Print value of "JAVA_HOME" to stdout (ignores silent mode)
  54.      --emit-url             Print value of "url" to stdout (ignores silent mode)
  55.   -v|--verbose              Displays verbose output
  56.  
  57.   -f|--feature ea|16|...|9  JDK feature release number, defaults to "ea"
  58.   -o|--os linux-x64|osx-x64 Operating system identifier
  59.   -u|--url "https://..."    Use custom JDK archive (provided as .tar.gz file)
  60.   -w|--workspace PATH       Working directory defaults to \${HOME} [${HOME}]
  61.   -t|--target PATH          Target directory, defaults to first component of the tarball
  62.   -c|--cacerts              Link system CA certificates (currently only Debian/Ubuntu is supported)
  63. EOF
  64. }
  65.  
  66. function script_exit() {
  67.     if [[ $# -eq 1 ]]; then
  68.         printf '%s\n' "$1"
  69.         exit 0
  70.     fi
  71.  
  72.     if [[ $# -eq 2 && $2 =~ ^[0-9]+$ ]]; then
  73.         printf '%b\n' "$1"
  74.         exit "$2"
  75.     fi
  76.  
  77.     script_exit 'Invalid arguments passed to script_exit()!' 2
  78. }
  79.  
  80. function say() {
  81.     if [[ ${silent} != true ]]; then
  82.         echo "$@"
  83.     fi
  84. }
  85.  
  86. function verbose() {
  87.     if [[ ${verbose} == true ]]; then
  88.         echo "$@"
  89.     fi
  90. }
  91.  
  92. function parse_options() {
  93.     local option
  94.     while [[ $# -gt 0 ]]; do
  95.         option="$1"
  96.         shift
  97.         case ${option} in
  98.             -h|-H|--help)
  99.                 usage
  100.                 exit 0
  101.                 ;;
  102.             -v|-V|--verbose)
  103.                 verbose=true
  104.                 ;;
  105.             -s|-S|--silent)
  106.                 silent=true
  107.                 verbose "Silent mode activated"
  108.                 ;;
  109.             -d|-D|--dry-run)
  110.                 dry=true
  111.                 verbose "Dry-run mode activated"
  112.                 ;;
  113.             -e|-E|--emit-java-home)
  114.                 emit_java_home=true
  115.                 verbose "Emit JAVA_HOME"
  116.                 ;;
  117.             --emit-url)
  118.                 emit_url=true
  119.                 verbose "Emit download URL"
  120.                 ;;
  121.             -f|-F|--feature)
  122.                 feature="$1"
  123.                 verbose "feature=${feature}"
  124.                 shift
  125.                 ;;
  126.             -l|-L|--license)
  127.                 # license="$1"
  128.                 say "Ignoring license option: $1 -- using GPLv2+CE by default"
  129.                 verbose "license=${license}"
  130.                 shift
  131.                 ;;
  132.             -o|-O|--os)
  133.                 os="$1"
  134.                 verbose "os=${os}"
  135.                 shift
  136.                 ;;
  137.             -u|-U|--url)
  138.                 url="$1"
  139.                 verbose "url=${url}"
  140.                 shift
  141.                 ;;
  142.             -w|-W|--workspace)
  143.                 workspace="$1"
  144.                 verbose "workspace=${workspace}"
  145.                 shift
  146.                 ;;
  147.             -t|-T|--target)
  148.                 target="$1"
  149.                 verbose "target=${target}"
  150.                 shift
  151.                 ;;
  152.             -c|-C|--cacerts)
  153.                 cacerts=true
  154.                 verbose "Linking system CA certificates"
  155.                 ;;
  156.             *)
  157.                 script_exit "Invalid argument was provided: ${option}" 2
  158.                 ;;
  159.         esac
  160.     done
  161. }
  162.  
  163. function determine_latest_jdk() {
  164.     local number
  165.     local curl_result
  166.     local url
  167.  
  168.     number=15
  169.     verbose "Determine latest JDK feature release number, starting with ${number}"
  170.     while [[ ${number} != 99 ]]
  171.     do
  172.       url="https://jdk.java.net/${number}"
  173.       curl_result=$(curl -o /dev/null --silent --head --write-out %{http_code} ${url})
  174.       if [[ ${curl_result} -ge 400 ]]; then
  175.         break
  176.       fi
  177.       verbose "  Found ${url} [${curl_result}]"
  178.       latest_jdk=${number}
  179.       number=$[$number +1]
  180.     done
  181.  
  182.     verbose "Latest JDK feature release number is: ${latest_jdk}"
  183. }
  184.  
  185. function perform_sanity_checks() {
  186.     if [[ ${feature} == '?' ]] || [[ ${feature} == 'ea' ]]; then
  187.         feature=${latest_jdk}
  188.     fi
  189.     if [[ ${feature} -lt 9 ]] || [[ ${feature} -gt ${latest_jdk} ]]; then
  190.         script_exit "Expected feature release number in range of 9 to ${latest_jdk}, but got: ${feature}" 3
  191.     fi
  192.     if [[ -d "$target" ]]; then
  193.         script_exit "Target directory must not exist, but it does: $(du -hs '${target}')" 3
  194.     fi
  195. }
  196.  
  197. function determine_url() {
  198.     local properties='https://github.com/sormuras/bach/raw/master/install-jdk.properties'
  199.     url=$(wget --quiet --output-document - ${properties} | grep -i "${feature}-${os}=" | awk -F "=" '{print $2}')
  200.  
  201.     if [[ -z ${url} ]]; then
  202.         script_exit "Couldn't determine a download url for ${feature}-${license} on ${os}" 1
  203.     fi
  204. }
  205.  
  206. function prepare_variables() {
  207.     if [[ ${os} == '?' ]]; then
  208.         if [[ "$OSTYPE" == "darwin"* ]]; then
  209.           os='osx-x64'
  210.         else
  211.           os='linux-x64'
  212.         fi
  213.     fi
  214.     if [[ ${url} == '?' ]]; then
  215.         determine_latest_jdk
  216.         perform_sanity_checks
  217.         determine_url
  218.     else
  219.         feature='<overridden by custom url>'
  220.         license='<overridden by custom url>'
  221.         os='<overridden by custom url>'
  222.     fi
  223.     status=$(curl -o /dev/null --silent --head --write-out %{http_code} ${url})
  224. }
  225.  
  226. function print_variables() {
  227. cat << EOF
  228. Variables:
  229.   feature = ${feature}
  230.        os = ${os}
  231.       url = ${url}
  232.    status = ${status}
  233. EOF
  234. }
  235.  
  236. function download_and_extract_and_set_target() {
  237.     local quiet='--quiet'; if [[ ${verbose} == true ]]; then quiet=''; fi
  238.     local local="--directory-prefix ${workspace} --output-document=jdk.tar.gz"
  239.     local remote='--timestamping --continue'
  240.     local wget_options="${quiet} ${local} ${remote}"
  241.     local tar_options="--file jdk.tar.gz"
  242.  
  243.     say "Downloading JDK from ${url}..."
  244.     verbose "Using wget options: ${wget_options}"
  245.     wget ${wget_options} ${url}
  246.  
  247.     if [[ ${os} == 'windows-x64' ]]; then
  248.         script_exit "Extracting archives on Windows isn't supported, yet" 4
  249.     fi
  250.  
  251.     verbose "Using tar options: ${tar_options}"
  252.     if [[ ${target} == '?' ]]; then
  253.         tar --extract ${tar_options} -C "${workspace}"
  254.         if [[ "$OSTYPE" != "darwin"* ]]; then
  255.             target="${workspace}"/$(tar --list ${tar_options} | grep 'bin/javac' | tr '/' '\n' | tail -3 | head -1)
  256.         else
  257.             target="${workspace}"/$(tar --list ${tar_options} | head -2 | tail -1 | cut -f 2 -d '/' -)/Contents/Home
  258.         fi
  259.         verbose "Set target to: ${target}"
  260.     else
  261.         echo "Using custom target: ${target}"
  262.         if [[ "$OSTYPE" != "darwin"* ]]; then
  263.             mkdir --parents "${target}"
  264.             tar --extract ${tar_options} -C "${target}" --strip-components=1
  265.         else
  266.             mkdir -p "${target}"
  267.             tar --extract ${tar_options} -C "${target}" --strip-components=4
  268.         fi
  269.     fi
  270.  
  271.     if [[ ${verbose} == true ]]; then
  272.         echo "Content of target directory:"
  273.         ls "${target}"
  274.         echo "Content of release file:"
  275.         [[ ! -f "${target}/release" ]] || cat "${target}/release"
  276.     fi
  277.  
  278.     # Link to system certificates
  279.     # https://openjdk.java.net/jeps/319
  280.     # https://bugs.openjdk.java.net/browse/JDK-8196141
  281.     if [[ ${cacerts} == true ]]; then
  282.         local directory="${target}/lib/security/cacerts"
  283.         if [[ -f "${directory}" ]]; then
  284.             mv "${directory}" "${directory}.jdk"
  285.             ln -s /etc/ssl/certs/java/cacerts "${directory}"
  286.         else
  287.             verbose "Directory ${directory} doesn't exist, didn't link system CA certificates."
  288.         fi
  289.     fi
  290. }
  291.  
  292. function main() {
  293.     initialize
  294.     parse_options "$@"
  295.  
  296.     say "$script_name $script_version"
  297.     prepare_variables
  298.  
  299.     if [[ ${silent} == false ]]; then print_variables; fi
  300.     if [[ ${emit_url} == true ]]; then echo "${url}"; fi
  301.     if [[ ${dry} == true ]]; then exit 0; fi
  302.  
  303.     download_and_extract_and_set_target
  304.  
  305.     export JAVA_HOME=$(cd "${target}"; pwd)
  306.     export PATH=${JAVA_HOME}/bin:$PATH
  307.  
  308.     if [[ ${silent} == false ]]; then java -Xmx100m -version; fi
  309.     if [[ ${emit_java_home} == true ]]; then echo "${JAVA_HOME}"; fi
  310. }
  311.  
  312. main "$@"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement