当前位置:  开发笔记 > 编程语言 > 正文

什么版本的javac构建了我的jar?

如何解决《什么版本的javac构建了我的jar?》经验,为你挑选了7个好方法。

如何判断使用哪个版本的Java编译器构建jar?我有一个jar文件,它可以在三个JDK中的任何一个中构建.我们需要确切地知道哪一个,所以我们可以证明兼容性.编译器版本是嵌入在类文件或jar中的某个位置吗?



1> David J. Lis..:

A jar只是一个容器.它是一个文件存档āla tar.虽然jar可能在其META-INF层次结构中包含有趣的信息,但它没有义务在其内容中指定类的复古.为此,必须检查class其中的文件.

正如Peter Lawrey在对原始问题的评论中提到的那样,您不一定知道哪个JDK版本构建了给定class文件,但您可以找到class包含在其中的文件的字节码类版本jar.

是的,这有点糟糕,但第一步是从中提取一个或多个类jar.例如:

$ jar xf log4j-1.2.15.jar

在安装了Cygwin的 Linux,Mac OS X或Windows上,file(1)命令知道类版本.

$ file ./org/apache/log4j/Appender.class
./org/apache/log4j/Appender.class: compiled Java class data, version 45.3

或者,使用javapJDK作为@jikes.thunderbolt恰当地指出:

$ javap -v ./org/apache/log4j/Appender.class | grep major
 major version: 45

如果你被降级到Windows没有任何一个file或没有的环境grep

> javap -v ./org/apache/log4j/Appender.class | findstr major
 major version: 45

FWIW,我会同意,这将比原始问题javap更能说明给定class文件.

无论如何,一个不同的类版本,例如:

$ file ~/bin/classes/P.class
/home/dave/bin/classes/P.class: compiled Java class data, version 50.0

类版本主编号对应于以下Java JDK版本:

45.3 = 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


我的`file`版本没有显示,但我可以用这个命令手动检查类:`hexdump~/bin/classes/P.class | head`.只需查看第八个字节并转换为十进制.
@JarettMillard我的cygwin`文件file.class`(5.22-1)最初没有显示java类目标:"file.class:[architecture = 6909806] [architecture = 6845039]".但是`file -k file.class`做到了:"file.class:[architecture = 6909806] [architecture = 6845039]编译的Java类数据,版本50.0(Java 1.6)".看起来`file`在没有`-k`的魔法文件数据库中只获得了第一个匹配.
FYI'文件'似乎依赖于Java版本是否也将显示JDK版本.在CentOS/Oracle Linux和Java 6编译的类中,我获得了"编译的Java类数据,版本50.0(Java 1.6)"但是当我在使用Java 7编译的类上运行它时,我只获得通用版本"编译的Java类数据,版本51.0"

2> Jonathon Fau..:

你无法从JAR文件中分辨出来.

下载十六进制编辑器并打开JAR中的一个类文件,查看字节偏移4到7.版本信息是内置的.

http://en.wikipedia.org/wiki/Java_class_file

注意:如下面的评论所述,

这些字节告诉你该类编译的版本是什么,而不是编译它的版本.


为了迂腐,这些字节告诉你编译FOR的类的版本,而不是编译它的版本.Java允许您编译代码,以便它们与早期版本的Java兼容.但是,这仅适用于字节代码和格式.例如,它将很乐意编译将JDK 6库引用为JDK 5格式的代码.JDK 5将加载该类,但无法运行它,因为JDK 5库没有从JDK 6引用的代码.
**[其他答案](http://stackoverflow.com/a/3313839/641451)告诉如何通过命令行轻松检查**
我们可以在清单文件中找到它创建者:1.7.0_21-b11(Oracle Corporation)

3> 小智..:

以下是Java查找此信息的方法.

Windows:javap -v | findstr major
Unix:javap -v | grep major

例如:
> javap -v Application | findstr major   major version: 51


在给出的所有答案中,您的答案是最简洁的,并且不涉及编写10行代码来了解版本信息.为此+1

4> jackrabbit..:

Java compiler(javac)不构建jar,它将Java文件转换为类文件.Jar工具(jar)创建实际的jar.如果未指定自定义清单,则默认清单将指定用于创建jar的JDK版本.


虽然是真的,但这并没有提供问题的答案.
@ zb226 AFAIK用于编译类的编译器版本无法从类文件中获取,只有类编译的版本为_for_.我提供的信息提供了唯一的(标准)信息,可用于建立人工制品的版本.如果那不是被问到的问题,那么问题应该改写.

5> anre..:

没有必要解压缩JAR(如果其中一个类名已知或被查找,例如使用7zip),那么在Windows上就足够了:

javap -cp log4j-core-2.5.jar -verbose org.apache.logging.log4j.core.Logger | findstr major



6> Wolfgang Fah..:

由于我需要分析胖罐子,因此我对jar文件中每个类的版本感兴趣。因此,我采用了Joe Liversedge的方法 /sf/ask/17360801/并将其与David J. Liszewski的/sf/ask/17360801/类编号版本表结合起来以创建bash脚本jarv在jar文件中显示所有类文件的版本。

用法

usage: ./jarv jarfile
 -h|--help: show this usage

jarv $Home/.m2/repository/log4j/log4j/1.2.17/log4j-1.2.17.jar

java 1.4 org.apache.log4j.Appender
java 1.4 org.apache.log4j.AppenderSkeleton
java 1.4 org.apache.log4j.AsyncAppender$DiscardSummary
java 1.4 org.apache.log4j.AsyncAppender$Dispatcher
...

Bash脚本jarv

#!/bin/bash
# WF 2018-07-12
# find out the class versions with in jar file
# see /sf/ask/17360801/

# uncomment do debug
# set -x

#ansi colors
#http://www.csc.uvic.ca/~sae/seng265/fall04/tips/s265s047-tips/bash-using-colors.html
blue='\033[0;34m'  
red='\033[0;31m'  
green='\033[0;32m' # '\e[1;32m' is too bright for white bg.
endColor='\033[0m'

#
# a colored message 
#   params:
#     1: l_color - the color of the message
#     2: l_msg - the message to display
#
color_msg() {
  local l_color="$1"
  local l_msg="$2"
  echo -e "${l_color}$l_msg${endColor}"
}

#
# error
#
#   show an error message and exit
#
#   params:
#     1: l_msg - the message to display
error() {
  local l_msg="$1"
  # use ansi red for error
  color_msg $red "Error: $l_msg" 1>&2
  exit 1
}

#
# show the usage
#
usage() {
  echo "usage: $0 jarfile"
  # -h|--help|usage|show this usage
  echo " -h|--help: show this usage"
  exit 1 
}

#
# showclassversions
#
showclassversions() {
  local l_jar="$1"
  jar -tf "$l_jar" | grep '.class' | while read classname
  do
    class=$(echo $classname | sed -e 's/\.class$//')
    class_version=$(javap -classpath "$l_jar" -verbose $class | grep 'major version' | cut -f2 -d ":" | cut -c2-)
    class_pretty=$(echo $class | sed -e 's#/#.#g')
    case $class_version in
      45.3) java_version="java 1.1";;
      46) java_version="java 1.2";;
      47) java_version="java 1.3";;
      48) java_version="java 1.4";;
      49) java_version="java5";;
      50) java_version="java6";;
      51) java_version="java7";;
      52) java_version="java8";;
      53) java_version="java9";;
      54) java_version="java10";;
      *) java_version="x${class_version}x";;
    esac
    echo $java_version $class_pretty
  done
}

# check the number of parameters
if [ $# -lt 1 ]
then
  usage
fi

# start of script
# check arguments
while test $# -gt 0
do
  case $1 in
    # -h|--help|usage|show this usage
    -h|--help) 
      usage
      exit 1
      ;;
    *)
     showclassversions "$1"
  esac
  shift
done 



7> cahit beyaz..:

您可以使用十六进制编辑器从.class文件中找到Java编译器版本。

步骤1:使用zip提取程序从jar文件中提取.class文件

步骤2:使用十六进制编辑器打开.class文件。(我使用过notepad ++十六进制编辑器插件。此插件将文件读取为二进制文件,并以十六进制显示)。

索引6和7给出了所使用的类文件格式的主要版本号。 https://zh.wikipedia.org/wiki/Java_class_file

Java SE 11 = 55(十六进制0x37)

Java SE 10 = 54(十六进制0x36)

Java SE 9 = 53(十六进制0x35)

Java SE 8 = 52(十六进制0x34),

Java SE 7 = 51(16x 0x33),

Java SE 6.0 = 50(16x 0x32),

Java SE 5.0 = 49(十六进制0x31),

JDK 1.4 = 48(十六进制0x30),

JDK 1.3 = 47(十六进制0x2F),

JDK 1.2 = 46(十六进制0x2E),

JDK 1.1 = 45(十六进制0x2D)。

推荐阅读
小白也坚强_177
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有