[java] javac의 어떤 버전이 내 항아리를 만들었습니까?

jar를 빌드하는 데 사용 된 Java 컴파일러 버전을 어떻게 알 수 있습니까? jar 파일이 있으며 세 개의 JDK 중 하나에서 빌드되었을 수 있습니다. 우리는 정확히 어느 것을 알아야하므로 호환성을 인증 할 수 있습니다. 컴파일러 버전이 클래스 파일이나 jar에 포함되어 있습니까?



답변

반드시 JAR 파일 자체에서 알 수는 없습니다.

16 진 편집기를 다운로드하고 JAR 내부의 클래스 파일 중 하나를 열고 바이트 오프셋 4-7을보십시오. 버전 정보가 내장되어 있습니다.

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

참고 : 아래 의견에서 언급했듯이

이 바이트는 클래스가 컴파일 된 버전이 아니라 클래스가 컴파일 된 버전을 알려줍니다.


답변

A jar는 단지 컨테이너입니다. 파일 아카이브 tar입니다. META-INF 계층 jar내에 흥미로운 정보가 포함되어있을 수 있지만, 컨텐츠 내에 클래스의 빈티지를 지정해야 할 의무는 없습니다. 이를 위해서는 파일을 검사해야합니다 .class

뿐만 피터 Lawrey이 원래의 질문에 코멘트에 언급, 당신은 반드시 주어진 내장 된 JDK 버전 알 수없는 class파일을,하지만 당신은의 바이트 코드 클래스 버전을 찾을 수 있습니다 classA의 포함 된 파일을 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중 하나없이 환경 으로 강등filegrep

> 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 = 자바 1.1
  • 46 = 자바 1.2
  • 47 = 자바 1.3
  • 48 = 자바 1.4
  • 49 = 자바 5
  • 50 = 자바 6
  • 51 = 자바 7
  • 52 = 자바 8
  • 53 = 자바 9

답변

이 정보를 찾는 Java의 방법은 다음과 같습니다.

Windows : javap -v <class> | findstr major
유닉스 :javap -v <class> | grep major

예를 들면 다음과 같습니다.
> javap -v Application | findstr major
  major version: 51


답변

JAR의 압축을 풀 필요가 없습니다 (클래스 이름 중 하나가 알려져 있거나 예를 들어 7zip을 사용하여 찾은 경우). Windows에서는 다음과 같이 충분합니다.

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


답변

Java 컴파일러 ( javac)는 jar를 빌드하지 않고 Java 파일을 클래스 파일로 변환합니다. 항아리 도구 ( jar)는 실제 항아리를 만듭니다. 사용자 정의 매니페스트가 지정되지 않은 경우 기본 매니페스트는 jar 작성에 사용 된 JDK 버전을 지정합니다.


답변

뚱뚱한 항아리를 분석해야했기 때문에 jar 파일의 각 개별 클래스 버전에 관심이있었습니다. 따라서 Joe Liversedge 접근 방식을 https://stackoverflow.com/a/27877215/1497139로 가져 와서
David J. Liszewski의 https://stackoverflow.com/a/3313839/1497139 클래스 번호 버전 테이블과 결합하여 bash 스크립트를 작성했습니다. jarv에 모든 클래스 파일의 버전을 표시하는 jarv

용법

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
...

배쉬 스크립트 jarv

#!/bin/bash
# WF 2018-07-12
# find out the class versions with in jar file
# see https://stackoverflow.com/questions/3313532/what-version-of-javac-built-my-jar

# 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 


답변

16 진 편집기를 사용하여 .class 파일에서 Java 컴파일러 버전을 찾을 수 있습니다.

1 단계 : Zip 추출기를 사용하여 jar 파일에서 .class 파일 추출

2 단계 : 16 진수 편집기로 .class 파일을 엽니 다.
여기에 이미지 설명을 입력하십시오

색인 6과 7은 사용중인 클래스 파일 형식의 주요 버전 번호를 제공합니다.
https://en.wikipedia.org/wiki/Java_class_file

Java SE 11 = 55 (0x37 16 진수)

Java SE 10 = 54 (0x36 16 진수)

자바 SE 9 = 53 (0x35 16 진수)

Java SE 8 = 52 (0x34 16 진수)

Java SE 7 = 51 (0x33 16 진수)

Java SE 6.0 = 50 (0x32 16 진수)

Java SE 5.0 = 49 (0x31 16 진수),

JDK 1.4 = 48 (0x30 16 진수)

JDK 1.3 = 47 (0x2F 16 진수)

JDK 1.2 = 46 (0x2E 16 진수)

JDK 1.1 = 45 (0x2D 16 진수).