Понимание байт-кода Java
Часто я застрял в файле класса java без источника, и я пытаюсь понять проблему, которую я имею под рукой.
Обратите внимание, что декомпилятор полезен, но не достаточен во всех ситуациях...
У меня есть два вопроса
- Какие инструменты доступны для просмотра java-байтового кода (желательно из командной строки linux).
- Каковы хорошие ссылки для знакомства с синтаксисом java-байтового кода.
Ответы
Ответ 1
Вместо того, чтобы смотреть прямо на байт-код Java, для чего потребуется знание виртуальной машины Java и ее операций, можно попытаться использовать утилиту для декомпиляции Java. Декомпилятор попытается создать исходный файл java
из указанного файла class
.
Как "декомпилировать" файлы классов Java? - это связанный с этим вопрос, который будет информативным для выяснения того, как декомпилировать файлы Java class
.
Тем не менее, можно использовать команду javap
, которая является частью JDK, чтобы разобрать файлы Java class
. Результатом javap
будет байт-код Java, содержащийся в файлах class
. Но следует предупредить, что байт-код не похож на исходный код Java.
Определенным источником для изучения байт-кода Java и самой виртуальной машины Java будет Спецификация виртуальной машины Java, второй выпуск. В частности, Глава 6: Набор инструкций виртуальной машины Java содержит индекс всех инструкций байткода.
Ответ 2
Чтобы просмотреть инструкцию байтов для файлов классов, используйте команду javap -v
так же, как если бы вы запускали java-программу, указав путь к классам (если необходимо) и имя класса.
Пример:
javap -v com.company.package.MainClass
О наборе команд байткода,
Краткое описание инструкций
Ответ 3
Fernflower - аналитический декомпилятор, поэтому он декомпилирует классы в читаемый код Java вместо байт-кодов. Это гораздо полезнее, когда вы хотите понять, как работает код.
Ответ 4
Если у вас есть класс и нет исходного кода, но у вас есть ошибка, вы можете сделать одну из двух основных вещей:
- Декомпилируйте, исправьте ошибку и заново создайте файл jar. Я делал это раньше, но системные администраторы склонны к тому, чтобы внедрить это в производство.
-
Напишите модульные тесты для класса, определите причину ошибки, сообщите об ошибке с модульными тестами и дождитесь ее исправления.
(2), как правило, тот, который sysadmins, по моему опыту, предпочитает.
Если вы идете с (2), то, тем временем, поскольку вы знаете, что вызывает ошибку, вы можете либо не допускать, чтобы входные данные поступали в класс, чтобы предотвратить проблему, либо быть готовым к ее правильной обработке, когда ошибка происходит.
Вы также можете использовать AspectJ для ввода кода в класс проблем и изменения поведения метода без фактической перекомпиляции. Я думаю, что это может быть предпочтительным вариантом, так как вы можете изменить его для всего кода, который может вызвать функцию, не беспокоясь о том, чтобы обучать всех проблеме.
Если вы научитесь читать инструкции байт-кода, что вы будете делать, чтобы решить проблему?
Ответ 5
У меня есть два вопроса
1) Какие инструменты доступны для просмотра java-байтового кода (желательно из командной строки linux)
Инструмент javap
(с параметром -c) будет дизассемблировать файл байт-кода. Он запускается из командной строки и поставляется как часть Java SDK.
2) Каковы хорошие ссылки, чтобы ознакомиться с синтаксисом java-байтового кода
Инструмент javap
использует тот же синтаксис, который используется в спецификации JVM, и спецификация JVM, естественно, является окончательным источником. Я также заметил "Внутри виртуальной машины Java" Билла Веннера. Я никогда не читал его, и похоже, что это может быть из печати.
Фактический (текстовый) синтаксис прост и понятен самостоятельно... при условии, что у вас есть ссылка, которая объясняет, что делают байт-коды, и что вы умеренно знакомы с чтением кода на этом уровне. Но, скорее всего, будет легче считывать выходные данные декомпилятора, даже если байт-коды подаются через обфускатор.
Ответ 6
Вы можете найти плагин Eclipse Byte Code Outline:
http://andrei.gmxhome.de/bytecode/index.html
Я не использовал его сам - просто видел, как это упоминалось попутно.