Этот класс предоставляет услуги, необходимые для инструментирования кода на языке Java. Инструментирование заключается в добавлении байт-кодов в методы с целью сбора данных для использования инструментами. Поскольку изменения являются чисто добавочными, эти инструменты не изменяют состояние или поведение приложения. Примерами таких безвредных инструментов являются агенты мониторинга, профилировщики, анализаторы покрытия и логгеры событий.
Получить экземпляр интерфейса Instrumentation можно двумя способами:
Когда JVM запускается с указанием класса агента. В этом случае экземпляр Instrumentation передается методу premain класса агента.
Когда JVM предоставляет механизм для запуска агентов после запуска JVM. В этом случае экземпляр Instrumentation передается методу agentmain кода агента.Эти механизмы описаны в спецификации пакета.
Как только агент получает экземпляр Instrumentation
, он может вызывать методы этого экземпляра в любое время.
package java.lang.instrument;
import java.io.File;
import java.io.IOException;
import java.util.jar.JarFile;
/*
* Copyright 2003 Wily Technology, Inc.
*/
Существует два способа получения экземпляра интерфейса
Instrumentation
:
Эти механизмы описаны в спецификации пакета {@linkplain java.lang.instrument}.
Как только агент получает экземпляр Instrumentation
, агент может вызывать методы этого экземпляра в любое время.```java
public interface Instrumentation {
Регистрирует предоставленный преобразователь. Преобразователь будет видеть все будущие определения классов, кроме определений классов, на которых зависят любые зарегистрированные преобразователи. Преобразователь вызывается при загрузке классов и при их переопределении. Если canRetransform равно true, он будет вызван при переформатировании классов. Порядок вызовов преобразования указан в методе `ClassFileTransformer.transform`. Если преобразователь выбрасывает исключение во время выполнения, JVM все равно вызовет остальные зарегистрированные преобразователи в порядке. Тот же преобразователь может быть добавлен более одного раза, но это сильнее всего не рекомендуется — избегайте этого, создавая новый экземпляр класса преобразователя.Регистрирует предоставленный преобразователь. Преобразователь будет видеть все будущие определения классов, кроме определений классов, на которых зависят любые зарегистрированные преобразователи. Преобразователь вызывается при загрузке классов, при их переопределении. Если canRetransform равно true, при их переформатировании. Порядок вызовов преобразования указан в ClassFileTransformer.transform. Если преобразователь выбрасывает исключение во время выполнения, JVM все равно вызовет остальные зарегистрированные преобразователи в порядке. Тот же преобразователь может быть добавлен более одного раза, но это сильнее всего не рекомендуется — избегайте этого, создавая новый экземпляр класса преобразователя.
Этот метод предназначен для использования в инструментировании, как описано в спецификации класса.
Этот метод предназначен для использования в инструментировании, как описано в спецификации класса.
Параметры:
- transformer – трансформер для регистрации
- canRetransform – может ли трансформация этого трансформера быть переформирована
Выбрасывает:
- NullPointerException – если передан null трансформер
- UnsupportedOperationException – если canRetransform истинно и текущая конфигурация JVM не позволяет переформирование (isRetransformClassesSupported является false)
См. также:
с версии 1.6```java
void
addTransformer(ClassFileTransformer transformer, boolean canRetransform);
```Зарегистрировать предоставленный трансформер. Зарегистрировать поддерживаемый трансформер.
<P>
То же самое, что <code>addTransformer(transformer, false)</code>.
@param transformer трансформер для регистрации
@throws java.lang.NullPointerException если передан <code>null</code> трансформер
@see #addTransformer(ClassFileTransformer,boolean)
```java
void
addTransformer(ClassFileTransformer transformer);
Отменить регистрацию предоставленного трансформера. Будущие определения классов не будут показаны трансформеру. Удаляет последний добавленный соответствующий экземпляр трансформера.
Отменяет регистрацию предоставленного трансформера. Будущие определения классов не будут переданы трансформеру. Удаляет последний добавленный соответствующий экземпляр трансформера.
В связи с многопоточным характером загрузки классов, возможно, что трансформер будет получать вызовы после своего удаления. Трансформеры должны быть написаны с учетом защиты, чтобы ожидать этой ситуации.
@param transformer трансформер для отмены регистрации
@return true, если трансформер был найден и удален, false, если трансформер не был найден
@throws java.lang.NullPointerException если передан null
трансформер
boolean
removeTransformer(ClassFileTransformer transformer);
Возвращает, поддерживает ли текущая конфигурация JVM переформирование классов.
Возвращает, поддерживает ли текущая конфигурация JVM переформирование классов.Возможность переформирования уже загруженного класса является опциональной функцией JVM. Переформирование будет поддерживаться только в том случае, если атрибут манифеста Can-Retransform-Classes в файле JAR агента (как описано в спецификации пакета) установлен на true и JVM поддерживает эту функцию.
Переформирование уже загруженного класса является опциональной функцией JVM. Переформирование будет поддерживаться только в том случае, если атрибут манифеста Can-Retransform-Classes в файле JAR агента (как описано в спецификации пакета) установлен на true и JVM поддерживает эту функцию.
В течение одного запуска одного экземпляра JVM, повторные вызовы этого метода всегда будут возвращать одинаковый ответ.
В течение одного запуска одного экземпляра JVM, повторные вызовы этого метода всегда будут возвращать одинаковый ответ. Возвращает: true, если текущая конфигурация JVM поддерживает переформатирование классов, false, если нет. См. также: 1.6
boolean
isRetransformClassesSupported();
Переформатировать предоставленное множество классов.Эта функция упрощает инструментирование уже загруженных классов. Когда классы загружаются в первый раз или когда они переопределяются, начальные байты файлов классов могут быть преобразованы с помощью ClassFileTransformer. Эта функция повторно запускает процесс преобразования (независимо от того, произошло ли преобразование ранее). Этот процесс переформатирования следует этим шагам:```markdown Возвращает: true, если текущая конфигурация JVM поддерживает переформатирование классов, false, если нет. См. также: 1.6
boolean isRetransformClassesSupported();
Переформатировать предоставленное множество классов. Этот метод позволяет инструментировать уже загруженные классы. Когда классы загружаются в первый раз или переопределяются, начальные байты файлов классов могут быть преобразованы с помощью ClassFileTransformer. Этот метод повторно запускает процесс преобразования (независимо от того, происходило ли преобразование ранее). Переформатирование выполняется по следующим шагам:
начиная с начальных байтов файлов классов
для каждого преобразователя, добавленного с canRetransform false, байты, возвращенные методом transform во время последней загрузки класса или переопределения, используются вновь как результат преобразования; обратите внимание, что это эквивалентно повторному применению предыдущего преобразования без изменений; за исключением того, что метод transform не вызывается
для каждого преобразователя, добавленного с canRetransform true, метод transform вызывается в этих преобразователях
преобразованные байты файлов классов устанавливаются как новое определение класса
Порядок преобразования описан в методе transform. Тот же порядок используется в автоматическом повторном применении неспособных к переформатированию преобразователей.
- преобразованные байты файла класса устанавливаются как новое определение классаПорядок трансформации описан в методе transform. Этот же порядок используется при автоматическом повторном применении трансформаций, которые не могут быть повторно применены.
```Изначальные байты файла класса представляют байты, переданные в ClassLoader.defineClass или redefineClasses (до применения любых трансформаций), однако они могут не совпадать с ними точно. Пул постоянных значений может не иметь такой же структуры или содержимого. Пул постоянных значений может содержать больше или меньше записей. Записи пула постоянных значений могут находиться в другом порядке; однако индексы пула постоянных значений в байт-коде методов будут соответствовать. Некоторые атрибуты могут отсутствовать. Где порядок не имеет значения, например, порядок методов, порядок может не сохраняться.Инициализационный файл класса представляет собой последовательность байтов, передаваемую методу ClassLoader.defineClass или redefineClasses (до применения любых преобразований), но он может не совпадать полностью. Константный пул может иметь отличную структуру или содержимое. Константный пул может содержать больше или меньше записей. Порядок записей в константном пуле может отличаться. Однако индексы константного пула в байт-коде методов будут соответствовать. Некоторые атрибуты могут отсутствовать. Если порядок не имеет значения, например, порядок методов, он может не сохраняться.```Этот метод работает с набором, чтобы позволить одновременное выполнение взаимозависимых изменений для нескольких классов (переопределение класса A может потребовать переопределения класса B).
Если переопределенный метод имеет активные стековые кадры, эти активные кадры продолжат выполнение байт-кода исходного метода. Переопределенный метод будет использоваться для новых вызовов.
Этот метод не вызывает никакой инициализации, кроме той, которая произойдет в соответствии с обычными семантиками JVM. Другими словами, переопределение класса не вызывает выполнение его инициализаторов. Значения статических переменных останутся такими же, какими они были до вызова.
Экземпляры переопределенного класса не затрагиваются.Переопределение может изменять тела методов, константный пул и атрибуты. Переопределение не должно добавлять, удалять или переименовывать поля или методы, изменять сигнатуры методов или изменять наследование. Эти ограничения могут быть сняты в будущих версиях. Байт-код файла класса не проверяется, не верифицируется и не устанавливается до применения всех преобразований. Если результирующий байт-код содержит ошибки, этот метод выбросит исключение.
Переустановка может изменить тело метода, пулы констант и атрибуты. Переустановка не должна добавлять, удалять или переименовывать поля или методы, изменять сигнатуру метода или изменять наследование. Эти ограничения могут быть сняты в будущих версиях. Проверка, валидация и установка байт-кодов классов выполняются после применения преобразования. Если результат байт-кода неверен, этот метод выбросит исключение.
Если этот метод выбрасывает исключение, то ни один класс не был перезапроектирован.Если классы не могут быть перезапрошитованы, то этот метод предназначен для использования в инструментарии, как описано в спецификации класса.
Параметры:
classes – массив классов для перезапроса; допускается нулевая длина массива, в этом случае этот метод ничего не делает
Выбрасывает:
UnmodifiableClassException – если указанный класс не может быть изменен (isModifiableClass вернет false)
UnsupportedOperationException – если текущая конфигурация JVM не позволяет перезапрос (isRetransformClassesSupported вернет false) или попытка перезапроса предприняла недопустимые изменения
ClassFormatError – если данные не содержат валидного класса
NoClassDefFoundError – если имя в файле класса не равно имени класса
UnsupportedClassVersionError – если номера версий файла класса не поддерживаются
ClassCircularityError – если новые классы содержат цикличность
LinkageError – если произошла ошибка связи
NullPointerException – если предоставленный массив классов или любой из его компонентов является null.
См. также:
1.6
```java
void
retransformClasses(Class<?>... classes) throws UnmodifiableClassException;
``````markdown
/**
* Возвращает, поддерживает ли текущая конфигурация JVM перезапрос классов.
* Возможность перезапроса уже загруженного класса является опциональной возможностью JVM.
* Перезапрос будет поддерживаться только если атрибут манифеста <code>Can-Redefine-Classes</code> установлен в <code>true</code> в JAR-файле агента (как описано в спецификации пакета {@linkplain java.lang.instrument}) и JVM поддерживает эту возможность.
* В течение одной инстанции одной JVM повторные вызовы этого метода всегда будут возвращать одинаковый ответ.
* @return true, если текущая конфигурация JVM поддерживает перезапрос классов, false в противном случае.
* @see #redefineClasses
*/
boolean
isRedefineClassesSupported();
``` /**
* Перерасчет поставляемого набора классов с использованием поставляемых файлов классов.
*
* <p>
* Этот метод используется для замены определения класса без ссылки на существующие байты файла класса,
* как это может быть сделано при перекомпиляции из исходного кода для отладки с фиксацией и продолжением.
* Если существующие байты файла класса должны быть трансформированы (например, при инструментировании байткода),
* следует использовать метод {@link #retransformClasses retransformClasses}.
*
* <p>
* Этот метод работает с набором классов для возможности одновременного изменения нескольких взаимозависимых классов
* (перерасчет класса A может потребовать перерасчета класса B).
*
* <p>
*
``` * Если перерасчитанный метод имеет активные стеки вызовов, эти активные стеки продолжают выполнять байткоды исходного метода.
* Перерасчитанный метод будет использоваться для новых вызовов.
*
* <P>
* Этот метод не вызывает никакой инициализации, кроме той, которая произойдет в соответствии с обычными семантиками JVM.
* Другими словами, перерасчет класса не вызывает выполнение его инициализаторов. Значения статических переменных останутся такими же, какими они были до вызова.
*
* <P>
* Экземпляры перерасчитанного класса не затрагиваются.
*
* <P>
* Перерасчет может изменять тела методов, константный пул и атрибуты.
* Перерасчет не должен добавлять, удалять или переименовывать поля или методы, изменять сигнатуры методов или изменять наследование.
* Эти ограничения могут быть сняты в будущих версиях. Байты файла класса не проверяются, не проверяются и не устанавливаются до применения трансформаций.
* Если результирующие байты содержат ошибки, этот метод выбросит исключение.
*
* <P>
* Если этот метод выбросит исключение, ни один класс не будет перерасчитан.
* <P>
* Этот метод предназначен для использования в инструментировании, как описано в спецификации класса {@linkplain Instrumentation}.
*
* @param definitions массив классов для перерасчета с соответствующими определениями;```markdown
* допускается нулевая длина массива, в этом случае этот метод ничего не делает
* @throws java.lang.instrument.UnmodifiableClassException если указанный класс не может быть изменен
* ({@link #isModifiableClass} вернет <code>false</code>)
* @throws java.lang.UnsupportedOperationException если текущая конфигурация JVM не позволяет
* переопределение ({@link #isRedefineClassesSupported} равно false) или попытка переопределения
* вносит недопустимые изменения
* @throws java.lang.ClassFormatError если данные не содержат валидного класса
* @throws java.lang.NoClassDefFoundError если имя в файле класса не равно имени класса
* @throws java.lang.UnsupportedClassVersionError если номера версий файла класса не поддерживаются
* @throws java.lang.ClassCircularityError если новые классы содержат циклическую зависимость
* @throws java.lang.LinkageError если произошла ошибка связывания
* @throws java.lang.NullPointerException если массив определений классов или любой из его компонентов
* равен <code>null</code>
* @throws java.lang.ClassNotFoundException Никогда не выбрасывается (присутствует только для совместимости)
*
* @see #isRedefineClassesSupported
* @see #addTransformer
* @see java.lang.instrument.ClassFileTransformer
*/
void redefineClasses(ClassDefinition... definitions)
throws ClassNotFoundException, UnmodifiableClassException;
```markdown
* Определяет, может ли класс быть изменен с помощью
* {@linkplain #retransformClasses перетрансформации}
* или {@linkplain #redefineClasses перераз界}.
* Если класс может быть изменен, этот метод возвращает <code>true</code>.
```markdown
* допускается нулевая длина массива, в этом случае этот метод ничего не делает
* @throws java.lang.instrument.UnmodifiableClassException если указанный класс не может быть изменен
* ({@link #isModifiableClass} вернет <code>false</code>)
* @throws java.lang.UnsupportedOperationException если текущая конфигурация JVM не позволяет
* переопределение ({@link #isRedefineClassesSupported} равно false) или попытка переопределения
* вносит недопустимые изменения
* @throws java.lang.ClassFormatError если данные не содержат валидного класса
* @throws java.lang.NoClassDefFoundError если имя в файле класса не равно имени класса
* @throws java.lang.UnsupportedClassVersionError если номера версий файла класса не поддерживаются
* @throws java.lang.ClassCircularityError если новые классы содержат циклическую зависимость
* @throws java.lang.LinkageError если произошла ошибка связывания
* @throws java.lang.NullPointerException если массив определений классов или любой из его компонентов
* равен <code>null</code>
* @throws java.lang.ClassNotFoundException Никогда не выбрасывается (присутствует только для совместимости)
*
* @see #isRedefineClassesSupported
* @see #addTransformer
* @see java.lang.instrument.ClassFileTransformer
*/
void redefineClasses(ClassDefinition... definitions)
throws ClassNotFoundException, UnmodifiableClassException;
```markdown
* Определяет, может ли класс быть изменен с помощью
* {@linkplain #retransformClasses перетрансформации}
* или {@linkplain #redefineClasses перераз界}.
* Если класс может быть изменен, этот метод возвращает <code>true</code>.
```markdown
* допускается нулевая длина массива, в этом случае этот метод ничего не делает
* @throws java.lang.instrument.UnmodifiableClassException если указанный класс не может быть изменен
* ({@link #isModifiableClass} вернет <code>false</code>)
* @throws java.lang.UnsupportedOperationException если текущая конфигурация JVM не позволяет
* переопределение ({@link #isRedefineClassesSupported} равно false) или попытка переопределения
* вносит недопустимые изменения
* @throws java.lang.ClassFormatError если данные не содержат валидного класса
* @throws java.lang.NoClassDefFoundError если имя в файле класса не равно имени класса
* @throws java.lang.UnsupportedClassVersionError если номера версий файла класса не поддерживаются
* @throws java.lang.ClassCircularityError если новые классы содержат циклическую зависимость
* @throws java.lang.LinkageError если произошла ошибка связывания
* @throws java.lang.NullPointerException если массив определений классов или любой из его компонентов
* равен <code>null</code>
* @throws java.lang.ClassNotFoundException Никогда не выбрасывается (присутствует только для совместимости)
*
* @see #isRedefineClassesSupported
* @see #addTransformer
* @see java.lang.instrument.ClassFileTransformer
*/
void redefineClasses(ClassDefinition... definitions)
throws ClassNotFoundException, UnmodifiableClassException;
```markdown
* Определяет, может ли класс быть изменен с помощью
* {@linkplain #retransformClasses перетрансформации}
* или {@linkplain #redefineClasses перераз界}.
* Если класс может быть изменен, этот метод возвращает <code>true</code>.
```markdown
* допускается нулевая длина массива, в этом случае этот метод ничего не делает
* @throws java.lang.instrument.UnmodifiableClassException если указанный класс не может быть изменен
* ({@link #isModifiableClass} вернет <code>false</code>)
* @throws java.lang.UnsupportedOperationException если текущая конфигурация JVM не позволяет
* переопределение ({@link #isRedefineClassesSupported} равно false) или попытка переопределения
* вносит недопустимые изменения
* @throws java.lang.ClassFormatError если данные не содержат валидного класса
* @throws java.lang.NoClassDefFoundError если имя в файле класса не равно имени класса
* @throws java.lang.UnsupportedClassVersionError если номера версий файла класса не поддерживаются
* @throws java.lang.ClassCircularityError если новые классы содержат циклическую зависимость
* @throws java.lang.LinkageError если произошла ошибка связывания
* @throws java.lang.NullPointerException если массив определений классов или любой из его компонентов
* равен <code>null</code>
* @throws java.lang.ClassNotFoundException Никогда не выбрасывается (присутствует только для совместимости)
*
* @see #isRedefineClassesSupported
* @see #addTransformer
* @see java.lang.instrument.ClassFileTransformer
*/
void redefineClasses(ClassDefinition... definitions)
throws ClassNotFoundException, UnmodifiableClassException;
```markdown
* Определяет, может ли класс быть изменен с помощью
* {@linkplain #retransformClasses перетрансформации}
* или {@linkplain #redefineClasses перераз界}.
* Если класс может быть изменен, этот метод возвращает <code>true</code>.
```markdown
* допускается нулевая длина массива, в этом случае этот метод ничего не делает
* @throws java.lang.instrument.UnmodifiableClassException если указанный класс не может быть изменен
* ({@link #isModifiableClass} вернет <code>false</code>)
* @throws java.lang.UnsupportedOperationException если текущая конфигурация JVM не позволяет
* переопределение ({@link #isRedefineClassesSupported} равно false) или попытка переопределения
* вносит недопустимые изменения
* @throws java.lang.ClassFormatError если данные не содержат валидного класса
* @throws java.lang.NoClassDefFoundError если имя в файле класса не равно имени класса
* @throws java.lang.UnsupportedClassVersionError если номера версий файла класса не поддерживаются
* @throws java.lang.ClassCircularityError если новые классы содержат циклическую зависимость
* @throws java.lang.LinkageError если произошла ошибка связывания
* @throws java.lang.NullPointerException если массив определений классов или любой из его компонентов
* равен <code>null</code>
* @throws java.lang.ClassNotFoundException Никогда не выбрасывается (присутствует только для совместимости)
*
* @see #isRedefineClassesSupported
* @see #addTransformer
* @see java.lang.instrument.ClassFileTransformer
*/
void redefineClasses(ClassDefinition... definitions)
throws ClassNotFoundException, UnmodifiableClassException;
```markdown
* Определяет, может ли класс быть изменен с помощью
* {@linkplain #retransformClasses перетрансформации}
* или {@linkplain #redefineClasses перераз界}.
* Если класс может быть изменен, этот метод возвращает <code>true</code>.
```markdown
* допускается нулевая длина массива, в этом случае этот метод ничего не делает
* @throws java.lang.instrument.UnmodifiableClassException если указанный класс не может быть изменен
* ({@link #isModifiableClass} вернет <code>false</code>)
* @throws java.lang.UnsupportedOperationException если текущая конфигурация JVM не позволяет
* переопределение ({@link #isRedefineClassesSupported} равно false) или попытка переопределения
* вносит недопустимые изменения
* @throws java.lang.ClassFormatError если данные не содержат валидного класса
* @throws java.lang.NoClassDefFoundError если имя в файле класса не равно имени класса
* @throws java.lang.UnsupportedClassVersionError если номера версий файла класса не поддерживаются
* @throws java.lang.ClassCircularityError если новые классы содержат циклическую зависимость
* @throws java.lang.LinkageError если произошла ошибка связывания
* @throws java.lang.NullPointerException если массив определений классов или любой из его компонентов
* равен <code>null</code>
* @throws java.lang.ClassNotFoundException Никогда не выбрасывается (присутствует только для совместимости)
*
* @see #isRedefineClassesSupported
* @see #addTransformer
* @see java.lang.instrument.ClassFileTransformer
*/
void redefineClasses(ClassDefinition... definitions)
throws ClassNotFoundException, UnmodifiableClassException;
```markdown
* Определяет, может ли класс быть изменен с * Если класс не может быть изменен, этот метод возвращает <code>false</code>.
* <P>
* Для перетрансформации класса значение {@link #isRetransformClassesSupported} должно быть <code>true</code>.
* Но значение <code>isRetransformClassesSupported()</code> не влияет на значение, возвращаемое этим методом.
* Для переразделения класса значение {@link #isRedefineClassesSupported} должно быть <code>true</code>.
* Но значение <code>isRedefineClassesSupported()</code> не влияет на значение, возвращаемое этим методом.
* <P>
* Примитивные классы (например, <code>java.lang.Integer.TYPE</code>)
* и массивные классы никогда не могут быть изменены.
*
* @param theClass класс, который нужно проверить на возможность изменения
* @return <code>true</code>, если класс может быть изменен, иначе <code>false</code>
* @throws java.lang.NullPointerException если указанный класс равен <code>null</code>.
*
* @see #retransformClasses
* @see #isRetransformClassesSupported
* @see #redefineClasses
* * @see #isRedefineClassesSupported
* @since 1.6
*/
boolean
isModifiableClass(Class<?> theClass); /**
* Возвращает массив всех классов, загруженных в JVM.
*
* @return массив, содержащий все классы, загруженные в JVM; нулевой длины, если классов нет
*/
@SuppressWarnings("rawtypes")
Class[]
getAllLoadedClasses(); /**
* Возвращает массив всех классов, для которых <code>loader</code> является инициирующим загрузчиком.
* Если предоставленный загрузчик равен <code>null</code>, возвращаются классы, инициированные загрузчиком по умолчанию.
*
* @param loader загрузчик, для которого будет возвращен массив инициированных классов
* @return массив, содержащий все классы, для которых загрузчик является инициирующим загрузчиком, нулевой длины, если классов нет
*/
@SuppressWarnings("rawtypes")
Class[]
getInitiatedClasses(ClassLoader loader); /**
* Возвращает реализация-специфичное приближение объема хранилища, потребляемого
* указанным объектом. Результат может включать часть или все избыточные данные объекта,
* и поэтому полезен для сравнения внутри одной реализации, но не между разными реализациями.
*
* Оценка может изменяться в течение одного вызова JVM.
*
* @param objectToSize объект для измерения
* @return реализация-специфичное приближение объема хранилища, потребляемого указанным объектом
* @throws java.lang.NullPointerException если предоставленный объект равен <code>null</code>.
*/
long
getObjectSize(Object objectToSize); /**
* Указывает JAR-файл с классами инструментирования, которые должны быть определены загрузчиком классов по умолчанию.
*
* <p> Когда встроенный загрузчик классов виртуальной машины, известный как "загрузчик классов по умолчанию", не может найти класс,
* записи в {@link java.util.jar.JarFile} будут использоваться для определения классов.
*/
/**
* Возвращает JAR-файл, содержащий классы инструментирования.
*
* @return JAR-файл, содержащий классы инструментирования
*/
java.util.jar.JarFile
getInstrumentationJarFile();JarFile JAR-файлы} также будут проверены.
*
* <p> Этот метод может быть использован несколько раз для добавления нескольких JAR-файлов для поиска в порядке, в котором этот метод был вызван.
*
* <p> Агент должен убедиться, что JAR-файл не содержит никаких классов или ресурсов, кроме тех, которые должны быть определены загрузчиком классов по умолчанию для целей инструментирования.
* Нарушение этого предупреждения может привести к непредвиденному поведению, которое сложно диагностировать. Например, предположим, что есть загрузчик L, и родитель L для делегирования — загрузчик классов по умолчанию.
* Кроме того, метод в классе C, определённом L, ссылается на вспомогательный класс C$1. Если JAR-файл содержит класс C$1, то делегирование загрузчику классов по умолчанию приведёт к тому, что C$1 будет определён загрузчиком классов по умолчанию.
* В этом примере будет выброшено исключение <code>IllegalAccessError</code>, что может привести к сбою приложения. Одним из подходов к избежанию таких проблем является использование уникального имени пакета для классов инструментирования.
*
* <p>
* <cite>Спецификация виртуальной машины Java™</cite>
* указывает, что последующая попытка разрешения символической ссылки, которую виртуальная машина Java ранее не смогла разрешить, всегда завершается ошибкой, аналогичной той, которая была выброшена в результате первой попытки разрешения.
* В результате, если JAR-файл содержит запись, соответствующую классу, для которого виртуальная машина Java не смогла разрешить ссылку, последующие попытки разрешения этой ссылки завершатся ошибкой, аналогичной первой попытке.
*
* @param jarfile
* JAR-файл для поиска, когда загрузчик классов по умолчанию не может найти класс.
*
* @throws NullPointerException
* Если <code>jarfile</code> равно <code>null</code>.
*
* @see #appendToSystemClassLoaderSearch
*/ * @see java.lang.ClassLoader
* @see java.util.jar.JarFile
*
* @since 1.6
*/
void
appendToBootstrapClassLoaderSearch(JarFile jarfile); /**
* Указывает JAR-файл с классами инструментирования, которые должны быть определены
* системным загрузчиком классов.
*
* Когда системный загрузчик классов для делегирования (см.
* {@link java.lang.ClassLoader#getSystemClassLoader getSystemClassLoader()})
* неудачно ищет класс, записи в {@link java.util.jar.JarFile JarFile} также будут
* искаться.
*
* <p> Этот метод может быть использован несколько раз для добавления нескольких
* JAR-файлов для поиска в порядке, в котором этот метод был вызван.
*
* <p> Агент должен принять меры, чтобы убедиться, что JAR-файл не содержит никаких * классов или ресурсов, кроме тех, которые должны быть определены системным
* загрузчиком классов для целей инструментирования.
* Нарушение этого предупреждения может привести к непредвиденному поведению,
* которое трудно диагностировать (см.
* {@link #appendToBootstrapClassLoaderSearch appendToBootstrapClassLoaderSearch}).
*
* <p> Системный загрузчик классов поддерживает добавление JAR-файла для поиска, если
* он реализует метод с именем <code>appendToClassPathForInstrumentation</code>, который
* принимает один параметр типа <code>java.lang.String</code>. Метод не требуется
* иметь <code>public</code> доступ. Имя JAR-файла получается путем вызова метода
* {@link java.util.zip.ZipFile#getName getName()} на <code>jarfile</code>, и это
* предоставляется как параметр метода <code>appendToClassPathForInstrumentation</code>.
*
* <p>
* <cite>Спецификация виртуальной машины Java™</cite>
* указывает, что последующая попытка разрешения символической ссылки, которую
* виртуальная машина Java ранее неудачно попыталась разрешить, всегда завершается
* ошибкой, которая была выброшена в результате первой попытки разрешения.
* В результате, если JAR-файл содержит запись, соответствующую классу, для которого
* виртуальная машина Java неудачно попыталась разрешить ссылку, то последующие
* попытки разрешения этой ссылки завершатся ошибкой, такой же, как первая попытка.
*
* <p> Этот метод не изменяет значение <code>java.class.path</code> * {@link java.lang.System#getProperties system property}.
*
* @param jarfile
*
* JAR-файл, который будет искаться системным загрузчиком классов,
* если загрузчик классов неудачно ищет класс.
*
* @throws UnsupportedOperationException
* Если системный загрузчик классов не поддерживает добавление
* JAR-файла для поиска.
*
* @throws NullPointerException
* Если <code>jarfile</code> равно <code>null</code>.
*
* @see #appendToBootstrapClassLoaderSearch
* @see java.lang.ClassLoader#getSystemClassLoader
* @see java.util.jar.JarFile
* @since 1.6
*/
void
appendToSystemClassLoaderSearch(JarFile jarfile); /**
* Возвращает, поддерживает ли текущая конфигурация JVM
* установку префикса для native метода
* {@linkplain #setNativeMethodPrefix(ClassFileTransformer,String)}.
* Возможность установки префикса для native метода является
* опциональной функцией JVM.
* Установка префикса для native метода будет поддерживаться только
* в том случае, если атрибут манифеста <code>Can-Set-Native-Method-Prefix</code>
* установлен в значение <code>true</code> в JAR-файле агента (как описано в
* {@linkplain java.lang.instrument пакетной спецификации}) и JVM поддерживает
* эту функцию.
* В течение одного запуска одной JVM повторные вызовы этого метода всегда
* будут возвращать одинаковый результат.
* @return true, если текущая конфигурация JVM поддерживает установку
* префикса для native метода, иначе false.
* @see #setNativeMethodPrefix
* @since 1.6
*/
boolean
isNativeMethodPrefixSupported(); /**
* Этот метод изменяет обработку ошибок при разрешении
* встроенных методов, позволяя повторную попытку с префиксом,
* добавленным к имени.
* При использовании с
* {@link java.lang.instrument.ClassFileTransformer ClassFileTransformer},
* он позволяет встроенным методам быть инструментированными.
* <p>
* Поскольку встроенные методы не могут быть напрямую инструментированы
* (у них нет байткода), их необходимо обернуть в метод, не являющийся встроенным,
* который может быть инструментирован.
* Например, если бы у нас был:
* <pre>
* native boolean foo(int x);
* </pre>
* <p>
* Мы могли бы преобразовать файл класса (с помощью
* ClassFileTransformer при первоначальном определении класса)
* так, чтобы это стало:
* <pre>
* boolean foo(int x) {
* <i>. . . запись входа в foo . . . </i>
* return wrapped_foo(x);
* }
*
* native boolean wrapped_foo(int x);
* </pre>
* <p>
* Где <code>foo</code> становится обёрткой для фактического встроенного метода с добавленным префиксом "wrapped_".
* Обратите внимание, что "wrapped_" был бы плохим выбором префикса, так как он мог бы стать именем существующего метода,
* поэтому что-то вроде "$$$MyAgentWrapped$$$_" было бы лучше, но это сделало бы эти примеры менее читаемыми.
* <p>
* Обёртка позволяет собирать данные о вызовах встроенных методов, но теперь проблема заключается в связывании
* обёрнутого метода с его встроенной реализацией. * То есть, метод <code>wrapped_foo</code> должен быть связан с встроенной реализацией <code>foo</code>,
* которая может быть:
* <pre>
* Java_somePackage_someClass_foo(JNIEnv* env, jint x)
* </pre>
* <p>
* Эта функция позволяет указывать префикс и обеспечивает правильное разрешение.
* Конкретно, когда стандартное разрешение не удаётся, разрешение повторяется, учитывая префикс.
* Разрешение происходит двумя способами: явное разрешение с помощью функции JNI <code>RegisterNatives</code>
* и обычное автоматическое разрешение. Для
* <code>RegisterNatives</code>, JVM попытается установить следующую связь:
* <pre>{@code
* метод(foo) -> nativeImplementation(foo)
* }</pre>
* <p>
* Когда это не удаётся, разрешение повторяется с учетом префикса.
* Указанный префикс, добавленный к имени метода, что приводит к правильному разрешению:
* <pre>{@code
* метод(wrapped_foo) -> nativeImplementation(foo)
* }</pre>
* <p>
* Для автоматического разрешения JVM попытается:
* <pre>{@code
* метод(wrapped_foo) -> nativeImplementation(wrapped_foo)
* }</pre>
* <p>
* Когда это не удаётся, разрешение будет повторно попытано
* с указанным префиксом удалённым из имени реализации,
* что приводит к правильному разрешению:
* <pre>{@code
* метод(wrapped_foo) -> nativeImplementation(foo)
* }</pre>
* <p>
* Обратите внимание, что префикс используется только в случае,
* если стандартное разрешение не удаётся, поэтому native методы
* могут быть обёрнуты выборочно.
* <p>
* Поскольку каждый <code>ClassFileTransformer</code>
* может выполнять свою собственную трансформацию байт-кода,
* может быть применено более одного уровня обёртки. Таким образом,
* каждому трансформатору требуется свой собственный префикс. Поскольку
* трансформации применяются в определённом порядке, префиксы, если они
* применяются, будут применяться в том же порядке
* (см. {@link #addTransformer(ClassFileTransformer,boolean) addTransformer}).
* Таким образом, если три трансформатора применяют
* обёртки, <code>foo</code> может стать
* <code>$trans3_$trans2_$trans1_foo</code>. Но если, например,
* второй трансформатор не применяет обёртку к
* <code>foo</code>, это будет просто
* <code>$trans3_$trans1_foo</code>. Чтобы иметь возможность
* эффективно определить последовательность префиксов,
* промежуточный префикс применяется только если его нативная
* обёртка существует. Таким образом, в последнем примере, хотя
* <code>$trans1_foo</code> не является нативным методом,
* префикс <code>$trans1_</code> применяется, поскольку
* <code>$trans1_foo</code> существует.
*
* @param transformer
* ClassFileTransformer, который использует этот префикс для обёртки.
* @param prefix
* Префикс, применяемый к обёрнутым нативным методам при повторной попытке
* разрешения неудачного нативного метода. Если префикс
* является либо <code>null</code>, либо пустой строкой, то
* неудачные разрешения native методов не будут повторно пытаться для
* этого трансформатора.
* @throws java. lang. NullPointerException если передан <code>null</code> трансформатор.
* @throws java. lang. UnsupportedOperationException если текущая конфигурация JVM не позволяет задать префикс для native метода
({@link #isNativeMethodPrefixSupported} равен false).
* @throws java. lang. IllegalArgumentException если трансформатор не зарегистрирован
(см. {@link #addTransformer(ClassFileTransformer,boolean) addTransformer}).* @since 1.6
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )