Spec-Zone.ru › OpenJDK 17

Интерфейс ClassFileTransformer

public interface ClassFileTransformer
Преобразователь файлов классов. Агент регистрирует реализацию этого интерфейса с помощью метода addTransformer, чтобы метод преобразователя transform вызывался при загрузке классов, redefined или retransformed. Реализация должна переопределить один из методов transform определенных здесь. Преобразователи вызываются до того, как виртуальная машина Java определит класс.

Существует два вида преобразователей, определяемых параметром canRetransform метода Instrumentation.addTransformer(ClassFileTransformer,boolean):

  • способные к повторной трансформации преобразователи, добавленные с параметром canRetransform равным true
  • неспособные к повторной трансформации преобразователи, добавленные с параметром canRetransform равным false или добавленные с помощью метода Instrumentation.addTransformer(ClassFileTransformer)

После регистрации преобразователя с помощью метода addTransformer, преобразователь будет вызываться для каждого нового определения класса и каждой переопределения класса. Способные к повторной трансформации преобразователи также будут вызываться при каждой повторной трансформации класса. Запрос на новое определение класса выполняется с помощью метода ClassLoader.defineClass или его аналогов нативных методов. Запрос на переопределение класса выполняется с помощью Instrumentation.redefineClasses или его аналогов нативных методов. Запрос на повторную трансформацию класса выполняется с помощью Instrumentation.retransformClasses или его аналогов нативных методов. Преобразователь вызывается во время обработки запроса, до проверки или применения байтовых кодов файла класса. При наличии нескольких преобразователей преобразования выполняются последовательно путем объединения вызовов transform. То есть, байтовый массив, возвращаемый одним вызовом transform , становится входом (через параметр classfileBuffer) для следующего вызова.

Преобразования применяются в следующем порядке:

  • Преобразователи, не способные к повторной трансформации
  • Нативные преобразователи, не способные к повторной трансформации
  • Преобразователи, способные к повторной трансформации
  • Нативные преобразователи, способные к повторной трансформации

Для повторных трансформаций преобразователи, не способные к повторной трансформации, не вызываются, вместо этого используется результат предыдущего преобразования. Во всех остальных случаях этот метод вызывается. Внутри каждой из этих групп преобразователи вызываются в порядке их регистрации. Нативные преобразователи предоставляются событием ClassFileLoadHook в интерфейсе инструментария виртуальной машины Java).

Входной массив (через параметр classfileBuffer ) для первого преобразователя:

  • для нового определения класса, байты, переданные в ClassLoader.defineClass
  • для переопределения класса, definitions.getDefinitionClassFile() , где definitions является параметром метода Instrumentation.redefineClasses
  • для повторной трансформации класса, байты, переданные для нового определения класса или, если класс был переопределен, последний результат переопределения, со всеми преобразованиями, выполненными преобразователями, не способными к повторной трансформации, автоматически и без изменений повторно применёнными; подробности см. в Instrumentation.retransformClasses

Если реализующий метод определяет, что преобразования не нужны, он должен вернуть null. В противном случае он должен создать новый массив byte[], скопировать входной массив classfileBuffer в него, вместе со всеми желаемыми преобразованиями, и вернуть новый массив. Входной массив classfileBuffer не должен быть изменен.

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

Если преобразователь вызывает исключение (которое он не перехватывает), последующие преобразователи все равно будут вызваны, и загрузка, переопределение или повторная трансформация все равно будут попытанны. Таким образом, выброс исключения имеет тот же эффект, что и возврат null. Чтобы предотвратить неожиданное поведение при возникновении необрабатываемых исключений в коде преобразователя, преобразователь может перехватить Throwable. Если преобразователь считает, что classFileBuffer не представляет собой правильно отформатированный файл класса, он должен выбросить исключение IllegalClassFormatException; хотя это имеет тот же эффект, что и возврат null. Это облегчает ведение журнала или отладку ошибок формата.

Термин файл класса используется в соответствии с определением в разделе 3.1 спецификации «The Java Virtual Machine Specification», и означает последовательность байтов в формате файла класса, независимо от того, находятся ли они в файле.

Since:
1.5
See Also:
  • Instrumentation

Краткое описание методов

Модификатор и тип Метод Описание
default byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer)
Преобразует данный файл класса и возвращает новый файл заменяющего класса.
default byte[] transform(Module module, ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer)
Преобразует данный файл класса и возвращает новый файл заменяющего класса.

Подробное описание методов

transform

default byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException
Преобразует данный файл класса и возвращает новый файл заменяющего класса. Этот метод вызывается, когда метод Module содержащий метод transform не переопределён.
Требования к реализации:
По умолчанию возвращает null.
Параметры:
loader - загружающий класс преобразуемого класса, может быть null если это загрузчик Bootstrap
className - имя класса в внутреннем формате полных квалифицированных имен классов и интерфейсов, как определено в спецификации «The Java Virtual Machine Specification». Например, "java/util/List".
classBeingRedefined - если это вызов связанный с переопределением или повторной трансформацией, класс, который переопределяется или повторно преобразуется; если это загрузка класса, null
protectionDomain - область защиты класса, который определяется или переопределяется
classfileBuffer - входной байтовый буфер в формате файла класса - не должен быть изменён
Возвращает:
буфер хорошо сформированного файла класса (результат преобразования) или null если преобразование не выполняется
Исключения:
IllegalClassFormatException - если вход не представляет собой правильно сформированный файл класса

transform

default byte[] transform(Module module, ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException
Преобразует данный файл класса и возвращает новый файл заменяющего класса.
Требования к реализации:
По умолчанию этот метод вызывает метод transform.
Параметры:
module - модуль преобразуемого класса
loader - загружающий класс преобразуемого класса, может быть null если это загрузчик Bootstrap
className - имя класса в внутреннем формате полных квалифицированных имен классов и интерфейсов, как определено в спецификации «The Java Virtual Machine Specification». Например, "java/util/List".
classBeingRedefined - если это вызов связанный с переопределением или повторной трансформацией, класс, который переопределяется или повторно преобразуется; если это загрузка класса, null
protectionDomain - область защиты класса, который определяется или переопределяется
classfileBuffer - входной байтовый буфер в формате файла класса - не должен быть изменён
Возвращает:
буфер хорошо сформированного файла класса (результат преобразования) или null если преобразование не выполняется
Исключения:
IllegalClassFormatException - если вход не представляет собой правильно сформированный файл класса
Since:
9

© 1993, 2021, Oracle and/or its affiliates. All rights reserved.
Documentation extracted from Debian's OpenJDK Development Kit package.
Licensed under the GNU General Public License, version 2, with the Classpath Exception.
Various third party code in OpenJDK is licensed under different licenses (see Debian package).
Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.
https://docs.oracle.com/en/java/javase/17/docs/api/java.instrument/java/lang/instrument/ClassFileTransformer.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API