Как я могу сказать, какая версия компилятора Java использовалась для создания jar? У меня есть файл JAR, и он может быть встроен в любой из трех JDK. Нам нужно точно знать, какой именно, чтобы мы могли сертифицировать совместимость. Версия компилятора встроена где-то в файлы классов или jar?
212
Created-By: 1.7.0_13 (Oracle Corporation)
Created-By: Apache Maven
иBuild-Jdk: 1.8.0_25
Ответы:
Вы не можете сказать из самого файла JAR, обязательно.
Загрузите шестнадцатеричный редактор и откройте один из файлов классов внутри JAR и посмотрите на смещения байтов с 4 по 7. Информация о версии встроена.
http://en.wikipedia.org/wiki/Java_class_file
Примечание: как указано в комментарии ниже,
источник
А
jar
это просто контейнер. Это файловый архив а-ляtar
. Хотя ajar
может содержать интересную информацию, содержащуюся в его иерархии META-INF , он не обязан указывать марку классов внутри своего содержимого. Для этого нужно изучитьclass
файлы в нем.Как упоминал Питер Лоури в комментарии к исходному вопросу, вы не можете точно знать, какая версия JDK создала данный
class
файл, но вы можете узнать версиюclass
файла класса байт-кода, содержащуюся вjar
.Да, это отстой, но первым шагом является извлечение одного или нескольких классов из
jar
. Например:В Linux, Mac OS X или Windows с установленным Cygwin команда file (1) знает версию класса.
Или, альтернативно, использование
javap
из JDK как @ jikes.thunderbolt удачно указывает:И если вы переведены в
Windows
среду безfile
илиgrep
FWIW, я согласен, что
javap
расскажет намного больше о данномclass
файле, чем первоначальный вопрос.В любом случае, версия другого класса, например:
Основной номер версии класса соответствует следующим версиям Java JDK:
источник
file
не показали, но я был в состоянии проверить класс вручную с помощью этой команды:hexdump ~/bin/classes/P.class | head
. Просто посмотрите на восьмой байт и преобразуйте в десятичный.JAR=something.jar ; unzip -p $JAR `unzip -l $JAR | grep '\.class$' | head -1` | file -
file file.class
(5.22-1) изначально не показывал цель класса java: "file.class: [зодчество = 6909806] [зодчество = 6845039]". Однакоfile -k file.class
сделал это: «file.class: [Architecture = 6909806] [Architecture = 6845039] скомпилированные данные класса Java, версия 50.0 (Java 1.6)». Похоже,file
получил только первый матч в его дабах magicfiles без-k
.Вот способ Java найти эту информацию.
Windows:
javap -v <class> | findstr major
Unix:
javap -v <class> | grep major
Например:
> javap -v Application | findstr major major version: 51
источник
<class>
параметр?Application.class
файл, и он скомпилирован для Java 7 (major version: 51
).javac
версию, скомпилировавшую файлы .class, о чем и просили.Нет необходимости распаковывать JAR (если одно из имен классов известно или ищется, например, с помощью 7zip), поэтому в Windows будет достаточно следующего:
источник
javac
версия , которая составлена .class - файлы, что и было запрошено.Компилятор Java (
javac
) не создает jar-файлы, он переводит файлы Java в файлы классов. Инструмент Jar (jar
) создает настоящие банки. Если пользовательский манифест не указан, по умолчанию будет указано, какая версия JDK использовалась для создания jar-файла.источник
Поскольку мне нужно было анализировать толстые банки, меня интересовала версия каждого отдельного класса в файле jar. Поэтому я выбрал подход Джо Ливерседжа https://stackoverflow.com/a/27877215/1497139 и соединил его с таблицей версий номера класса Дэвида Дж. Лизевского ( https://stackoverflow.com/a/3313839/1497139) для создания сценария bash jarv, чтобы показать версии всех файлов классов в файле jar.
использование
пример
Баш сценарий ярв
источник
head -1
может использоваться вместе со сценарием: обычно достаточно увидеть версию первого класса в файле jar.Вы можете найти версию компилятора Java из файлов .class, используя Hex Editor.
Шаг 1: Извлеките файлы .class из jar-файла, используя zip-экстрактор
Шаг 2: откройте файл .class с помощью шестнадцатеричного редактора. (Я использовал плагин hexpad редактора notepad ++. Этот плагин читает файл как двоичный файл и показывает его в шестнадцатеричном формате).
Индексы 6 и 7 дают основной номер версии используемого файла класса. https://en.wikipedia.org/wiki/Java_class_file
Java SE 11 = 55 (0x37 hex)
Java SE 10 = 54 (0x36 hex)
Java SE 9 = 53 (0x35 hex)
Java SE 8 = 52 (0x34 hex),
Java SE 7 = 51 (0x33 hex),
Java SE 6.0 = 50 (0x32 hex),
Java SE 5.0 = 49 (0x31 hex),
JDK 1,4 = 48 (гекс 0x30),
JDK 1,3 = 47 (гекс 0x2F),
JDK 1,2 = 46 (гекс 0x2E),
JDK 1.1 = 45 (0x2D hex).
источник
Вы можете узнать двоичную версию Java, проверив первые 8 байтов (или используя приложение, которое может).
Насколько мне известно, сам компилятор не вставляет никакой идентификационной подписи. Так или иначе, я не могу обнаружить такую вещь в формате класса спецификации файловой VM .
источник
javac
версия , которая составлена .class - файлы, что и было запрошено.Код отправленный Оуэн может сказать вам информацию , указанную в ряде других ответов здесь:
Смотрите также этот и этот сайт. В итоге я быстро изменил код Mind Products, чтобы проверить, для чего была скомпилирована каждая из моих зависимостей.
источник
javac
версия , которая составлена .class - файлы, что и было запрошено.Разработчики и администраторы, использующие Bash, могут найти полезными следующие удобные функции:
Вы можете вставить их для одноразового использования или добавить в
~/.bash_aliases
или~/.bashrc
. Результаты выглядят примерно так:и
РЕДАКТИРОВАТЬ Как указывает крольчатник , вы не можете на 100% полагаться на манифест, чтобы сказать вам что-нибудь полезное. Если это так, то вы можете извлечь его в вашей любимой оболочке UNIX с помощью
unzip
:Этот .jar не имеет ничего полезного в манифесте о содержащихся классах.
источник
javac
версия , которая составлена .class - файлы, что и было запрошено.Один лайнер (Linux)
unzip -p mylib.jar META-INF/MANIFEST.MF
Это печатает содержимое
MANIFEST.MF
файла на стандартный вывод (надеюсь, он есть в вашем jar-файле :)В зависимости от того, что собрало ваш пакет, вы найдете версию
Created-By
илиBuild-Jdk
ключ JDK .источник
MANIFEST.MF
, равно как и нет никаких обязательств, чтобы значения были правильными (Да, я однажды встречал,.jar
где значение было фиктивным).javac
версия , которая составлена .class - файлы, что и было запрошено.В каждом файле класса есть номер версии, встроенный для уровня байтового кода, который JVM использует, чтобы увидеть, нравится ли ему этот конкретный фрагмент байтового кода или нет. Это 48 для Java 1.4, 49 для Java 1.5 и 50 для Java 6.
Существует много компиляторов, которые могут генерировать байт-код на каждом уровне, javac использует опцию «-target», чтобы указать, какой уровень байт-кода генерировать, а Java 6 javac может генерировать байт-код как минимум для 1.4, 1.5 и 6. Я не Полагайте, что компилятор вставляет все, что может идентифицировать сам компилятор, что, как я думаю, вы просите. Кроме того, все чаще используется компилятор Eclipse, так как это единственный jar, который может работать только с JRE.
В файле jar обычно много классов, и каждый из них является независимым, поэтому вам нужно изучить все классы в jar, чтобы быть уверенным в характеристиках содержимого.
источник
В ответ на ответ @David J. Liszewski я выполнил следующие команды для извлечения манифеста jar-файла в Ubuntu:
источник
unzip -p LiceneSearch.jar META-INF/MANIFEST.MF
javac
версию, скомпилировавшую файлы .class, о чем и просили.В большинстве случаев вы можете просматривать целые jar-файлы или war-файлы, которые содержат много jar-файлов в дополнение к самим себе.
Поскольку я не хотел проверять каждый класс вручную, я написал Java-программу для этого:
https://github.com/Nthalk/WhatJDK
Хотя это не говорит о том, что класс был скомпилирован с, он определяет, какие JDK смогут ЗАГРУЗИТЬ классы, и это, вероятно, то, с чего вы хотели начать.
источник
Чтобы расширить ответы Джонатона Фауста и МакДауэлла : Если вы работаете в системе * nix, вы можете использовать
od
(одну из самых ранних программ Unix 1, которая должна быть доступна практически везде) для запроса.class
файла на двоичном уровне:Это выведет знакомые целочисленные значения, например,
50
дляJava 5
,51
дляJava 6
и так далее.1 Цитата из https://en.wikipedia.org/wiki/Od_(Unix)
источник
javac
версию, скомпилировавшую файлы .class, о чем и просили.Я также написал свой собственный скрипт bash для вывода версии Java, требуемой для всех jar-файлов, передаваемых в командной строке ... У меня немного грубовато, но у меня работает ;-)
пример использования
jar_dump_version_of_jvm_required.sh
источник
Вы можете легко сделать это в командной строке, используя следующий процесс:
Если вам известно имя класса в jar, вы можете использовать следующую команду:
пример :
Вывод :
Краткий справочник:
источник
Вы проверяете в файле манифеста примера jar:
Версия манифеста: 1.0 Создано: 1.6.0 (IBM Corporation)
источник
В Windows сделайте следующее:
Теперь Eclipse покажет точную мажорную и минорную версию.
источник
Я строю небольшой скрипт bash (на github), основанный на предложении Davids, используя
file
командуисточник