Sunday, October 25, 2026

updatejdk 2.0.0: Keep Your JDKs Up to Date – Without a Package Manager

I have just released updatejdk.sh 2.0.0, a single Bash script that lists, installs, updates and downloads JDKs and JREs on macOS and Linux. It installs Eclipse Temurin by default, and other distributions like Zulu, Corretto or Liberica if you ask for them. It verifies every download by its checksum, and one command brings everything you have installed up to date.

Why another JDK tool?

I like to keep several feature versions side by side, sometimes from different vendors, and I don't want a package manager or a runtime of its own just for that. The vendors publish plain tarballs, and their APIs say which release is the latest. A small script is enough to put the two together.

updatejdk.sh is a new development based on the ideas of update_jdk from my bashberries project. The last version of update_jdk was 1.20.0, so the version numbers continue at 2.0.0. Unlike its predecessor, it looks up the releases by the Adoptium API and the foojay Disco API rather than taking a URL. It also knows which version is installed, and it handles several distributions, architectures and operating systems.

Getting started

It is one file:

curl -fsSL -o updatejdk.sh https://bit.ly/updatejdk

chmod +x updatejdk.sh


You need bash, curl and tar. You also need jq, but if it is missing, as on macOS before Sequoia, the script downloads a verified copy for the run.

A quick tour

What is available, and what is installed?

$ ./updatejdk.sh -l 21

Asking https://api.adoptium.net/v3 for Temurin 21 releases for macOS aarch64 ...


  VERSION   TYPE  LATEST               FORMATS          INSTALLED

  --------- ----- -------------------- ---------------- ---------

* 21 LTS    jdk   jdk-21.0.13+9        tar.gz pkg       21.0.13+9-LTS (up to date) /Library/Java/JavaVirtualMachines/temurin-21.jdk

  21 LTS    jre   jdk-21.0.13+9        tar.gz pkg


Installed variants are marked with *. If you also have Zulu or Corretto installed, -l lists them as well, each in a table of its own.

Installing and updating:

updatejdk.sh -i lts           # the JDK of the most recent LTS release

updatejdk.sh -i 21:jre        # the JRE of Java 21

updatejdk.sh -i 21 -a zulu    # Azul Zulu 21 from the foojay Disco API

updatejdk.sh -u               # update everything, each from its own source

updatejdk.sh -u -n            # dry run: which updates are there?


A variant is <feature-version>[:jdk|:jre][:<architecture>], and lts and latest work as feature versions too. -l -a lists all distributions you can choose from.

Your own directory with -d/--dir

By default, installations go to /Library/Java/JavaVirtualMachines on macOS and /usr/lib/jvm on Linux. With -d, they go to a directory of your own, and no root privileges are needed. You can use it for a sandbox or a CI cache, but the use case I care most about is bundling runtimes with an application.

Say you build a macOS app on an Intel Mac and want to ship a universal DMG that runs on both Intel and Apple Silicon. You need a JRE for each architecture, and -d gets you both:

updatejdk.sh -d build/jre -i 21:jre:x64       # -> build/jre/temurin-21.jre

updatejdk.sh -d build/jre -i 21:jre:aarch64   # -> build/jre/temurin-21-aarch64.jre

updatejdk.sh -d build/jre -u                  # updates both later


A few details make this practical:

  • Only an installation for another architecture than the machine's has the architecture in its name, so the two don't collide.

  • After unpacking, the script checks that the archive really is for the requested architecture, according to the OS_ARCH of its release file.

  • Another architecture can only be installed with -d, so it never gets in the way of java_home or update-alternatives.

  • -l aarch64 shows what is available for Apple Silicon and marks what you have.

  • -t and -z need to run that java. On an Intel Mac, an aarch64 Java can't run, so the script skips both for it with a warning.

And if your build needs a stable path, -L maintains a relative symbolic link to the installed variant, e.g. build/jre/latest -> temurin-21.jre/Contents/Home.

Just the packages with -g/--get

Sometimes you don't want to install anything, just get the package, e.g. for a Windows installer:

updatejdk.sh -g 21:jre:x64 --os windows                # the zip

updatejdk.sh -g 21:jre:x64 --os windows --package msi  # the installer

updatejdk.sh -g 21:jre --package pkg                   # the macOS installer


The package is verified like an installation and saved together with a .sha256 file, so you can check it later by shasum -a 256 -c.

Trust, but verify

Nothing is installed without a checksum. The script takes the SHA-256 from the Adoptium API, from foojay, or from the checksum file next to the package. For Corretto, it uses Corretto's own latest_sha256 endpoint. Liberica only publishes a SHA-1, which is accepted with a note. The script also checks the size, and it refuses archives with absolute paths or `..`. A network error stops the script with its cause, rather than being taken for a missing release.

Linux notes

On Linux, the script supports glibc and musl (Alpine). Installations in /usr/lib/jvm are registered with update-alternatives, with the feature version as the priority, so your distribution's default stays selected. Directories that belong to a system package, like the Temurin RPM, are left to apt or dnf. The script uses sudo, or doas on systems that only have that. If a command like curl is missing, as on a fresh Ubuntu desktop, it tells you the command that installs it.

On both macOS and Linux, -z also updates the time zone data of your installations by Oracle's tzupdater.

Tested on

  • macOS on Apple Silicon, macOS 15 Sequoia (x64) and macOS 14 Sonoma (x64)

  • Ubuntu 26.04 LTS (x64) and Ubuntu 26.04.1 LTS (aarch64)

  • Rocky Linux and Alpine Linux (x64) with Temurin, during development

Get it

The source, the README with all the details, and the release notes are on GitHub: https://github.com/jonelo/updatejdk. Bug reports and wishes are welcome as issues there. updatejdk.sh is licensed under the Apache License 2.0.

updatejdk is an independent project. It is not affiliated with, endorsed or sponsored by Oracle, the Eclipse Foundation or any vendor of the distributions it installs. Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates; Eclipse Temurin is a trademark of the Eclipse Foundation.


No comments:

Post a Comment