Determine Java version the easy way

Steve Boardwell
3 min readNov 20, 2020

--

Photo by Caspar Camille Rubin on Unsplash

This is just a short note. Will write more if I find the time.

Sometimes your script needs to know which version of java is currently running on your environment. And on those occasions, I always found myself looking for the all conquering “Eierlegenderwollmilichsau” of methods on the internet. It needed to be:

  • small (a couple of lines, no more)
  • non-intrusive (no added temp files, etc)
  • portable (-ish*)

* in an bash sense at least 😉, although I’m sure there’s a Windows equivalent

There are various ways to do so, such as parsing the version from the java -version command, creating a small Version.javato compile and run, etc.

Well, here’s another one! 😃

What the script should do is:

  • check for JAVA_HOME and, if found, add to the PATH
  • check for java as a command in general, failing if not found
  • check for version compatibility

For the compatibility test I’ve discovered the little known -XshowSettings:all flag. This little beauty contains tons of information but we are interested in the java version.

NOTE: The flag sends all its output STDERR so we need to redirect to STDOUT

So, anyway, let’s have a look:

❯ java -XshowSettings:all -version 2>&1 | grep "java.*version" 
java.class.version = 59.0
java.runtime.version = 15.0.1+9-18
java.specification.version = 15
java.version = 15.0.1
java.version.date = 2020-10-20
java.vm.specification.version = 15
java.vm.version = 15.0.1+9-18

And there you have it, java versions in all shapes and sizes. Nothing ground breaking, but it does the job and not a temp file in sight!

Here’s a 3-liner example using the java.specification.version property to look for versions 1.8, 11, or 15. Little gems to look out for in the script:

  • the awesome awk command with its built-in regular expression filter (so you don’t need to ...| grep... | awk... )
  • the equally useful curly braces grouping feature from bash for grouping multiple commands
#!/usr/bin/env bashset -euo pipefail# Check existence of JAVA_HOME
[ -n "${JAVA_HOME:-}" ] && { echo "JAVA_HOME check: ADDED"; export PATH="${JAVA_HOME}/bin:$PATH"; } || { echo "JAVA_HOME check: MISSING"; }
# Check 'java' as a command
command -v java &> /dev/null && { echo "Java command check PASSED"; } || { echo "java command not found. Exiting..."; exit 1; }
# Check version compatibility
[[ "$(java -XshowSettings:all -version 2>&1 | awk '/java\.specification\.version/ { print $3 }')" =~ (1.8|11|15) ]] && echo "Java version check PASSED" || { echo "Java version check FAILED"; exit 1; }

And here are some quick tests to illustrate:

❯ docker run --rm -it -v $(pwd):/app node:12 /app/java-check.sh; echo "Exit code $?"  
JAVA_HOME check: MISSING
java command not found. Exiting...
Exit code 1

❯ docker run --rm -it -v $(pwd):/app java:7 /app/java-check.sh; echo "Exit code $?"
JAVA_HOME check: ADDED
Java command check PASSED
Java version check FAILED
Exit code 1

❯ docker run --rm -it -v $(pwd):/app java:8 /app/java-check.sh; echo "Exit code $?"
JAVA_HOME check: ADDED
Java command check PASSED
Java version check PASSED
Exit code 0

❯ docker run --rm -it -v $(pwd):/app openjdk:11 /app/java-check.sh; echo "Exit code $?"
JAVA_HOME check: ADDED
Java command check PASSED
Java version check PASSED
Exit code 0

So, there you have it. Nothing huge, but important enough to want to share.

Until the next time.

--

--