如何通过Bash脚本判断含类文件与子JAR的JAR所需最低Java版本?
可以用Bash脚本实现,以下是具体方案
当然可以!核心思路是递归遍历目标JAR里的所有.class文件(包括嵌套子JAR里的),提取每个类的编译版本号,最终取所有版本里最低的那个,再映射到对应的Java版本。
实现步骤与脚本
下面是一个可直接运行的Bash脚本,它会自动处理嵌套JAR,收集所有类文件的版本信息并输出最低要求的Java版本:
#!/bin/bash # 定义Java版本与major version的映射表 declare -A java_versions=( [45]="Java 1.1" [46]="Java 1.2" [47]="Java 1.3" [48]="Java 1.4" [49]="Java 5" [50]="Java 6" [51]="Java 7" [52]="Java 8" [53]="Java 9" [54]="Java 10" [55]="Java 11" [56]="Java 12" [57]="Java 13" [58]="Java 14" [59]="Java 15" [60]="Java 16" [61]="Java 17" [62]="Java 18" [63]="Java 19" [64]="Java 20" [65]="Java 21" ) # 递归处理JAR文件或目录中的类文件 process_jar_or_dir() { local target="$1" local temp_dir=$(mktemp -d) # 如果是JAR文件,先解压到临时目录 if [[ "$target" == *.jar ]]; then unzip -q "$target" -d "$temp_dir" target="$temp_dir" fi # 遍历目标路径下的所有文件 find "$target" -type f | while read -r file; do case "$file" in *.class) # 提取major version major_version=$(javap -verbose "$file" 2>/dev/null | grep -E 'major version' | awk '{print $NF}') if [[ -n "$major_version" ]]; then echo "$major_version" fi ;; *.jar) # 递归处理嵌套JAR process_jar_or_dir "$file" ;; esac done # 清理临时目录 rm -rf "$temp_dir" } # 主逻辑:检查输入参数 if [[ $# -ne 1 ]]; then echo "用法: $0 <目标JAR文件路径>" exit 1 fi target_jar="$1" if [[ ! -f "$target_jar" ]]; then echo "错误: 文件 $target_jar 不存在" exit 1 fi # 收集所有major version,找到最小值 min_major=$(process_jar_or_dir "$target_jar" | sort -n | head -n 1) if [[ -n "$min_major" ]]; then echo "该JAR文件所需的最低Java版本为: ${java_versions[$min_major]}" else echo "错误: 未找到任何.class文件或无法读取版本信息" exit 1 fi
脚本说明
- 版本映射表:
java_versions数组存储了JVM规范中major version与Java版本的对应关系,覆盖到Java 21,后续版本可以自行补充。 - 递归处理:
process_jar_or_dir函数会自动识别JAR文件并解压,同时递归处理嵌套的子JAR,不放过任何一个类文件。 - 版本提取:用
javap -verbose读取类文件的版本信息,通过grep和awk提取major version数值。 - 取最小值:收集所有版本号后,排序取最小的那个,再映射为可读的Java版本。
注意事项
- 确保系统已安装
javap(随JDK自带)和unzip工具。 - 部分混淆过的类文件可能导致
javap无法读取版本信息,这种情况脚本会跳过该类,但如果大部分类都能正常读取,结果依然可靠。 - 脚本会创建临时目录存储解压内容,执行完毕后自动清理,不会留下垃圾文件。
内容的提问来源于stack exchange,提问作者hawkeye
相关产品推荐
相关产品推荐

