Spec-Zone.ru › OpenJDK 21

Интерфейс 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 Спецификации виртуальной машины Java, для обозначения последовательности байтов в формате файла класса, независимо от того, хранятся ли они в файле.

С момента:
1.5
См. также:
  • 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 , если используется загрузчик загрузки
className - имя класса в внутреннем формате полных квалифицированных имен классов и интерфейсов, как определено в Спецификации виртуальной машины Java. Например, "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 , если используется загрузчик загрузки
className - имя класса в внутреннем формате полных квалифицированных имен классов и интерфейсов, как определено в Спецификации виртуальной машины Java. Например, "java/util/List".
classBeingRedefined - если это вызвано переопределением или повторной трансформацией, класс, который переопределяется или подвергается повторной трансформации; если это загрузка класса, null
protectionDomain - область защиты класса, который определяется или переопределяется
classfileBuffer - входной буфер байтов в формате файла класса — не должен изменяться
Возвращает:
буфер файла класса правильной формы (результат преобразования), или null если преобразование не выполняется
Исключения:
IllegalClassFormatException - если входные данные не представляют собой корректный отформатированный файл класса
С момента:
9

© 1993, 2023, 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/21/docs/api/java.instrument/java/lang/instrument/ClassFileTransformer.html

Spec-Zone.ru

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