Skip to content

Instantly share code, notes, and snippets.

@maroph
Last active March 19, 2024 16:12
Show Gist options
  • Save maroph/7c30211e6e9c30c9a3d1e5d3da6fc62b to your computer and use it in GitHub Desktop.
Save maroph/7c30211e6e9c30c9a3d1e5d3da6fc62b to your computer and use it in GitHub Desktop.
Extract major/minor version number from a given Java class file
#!/usr/bin/env python3
#
##############################################
# Copyright (c) 2024 by Manfred Rosenboom #
# https://maroph.github.io/ (maroph@pm.me) #
# #
# This work is licensed under a MIT License. #
# https://choosealicense.com/licenses/mit/ #
##############################################
#
# 19-MAR-2024
# Print major/minor class file version number from a given
# Java class file and the related Java version.
#
# You can find the given support info on the following pages:
# Adoptium : https://adoptium.net/support - from July 2021 on
# AdoptOpenJDK : https://adoptopenjdk.net/support.html - before July 2021
#
import os
import sys
if len(sys.argv) < 2:
print("class file name missing")
sys.exit(1)
classfile = sys.argv[1]
if not os.path.isfile(classfile):
print("class file " + classfile + " does not exist")
sys.exit(1)
with open(classfile,"rb") as f:
ba = f.read(8)
if len(ba) < 8:
print("given file is not a Java class file")
sys.exit(1)
# each class file starts with the 4 bytes 0xcafebabe
if ba[0] != 0xca or ba[1] != 0xfe or ba[2] != 0xba or ba[3] != 0xbe:
print("given file is not a Java class file")
sys.exit(1)
# next 4 bytes: 2 bytes minor version and 2 bytes major version
# both numbers are unsigned integers in big endian format
minor = int(ba[4]) << 8 | int(ba[5])
major = int(ba[6]) << 8 | int(ba[7])
# dictionary: (Java class file major version, Java version)
# OpenJDK distributions:
# AdoptOpenJDK : https://adoptopenjdk.net/ (before July 2021)
# Adoptium : https://adoptium.net/ (from July 2021 on)
javaDict = {
66: "Java 22 (Adoptium Support: SEP-2024)",
65: "Java 21 (LTS: Adoptium Support: >= DEC-2029)",
64: "Java 20 (Adoptium Support: SEP-2023)",
63: "Java 19 (Adoptium Support: MAR-2023)",
62: "Java 18 (Adoptium Support: SEP-2022)",
61: "Java 17 (LTS: Adoptium Support: >= OCT-2027)",
60: "Java 16 (Adoptium Support: SEP-2021)",
59: "Java 15 (AdoptOpenJDK Support: MAR-2021)",
58: "Java 14 (AdoptOpenJDK Support: SEP-2020)",
57: "Java 13 (AdoptOpenJDK Support: MAR-2020)",
56: "Java 12 (AdoptOpenJDK Support: SEP-2019)",
55: "Java 11 (LTS: Adoptium Support: >= OCT-2024)",
54: "Java 10 (AdoptOpenJDK Support: SEP-2018)",
53: "Java 9 (AdoptOpenJDK Support: MAR-2018)",
52: "Java 8 (1.8 - LTS: Adoptium Support: >= NOV-2026)",
51: "Java 7 (1.7)",
50: "Java 6 (1.6)",
49: "Java 5 (1.5)",
48: "Java 1.4",
47: "Java 1.3",
46: "Java 1.2",
45: "Java 1.0/1.1"
}
if major in javaDict:
java = javaDict[major]
else:
java = "unknown"
print("major: 0x%04x (%d) , minor: 0x%04x (%d) , version: %s" % (major, major, minor, minor, java))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment