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