2013-09-25 6 views
9

При упаковке банки файла с пользовательскими Java агентом, вы можете добавить следующие свойства:разница между переназначением и ретрансформацией в javaagent

  • Can-Redefine-Classes
  • Can-Retransform-Classes

В чем разница между теми, два?

Если переопределение происходит до того, как класс загружен и ретрансформация после, то когда происходит точно ретрансформация?

ответ

4

Переопределение означает, что в произвольный момент времени агент будет ссылаться на Инструментарий. redefineClasses, чтобы изменить фактическое определение существующих (и уже загруженных) классов. Агент предоставит байт-код для нового определения.

Ретрансформация относится к процессу преобразования файлов классов, который обычно применяется при загрузке класса. Агенты могут регистрировать ClassFileTransformers, которые вызываются один за другим, чтобы применить преобразования к байтовому коду перед инициализацией класса. Таким образом, Retransformation ссылается на возможность JVM повторять этот процесс для уже загруженных классов. В этом случае агент может ссылаться на Instrumentation.retransformClasses, определяя, какие классы следует преобразовывать, но не байт-код. Вместо этого JVM будет вызывать все зарегистрированные ретрансляционные технологии ClassFileTransformers, обеспечивающие фактический байт-код (или результат предыдущего трансформатора для цепного трансформатора).

3

Они кажутся почти излишними в функциональности, которую они нам предлагают. Основное различие, по-видимому, состоит в том, что когда мы переопределяем класс byte[] с новым определением, то когда мы возвращаем ретрансформатор, получаем byte[], содержащий текущее определение через тот же API, и мы вернуть модифицированный byte[].

Поэтому, до redefine, нам нужно знать больше о классе. Рассмотрим пример использования инструкций трассировки трассировки. С retransform вы можете сделать это более непосредственно: просто посмотрите на приведенный байт-код, измените его и верните. Но если мы отправили маршрут redefine, нам нужно было бы взять оригинал byte[] откуда-то (например, getResourceAsStream()).

Другая очевидная разница заключается в том, как мы взаимодействуем с другими трансформаторами класса; кто идет первым. Преобразования применяются к исходному или переопределенному классу, поэтому несколько преобразований могут быть аддитивными, например.

Исторически, если мы посмотрим на Так как комментарии в API documentation или на странице 238 this book (Фризен 2007 Начиная Java SE 6 Platform), мы замечаем, что переопределение возможности были введены в Java 5, и ретрансформация в Java 6. Я предполагаю, что ретрансформация была представлена ​​как более общая возможность, но переопределение должно было быть сохранено для обратной совместимости.

Цитирование ключевого предложения о ретрансформации методы из книги, связанная выше:

агенты используют эти методы ретрансформацией ранее загруженные классов без необходимости доступа к их файлам класс.


Вторая часть вопроса:

Если переопределение происходит перед загрузкой класса и ретрансформации после, а затем, когда это точно произойдет ретрансформации?

Нет, переопределение происходит после загрузки класса, а также ретрансляции. Они случаются, когда вы вызываете свои методы Instrumentation экземпляров redefineClasses(..) и retransformClasses(..) соответственно.

Вот вопрос к любым экспертам мимо: есть все, что вы можете сделать переосмыслением классов, которые вы не можете сделать ретрансформацией их? Я предполагаю, что ответ «ничего».