Recently, I had to upgrade an old Java application running on an equally old Sun Solaris 11 server. Several upgrade candidates arrived as JAR files without much detail about the system requirements.

For reasons outside this discussion, upgrading the Java version on the server was out of the question. I needed to find out whether any of the application upgrade options were compatible with the versions of Java already installed on the system.

The basic process for extracting this info from an executable JAR file is as follows:

  1. Get the main class name from the META-INF/MANIFEST.MF file.
  2. Get the absolute path to the main class file.
  3. Extract the main class filename from the path.
  4. Determine the major version.
  5. Determine the Java version.

The process is a bit tedious, but below is the script that gets the job done. You can also download it from my GitHub repo. The script will search for *.jar file in your current directory and check all of them. You can modify the maxdepth parameter of the find command if you want the script to search recursively.

#!/bin/bash
#V 46:Java 1.2
#V 47:Java 1.3
#V 48:Java 1.4
#V 49:Java 5
#V 50:Java 6
#V 51:Java 7
#V 52:Java 8
#V 53:Java 9
#V 54:Java 10
#V 55:Java 11
#V 56:Java 12
#V 57:Java 13
#V 58:Java 14
#V 59:Java 15
#V 60:Java 16
#V 61:Java 17
this_script_full="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/$(basename "${BASH_SOURCE[0]}")"
for f in $(find . -maxdepth 1 -type f -name "*\.jar")
do
  main_class_name="$(unzip -p "${f}" META-INF/MANIFEST.MF | grep "^Main-Class:" | awk '{print $2}' | dos2unix)"
  main_class_path="$(jar -tf "${f}" | grep "${main_class_name}" | awk '(NR==1||length<$1){min=length; shortest=$0} END{print shortest}' | dos2unix)"
  main_class_filename="$(echo "${main_class_path}" | awk -F'/' '{print $NF}')"
  unzip -p "${f}" "${main_class_path}" > "${main_class_filename}"
  major_version="$(javap -verbose -classpath . "${main_class_filename}" | grep 'major version:' | awk '{print $NF}')"
  java_version="$(grep "^#V ${major_version}:" "${this_script_full}" | awk -F':' '{print $NF}')"
  echo -e "${f},\u2192,major version:,${major_version},Java version:,${java_version}"
  /bin/rm "${main_class_filename}"
done | column -s, -t

And here’s a sample output:

# /var/adm/bin/jar_version.sh
./TEST21_06-15-2022_0933.jar  →  major version:  50  Java version:  Java 6
./TEST23_05-24-2023_1234.jar  →  major version:  61  Java version:  Java 17