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:
- Get the main class name from the
META-INF/MANIFEST.MF
file. - Get the absolute path to the main class file.
- Extract the main class filename from the path.
- Determine the major version.
- 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
Experienced Unix/Linux System Administrator with 20-year background in Systems Analysis, Problem Resolution and Engineering Application Support in a large distributed Unix and Windows server environment. Strong problem determination skills. Good knowledge of networking, remote diagnostic techniques, firewalls and network security. Extensive experience with engineering application and database servers, high-availability systems, high-performance computing clusters, and process automation.