Determine Java version the easy way
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.java
to compile and run, etc.
Well, here’s another one! 😃
What the script should do is:
- check for
JAVA_HOME
and, if found, add to thePATH
- 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 toSTDOUT
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.