Как отладить байт-код, введенный в ВМ во время загрузки класса? - PullRequest
4 голосов
/ 13 ноября 2010

Контекст: в моем Java-проекте я байт-код внедряю в класс (скажем, Injected.java), а также байт-код, внедряющий ссылку на метод в Injected.java, так что этот метод устанавливает значение экземплярачлен.Это один из способов убедиться, что байт-код вводит правильные вещи.

Проблема: во время выполнения значение переменной экземпляра не устанавливается так, как ожидалось - это означает, что мое внедрение байт-кода очевидноне работает должным образом.

Вопрос: 1) Как мне проверить содержимое моего (недавно внедренного + модифицированного) класса, загруженного в JVM во время выполнения?(javap помогает сделать это для существующих классов) 2) Могу ли я отлаживать через Eclipse, код с байт-кодом?Есть ли плагин

Любое предложение приветствуется.

1 Ответ

1 голос
/ 13 ноября 2010

Вы можете использовать javaassist

Пойдем шаг за шагом:

  1. Получить содержимое файла класса (скажем, Point.class ), которое вы хотите изменить путем внедрения байт-кода BufferedInputStream fin = new BufferedInputStream(new FileInputStream("Point.class")); ClassFile cf = new ClassFile(new DataInputStream(fin));

  2. ClassFile предоставляет addField () и addMethod () для добавления поля или метода (обратите внимание, что конструктор рассматривается как метод на уровне байт-кода). Он также предоставляет addAttribute () для добавления атрибута в файл класса.

    Обратите внимание, что объекты FieldInfo, MethodInfo и AttributeInfo содержат ссылку на объект ConstPool (постоянная таблица пула). Объект ConstPool должен быть общим для объекта ClassFile и объекта FieldInfo (или MethodInfo и т. Д.), Который добавляется к этому объекту ClassFile. Другими словами, объект FieldInfo (или MethodInfo и т. Д.) Не должен совместно использоваться различными объектами ClassFile.

    Чтобы удалить поле или метод из объекта ClassFile, вы должны сначала получить объект java.util.List, содержащий все поля класса. getFields () и getMethods () возвращают списки. Поле или метод можно удалить, вызвав метод remove () объекта List. Атрибут может быть удален аналогичным образом. Вызовите getAttributes () в FieldInfo или MethodInfo, чтобы получить список атрибутов, и удалите один из списка.

  3. Теперь проверьте, действительно ли инъекция сработала:

    MethodInfo minfo = cf.getMethod("move"); // we assume move is not overloaded.

    CodeAttribute ca = minfo.getCodeAttribute();

    Существует несколько методов в MethodInfo / CodeAttribute для проверки

Если вам это нравится, пожалуйста, дайте мне знать. В этом случае я выложу более подробный блог на http://puspendu.wordpress.com/

Ссылка: здесь

...