Понимание байт-кода 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

Я не использовал его сам - просто видел, как это упоминалось попутно.