Spec-Zone.ru › OpenJDK 8

Интерфейс ClassFileTransformer


public interface ClassFileTransformer

Агент предоставляет реализацию этого интерфейса для преобразования файлов классов. Преобразование происходит перед определением класса JVM.

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

С:
1.5
См. также:
Instrumentation, Instrumentation.addTransformer(java.lang.instrument.ClassFileTransformer, boolean), Instrumentation.removeTransformer(java.lang.instrument.ClassFileTransformer)

Методы

Модификатор и тип Метод и описание
byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer)

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

Методы

transform

byte[] transform(ClassLoader loader,
                 String className,
                 Class<?> classBeingRedefined,
                 ProtectionDomain protectionDomain,
                 byte[] classfileBuffer)
          throws IllegalClassFormatException

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

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

Параметры:
loader - определяющий загрузчик класса, который должен быть преобразован, может быть null если загрузчик bootstrap
className - имя класса во внутреннем формате полностью квалифицированных имен классов и интерфейсов, как определено в спецификации The Java Virtual Machine Specification. Например, "java/util/List".
classBeingRedefined - если это вызвано переопределением или повторным преобразованием, класс, который переопределяется или повторно преобразуется; если это загрузка класса, null
protectionDomain - область защиты класса, который определен или переопределен
classfileBuffer - входной буфер байтов в формате файла класса - не должен быть изменен
Возвращает:
буфер файла класса с правильным форматом (результат преобразования) или null если преобразование не выполняется.
Исключения:
IllegalClassFormatException - если вход не представляет собой правильно отформатированный файл класса
См. также:
Instrumentation.redefineClasses(java.lang.instrument.ClassDefinition...)

© 1993, 2020, 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.

Spec-Zone.ru

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