Correct way to check Java version from BASH script
How can I check whether Java is available (in the PATH or via JAVA_HOME) from a bash script and make sure the version is at least 1.5?
Java 5 has been end-of-life for quite a long time. Java 6 will be end-of-life very soon. You should be moving to Java 6 as a priority, and to 7 as soon as you can.
@kittylyst: This is a minimal requirement. My software doesn’t need Java 6 features, so there is no point forcing users for something better. But thanks for pointing it out anyway.
17 Answers 17
if type -p java; then echo found java executable in PATH _java=java elif [[ -n "$JAVA_HOME" ]] && [[ -x "$JAVA_HOME/bin/java" ]]; then echo found java executable in JAVA_HOME _java="$JAVA_HOME/bin/java" else echo "no java" fi if [[ "$_java" ]]; then version=$("$_java" -version 2>&1 | awk -F '"' '/version/ ') echo version "$version" if [[ "$version" > "1.5" ]]; then echo version is more than 1.5 else echo version is less than 1.5 fi fi
Ug sorry cant get comments to format. This fails when Java version is 1.10. This is because string comapre is not a number compare. Also the answer is wrong when version is «1.5» Though I guess that would be «1.5.0» so I guess its okay.
good point. you could do something like: IFS=. read major minor extra 5 )); . — would have to check for invalid octal numbers like «08».
the » type -p java » won’t work in «sh»; so, for portability, use #!/bin/bash in the script, rather than #!/bin/sh (though, it’s possible that /bin/sh isn’t actually bourne shell, but rather a backward compatible variant)
For comparing versions, I suggest : version1=$(echo «$version» | awk -F. ») which will get you major and minor aligned with 3 digit for each, and then compare with if [ $version1 -ge 001008 ] ; then
You can obtain java version via:
JAVA_VER=$(java -version 2>&1 | sed -n ';s/.* version "\(.*\)\.\(.*\)\..*".*/\1\2/p;')
it will give you 16 for java like 1.6.0_13 , 15 for version like 1.5.0_17 and 110 for openjdk 11.0.6 2020-01-14 LTS .
So you can easily compare it in shell:
[ "$JAVA_VER" -ge 15 ] && echo "ok, java is 1.5 or newer" || echo "it's too old. "
UPDATE: This code should work fine with openjdk and JAVA_TOOL_OPTIONS as mentioned in comments.
The result of ‘java -version’ with OpenJDK 8 is slightly different, «java» is replaced by «openjdk» in the output. This expression works with both cases: sed ‘s/.*version «\(.*\)\.\(.*\)\..*»/\1\2/; 1q’
If JAVA_TOOL_OPTIONS is set the output is again slightly different, the java version is not on the first line. eg: Picked up JAVA_TOOL_OPTIONS: -agentlib:hprof java version «1.7.0_60» Java(TM) SE Runtime Environment (build 1.7.0_60-b19) Java HotSpot(TM) 64-Bit Server VM (build 24.60-b09, mixed mode) Dumping Java heap . allocation sites . done
Some tweak to this as below should work after Java 9 as well. JAVA_VER=$(java -version 2>&1 | sed -n ‘;s/.* version «(.*)\.(.*)\..*»/\1\2/p;’)
The answers above work correctly only for specific Java versions (usually for the ones before Java 9 or for the ones after Java 8.
I wrote a simple one liner that will return an integer for Java versions 6 through 11 (and possibly all future versions, until they change it again!).
It basically drops the «1.» at the beginning of the version number, if it exists, and then considers only the first number before the next «.».
java -version 2>&1 | head -1 | cut -d'»‘ -f2 | sed ‘/^1\./s///’ | cut -d’.’ -f1
You can issue java -version and read & parse the output
java -version 2>&1 >/dev/null | grep 'java version' | awk ''
This is very close to what I want. Do you know of a version which also searches $PATH before it calls locate (which isn’t always available)?
@Ravi, right I will edit those links, you could use java -version 2>&1 >/dev/null | grep ‘java version’ | awk ‘
If interested in the numerical part only and for further usage in path variables, you may use something like java -version 2>&1 | head -1 | cut -d ‘»‘ -f 2
You could also compare the jdk class version number with javap :
javap -verbose java.lang.String | grep "major version" | cut -d " " -f5
If its java 8, this will print 52, and 55 for java 11. With this you can make a simple comparison and you don’t have to deal with the version string parsing.
This is a nice hack if you just want to know the major version. Sometimes, you’d like to check that a certain patchlevel is installed.
I wrote a bash function that should work for JDK 9 and JDK 10.
#!/bin/bash # returns the JDK version. # 8 for 1.8.0_nn, 9 for 9-ea etc, and "no_java" for undetected jdk_version() < local result local java_cmd if [[ -n $(type -p java) ]] then java_cmd=java elif [[ (-n "$JAVA_HOME") && (-x "$JAVA_HOME/bin/java") ]] then java_cmd="$JAVA_HOME/bin/java" fi local IFS=$'\n' # remove \r for Cygwin local lines=$("$java_cmd" -Xms32M -Xmx32M -version 2>&1 | tr '\r' '\n') if [[ -z $java_cmd ]] then result=no_java else for line in $lines; do if [[ (-z $result) && ($line = *"version \""*) ]] then local ver=$(echo $line | sed -e 's/.*version "\(.*\)"\(.*\)/\1/; 1q') # on macOS, sed doesn't support '?' if [[ $ver = "1."* ]] then result=$(echo $ver | sed -e 's/1\.\(7*\)\(.*\)/\1/; 1q') else result=$(echo $ver | sed -e 's/\(2*\)\(.*\)/\1/; 1q') fi fi done fi echo "$result" > v="$(jdk_version)" echo $v
This returns 8 for Java 8 ( «1.8.0_151» etc), and 9 for Java 9 ( «9-Debian» etc), which should make it easier to do the further comparison.
Determining the Java version only using grep with Perl-style regex can be done like this:
java -version 2>&1 | grep -oP 'version "?(1\.)?\K\d+'
This will print the major version for Java 9 or higher and the minor version for versions lower than 9, for example 8 for Java 1.8 and 11 for Java 11.0.4 .
JAVA_MAJOR_VERSION=$(java -version 2>&1 | grep -oP 'version "?(1\.)?\K\d+' || true) if [[ $JAVA_MAJOR_VERSION -lt 8 ]]; then echo "Java 8 or higher is required!" exit 1 fi
The || true was added to prevent the script from aborting in case Java is not installed and the Shell option set -e was enabled.
A combination of different answers:
JAVA_VER=$(java -version 2>&1 | grep -i version | sed 's/.*version ".*\.\(.*\)\..*"/\1/; 1q')
- Returns 7 for Java 7 and 8 for Java 8
- Works with OpenJDK and with Oracle JDK
- Works even if the JAVA_TOOL_OPTIONS is set
java -version |& grep 'version' |& awk -F\" '< split($2,a,"."); print a[1]"."a[2]>'
#!/bin/bash echo `java -version 2>&1 | grep 'version' 2>&1 | awk -F\" '< split($2,a,"."); print a[1]"."a[2]>'` jver=`java -version 2>&1 | grep 'version' 2>&1 | awk -F\" '< split($2,a,"."); print a[1]"."a[2]>'` if [[ $jver == "1.8" ]]; then echo $jver is java 8 else echo $jver is java 11 fi
Small improvements: Use $(. ) instead of backticks. They are safer, support nesting, and easier to type on most keyboards/OSs.
The method I ended up using is:
# Work out the JAVA version we are working with: JAVA_VER_MAJOR="" JAVA_VER_MINOR="" JAVA_VER_BUILD="" # Based on: http://stackoverflow.com/a/32026447 for token in $(java -version 2>&1 | grep -i version) do if [[ $token =~ \"([[:digit:]])\.([[:digit:]])\.(.*)\" ]] then JAVA_VER_MAJOR=$ JAVA_VER_MINOR=$ JAVA_VER_BUILD=$ break fi done
It will work correctly even if JAVA_TOOL_OPTIONS is set to something due to filtering done by grep.
Another way is: A file called release is located in $JAVA_HOME . On Java 15 (Debian) it has as content:
IMPLEMENTOR="Debian" JAVA_VERSION="15.0.1" JAVA_VERSION_DATE="2020-10-20" MODULES="java.base java.compiler java.datatransfer java.xml java.prefs java.desktop java.instrument java.logging java.management java.security.sasl java.naming java.rmi java.management.rmi java.net.http java.scripting java.security.jgss java.transaction.xa java.sql java.sql.rowset java.xml.crypto java.se java.smartcardio jdk.accessibility jdk.internal.vm.ci jdk.management jdk.unsupported jdk.internal.vm.compiler jdk.aot jdk.internal.jvmstat jdk.attach jdk.charsets jdk.compiler jdk.crypto.ec jdk.crypto.cryptoki jdk.dynalink jdk.internal.ed jdk.editpad jdk.hotspot.agent jdk.httpserver jdk.incubator.foreign jdk.internal.opt jdk.jdeps jdk.jlink jdk.incubator.jpackage jdk.internal.le jdk.internal.vm.compiler.management jdk.jartool jdk.javadoc jdk.jcmd jdk.management.agent jdk.jconsole jdk.jdwp.agent jdk.jdi jdk.jfr jdk.jshell jdk.jsobject jdk.jstatd jdk.localedata jdk.management.jfr jdk.naming.dns jdk.naming.rmi jdk.net jdk.nio.mapmode jdk.sctp jdk.security.auth jdk.security.jgss jdk.unsupported.desktop jdk.xml.dom jdk.zipfs" OS_ARCH="x86_64" OS_NAME="Linux" SOURCE=""
So you see JAVA_VERSION , which contains the version number.
major=$(echo $JAVA_VERSION | cut -d. -f1)
sets major to the value 15 (=Major version number), which you can use further.
It’s a really simple solution.
How can I tell what version of Java I have installed?
I want to start toying around with java (eventually getting to the point where I can write basic little programs for android or web), but I’ve managed to have java messed up on my computer (from past experiments). I’m not sure which version of java I have, and would like to know if there is a command to see the version of java that is installed and active. Also, which version works best? All this on 32bit Ubuntu 12.04 EDIT:
Ok, so it seems like I have both openjdk 6 and 7, with openjdk 7 in use. I want to use openjdk 7, so how do I uninstall openjdk 6? Is just via USC good enough or is there a command that should be run?
4 Answers 4
update-java-alternatives -l shows you all the Java versions you have installed.
java -version shows you the Java version you are using.
java -showversion shows you the Java version you are using and help.
Normally it would be OpenJDK.
This command should tell you what is currently providing the Java virtual machine ( java ) and the Java compiler ( javac ):
file /etc/alternatives/java /etc/alternatives/javac
This assumes the «alternatives» system is working properly, which might not be the case, depending on how Java has been «messed up» in the past. To check this, run:
If the alternatives system is working correctly and being used by Java, then you should see:
/usr/bin/java: symbolic link to `/etc/alternatives/java' /usr/bin/javac: symbolic link to `/etc/alternatives/javac'
Otherwise please edit your question to provide details. Then it should be possible to give a more specific answer.
You can remove openjdk-6 with the Software Center. There are multiple packages associated with it, so you may need to remove more than one packages. (All the `openjdk-6 packages are listed here.)
Or you can use the command-line:
sudo apt-get remove openjdk-6-\* icedtea-6-\*
However, whichever method you use, you may want to check first to see what depends on these packages—you might have software installed that specifically needs version 6. (Probably not, but possibly.)
You can check for this by simulating the removal operation on the command-line:
apt-get -s remove openjdk-6-\* icedtea-6-\*
This will show you the effects of removing those packages, including what other packages would be removed as well. (You’ll notice that since this is a simulation, you don’t need sudo .)
If you want to be able to continue using Java content online in your web browser (this is not the same thing as JavaScript), then before you remove any icedtea-6- or openjdk-6- packages (except perhaps openjdk-6-jdk ), you should make sure you have icedtea-7- packages installed corresponding to whatever icedtea-6- packages are installed.
How can I check which JRE version I have?
According to the program I am trying to start, it requires Oracle(R) Java(TM) Runtime Environment 7 or 8 .
The number after the 1. In this case, you’re on JRE 7. If it really needs the Oracle JRE, see askubuntu.com/q/56104/158442
1 Answer 1
You need Oracle Java which you can install like this
sudo add-apt-repository ppa:webupd8team/java sudo apt-get update sudo apt-get install oracle-java8-installer
sudo apt-get install oracle-java8-set-default
Right now you have OpenJDK and as per your question you need Oracle Java. In case the JAVA_HOME is not setup properly you can do:
sudo vi /etc/environment export JAVA_HOME=/path-to-java-before-bin-dir source /etc/environment
Should I remove the old java? I don’t want it to interfere with the new one, and the system is low on memory. Will it have any effect on the Ubuntu if I remove it?
@inf3rno. No you don’t have to. The steps that i have provided doesn’t purge openJDK. It’s just make sure that you get Oracle Java 8 from the right PPA(so that you get future updates and bug fixes) and then it will make sure that it’s Oracle Java 8 is invoked when you issue java(provided you setup path properly). If this solves your problem — mark this as answer(tick mark)
Thanks! I’ll purge it, I guess programs which used that version are compatible with the oracle version.