Spec-Zone.ru › OpenJDK 17

Интерфейс Instrumentation

public interface Instrumentation
Этот класс предоставляет службы, необходимые для инструментирования кода языка программирования Java. Инструментирование — это добавление байткодов к методам для сбора данных, которые будут использоваться инструментами. Поскольку изменения являются чисто аддитивными, эти инструменты не изменяют состояние или поведение приложения. Примеры таких безвредных инструментов включают агенты мониторинга, профайлеры, анализаторы покрытия кода и регистраторы событий.

Существует два способа получения экземпляра интерфейса Instrumentation:

  1. При запуске JVM таким образом, что указывает на класс агента. В этом случае экземпляр Instrumentation передаётся методу premain класса агента.

  2. Когда JVM предоставляет механизм запуска агентов некоторое время после запуска JVM. В этом случае экземпляр Instrumentation передаётся методу agentmain кода агента.

Эти механизмы описаны в спецификации пакета.

После того, как агент получит экземпляр Instrumentation , агент может вызывать методы экземпляра в любое время.

Примечание API:
Этот интерфейс не предназначен для реализации вне модуля java.instrument.
С:
1.5

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

Модификатор и тип Метод Описание
void addTransformer(ClassFileTransformer transformer)
Регистрирует предоставленный трансформер.
void addTransformer(ClassFileTransformer transformer, boolean canRetransform)
Регистрирует предоставленный трансформер.
void appendToBootstrapClassLoaderSearch(JarFile jarfile)
Указывает JAR-файл с классами инструментирования, которые должны быть определены загрузчиком базового класса.
void appendToSystemClassLoaderSearch(JarFile jarfile)
Указывает JAR-файл с классами инструментирования, которые должны быть определены системным загрузчиком классов.
Class[] getAllLoadedClasses()
Возвращает массив всех классов, загруженных в данный момент JVM.
Class[] getInitiatedClasses(ClassLoader loader)
Возвращает массив всех классов, которые loader может найти по имени через ClassLoader::loadClass, Class::forName и привязку байткода.
long getObjectSize(Object objectToSize)
Возвращает реализуемую специфическую оценку объёма памяти, занимаемого указанным объектом.
boolean isModifiableClass(Class<?> theClass)
Проверяет, может ли класс быть модифицирован перетрансформацией или переопределением.
boolean isModifiableModule(Module module)
Проверяет, может ли модуль быть изменён с помощью redefineModule.
boolean isNativeMethodPrefixSupported()
Возвращает, поддерживает ли текущая конфигурация JVM установку префикса для методов нативных.
boolean isRedefineClassesSupported()
Возвращает, поддерживает ли текущая конфигурация JVM переопределение классов.
boolean isRetransformClassesSupported()
Возвращает, поддерживает ли текущая конфигурация JVM перетрансформацию классов.
void redefineClasses(ClassDefinition... definitions)
Переопределяет указанный набор классов, используя предоставленные файлы классов.
void redefineModule(Module module, Set<Module> extraReads, Map<String,Set<Module>> extraExports, Map<String,Set<Module>> extraOpens, Set<Class<?>> extraUses, Map<Class<?>,List<Class<?>>> extraProvides)
Переопределяет модуль, чтобы расширить набор модулей, которые он читает, набор пакетов, которые он экспортирует или открывает, или службы, которые он использует или предоставляет.
boolean removeTransformer(ClassFileTransformer transformer)
Отменяет регистрацию предоставленного трансформера.
void retransformClasses(Class<?>... classes)
Перетрансформирует указанный набор классов.
void setNativeMethodPrefix(ClassFileTransformer transformer, String prefix)
Этот метод изменяет обработку ошибок разрешения нативного метода, позволяя повторную попытку с применением префикса к имени.

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

addTransformer

void addTransformer(ClassFileTransformer transformer, boolean canRetransform)
Регистрирует предоставленный трансформатор. Все будущие определения классов будут видны трансформатору, за исключением определений классов, от которых зависит любой зарегистрированный трансформатор. Трансформатор вызывается при загрузке классов, при их переопределении и, если canRetransform имеет значение true, при их перетрансформации. ClassFileTransformer определяет порядок вызовов трансформации. Если трансформатор генерирует исключение во время выполнения, JVM все равно вызовет другие зарегистрированные трансформаторы в порядке. Один и тот же трансформатор может быть добавлен более одного раза, но это настоятельно не рекомендуется — избегайте этого, создавая новый экземпляр класса трансформатора.

Этот метод предназначен для использования в инструментировании, как описано в спецификации класса.

Параметры:
transformer - регистрируемый трансформатор
canRetransform - могут ли трансформации этого трансформатора быть перетрансформированы
Исключения:
NullPointerException - если передан null трансформатор
UnsupportedOperationException - если canRetransform имеет значение true и текущая конфигурация JVM не позволяет перетрансформацию (isRetransformClassesSupported() имеет значение false)
С момента:
1.6

addTransformer

void addTransformer(ClassFileTransformer transformer)
Регистрирует предоставленный трансформатор.

То же, что и addTransformer(transformer, false).

Параметры:
transformer - регистрируемый трансформатор
Исключения:
NullPointerException - если передан null трансформатор
См. также:
  • addTransformer(ClassFileTransformer,boolean)

removeTransformer

boolean removeTransformer(ClassFileTransformer transformer)
Отменяет регистрацию предоставленного трансформатора. Будущие определения классов не будут показаны трансформатору. Удаляет последнюю добавленную соответствующую экземпляр трансформатора. Из-за многопоточной природы загрузки классов, трансформатор может получить вызовы после того, как он был удален. Трансформаторы должны быть написаны защищенно, ожидая такой ситуации.
Параметры:
transformer - отменяемый трансформатор
Возвращает:
true, если трансформатор был найден и удален, false, если трансформатор не найден
Исключения:
NullPointerException - если передан null трансформатор

isRetransformClassesSupported

boolean isRetransformClassesSupported()
Возвращает, поддерживает ли текущая конфигурация JVM перетрансформацию классов. Возможность перетрансформировать уже загруженный класс является необязательной возможностью JVM. Перетрансформация будет поддерживаться только в том случае, если атрибут Can-Retransform-Classes манифеста установлен в true в JAR-файле агента (как описано в спецификации пакета) и JVM поддерживает эту возможность. В рамках одного экземпляра одной JVM многократные вызовы этого метода всегда возвращают один и тот же результат.
Возвращает:
true, если текущая конфигурация JVM поддерживает перетрансформацию классов, false — если нет.
С момента:
1.6
См. также:
  • retransformClasses(java.lang.Class<?>...)

retransformClasses

void retransformClasses(Class<?>... classes) throws UnmodifiableClassException
Перетрансформирует указанный набор классов.

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

  • начиная с начального байтового кода файла класса
  • для каждого трансформатора, который был добавлен с canRetransform false, байты, возвращённые методом transform во время последней загрузки или переопределения класса, повторно используются в качестве выходных данных трансформации; обратите внимание, что это эквивалентно повторному применению предыдущей трансформации без изменений; за исключением того, что transform метод не вызывается.
  • для каждого трансформатора, который был добавлен с canRetransform true, метод transform вызывается в этих трансформаторах
  • трансформированный байтовый код файла класса устанавливается в качестве нового определения класса

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

Начальный байтовый код файла класса представляет собой байты, переданные ClassLoader.defineClass или redefineClasses (до применения каких-либо трансформаций), однако они могут не совпадать с ними точно. Пул констант может не иметь той же компоновки или содержимого. Пул констант может содержать больше или меньше элементов. Элементы пула констант могут быть в другом порядке; однако индексы пула констант в байкодах методов будут соответствовать. Некоторые атрибуты могут отсутствовать. Там, где порядок не имеет значения, например, порядок методов, порядок может не сохраняться.

Этот метод работает с набором, чтобы позволить взаимозависимые изменения более чем одного класса одновременно (перетрансформация класса A может потребовать перетрансформации класса B).

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

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

Экземпляры перетрансформированного класса не затронуты.

Поддерживаемые изменения файла класса описаны в JVM TI RetransformClasses. Байты файла класса не проверяются, не верифицируются и не устанавливаются до тех пор, пока не будут применены все трансформации. Если полученные байты некорректны, этот метод сгенерирует исключение.

Если этот метод генерирует исключение, ни один класс не был перетрансформирован.

Этот метод предназначен для использования в инструментировании, как описано в спецификации класса.

Параметры:
classes - массив классов для перетрансформации; массив нулевой длины разрешен, в этом случае этот метод ничего не делает
Исключения:
UnmodifiableClassException - если указанный класс не может быть изменен (isModifiableClass(java.lang.Class<?>) вернёт false)
UnsupportedOperationException - если текущая конфигурация JVM не позволяет перетрансформацию (isRetransformClassesSupported() имеет значение false) или перетрансформация пыталась произвести недопустимые изменения
ClassFormatError - если данные не содержали допустимый класс
NoClassDefFoundError - если имя в файле класса не равно имени класса
UnsupportedClassVersionError - если номера версий файла класса не поддерживаются
ClassCircularityError - если новые классы содержат цикличность
LinkageError - если произошла ошибка связи
NullPointerException - если предоставленный массив классов или любой из его компонентов null.
С момента:
1.6
См. также:
  • isRetransformClassesSupported()
  • addTransformer(java.lang.instrument.ClassFileTransformer, boolean)
  • ClassFileTransformer

isRedefineClassesSupported

boolean isRedefineClassesSupported()
Возвращает, поддерживает ли текущая конфигурация JVM переопределение классов. Возможность переопределения уже загруженного класса является необязательной возможностью JVM. Переопределение будет поддерживаться только в том случае, если атрибут Can-Redefine-Classes манифеста установлен в true в JAR-файле агента (как описано в спецификации пакета) и JVM поддерживает эту возможность. В рамках одного экземпляра одной JVM многократные вызовы этого метода всегда возвращают один и тот же результат.
Возвращает:
true, если текущая конфигурация JVM поддерживает переопределение классов, false — если нет.
См. также:
  • redefineClasses(java.lang.instrument.ClassDefinition...)

переопределитьКлассы

void redefineClasses(ClassDefinition... definitions) throws ClassNotFoundException, UnmodifiableClassException
Переопределяет предоставленный набор классов, используя предоставленные файлы классов.

Этот метод используется для замены определения класса без ссылки на байты существующего файла класса, как это можно сделать при повторной компиляции из исходного кода для отладки «исправь и продолжай». В случаях, когда существующие байты файла класса должны быть преобразованы (например, в инструментировании байткода), следует использовать retransformClasses.

Этот метод работает со множеством элементов, чтобы разрешить взаимозависимые изменения более чем в одном классе одновременно (переопределение класса A может потребовать переопределения класса B).

Если переопределённый метод имеет активные стековые кадры, эти активные кадры продолжают выполнять байткод исходного метода. Переопределённый метод будет использоваться при новых вызовах.

Этот метод не вызывает инициализацию, кроме той, которая произошла бы в соответствии с обычной семантикой JVM. Другими словами, переопределение класса не приводит к выполнению его инициализаторов. Значения статических переменных останутся такими же, как и до вызова.

Экземпляры переопределённого класса не затронуты.

Поддерживаемые изменения в файлах классов описаны в JVM TI RedefineClasses. Байты файла класса не проверяются, не верифицируются и не устанавливаются до тех пор, пока не будут применены преобразования, если полученные байты неверны, этот метод выбросит исключение.

Если этот метод выбросит исключение, ни один класс не был переопределён.

Этот метод предназначен для использования в инструментировании, как описано в спецификации класса.

Параметры:
definitions - массив классов для переопределения с соответствующими определениями; разрешён массив нулевой длины, в этом случае этот метод ничего не делает
Исключения:
UnmodifiableClassException - если указанный класс не может быть изменён (isModifiableClass(java.lang.Class<?>) вернёт false)
UnsupportedOperationException - если текущая конфигурация JVM не позволяет переопределять (isRedefineClassesSupported() ложь) или переопределение пыталось произвести неподдерживаемые изменения
ClassFormatError - если данные не содержали допустимого класса
NoClassDefFoundError - если имя в файле класса не равно имени класса
UnsupportedClassVersionError - если номера версий файлов класса не поддерживаются
ClassCircularityError - если новые классы содержат цикличность
LinkageError - если произошла ошибка связи
NullPointerException - если предоставленный массив определений или любой из его компонентов null
ClassNotFoundException - Не может быть выброшен (присутствует только для совместимости)
См. также:
  • isRedefineClassesSupported()
  • addTransformer(java.lang.instrument.ClassFileTransformer, boolean)
  • ClassFileTransformer

isModifiableClass

boolean isModifiableClass(Class<?> theClass)
Проверяет, можно ли изменить класс с помощью повторной трансформации или переопределения. Если класс можно изменить, этот метод возвращает true. Если класс нельзя изменить, этот метод возвращает false.

Для повторной трансформации класса также должно быть истинно isRetransformClassesSupported(). Но значение isRetransformClassesSupported() не влияет на значение, возвращаемое этой функцией. Для переопределения класса также должно быть истинно isRedefineClassesSupported(). Но значение isRedefineClassesSupported() не влияет на значение, возвращаемое этой функцией.

Примитивные классы (например, java.lang.Integer.TYPE) и массивы классов никогда не могут быть изменены.

Параметры:
theClass - класс, который нужно проверить на возможность изменения
Возвращает:
можно ли изменить указанный класс
Исключения:
NullPointerException - если указанный класс null.
С тех пор:
1.6
См. также:
  • retransformClasses(java.lang.Class<?>...)
  • isRetransformClassesSupported()
  • redefineClasses(java.lang.instrument.ClassDefinition...)
  • isRedefineClassesSupported()

getAllLoadedClasses

Class[] getAllLoadedClasses()
Возвращает массив всех классов, которые в настоящее время загружены JVM. Возвращаемый массив включает все классы и интерфейсы, включая скрытые классы или интерфейсы, и классы массивов всех типов.
Возвращает:
массив, содержащий все классы, загруженные JVM; массив нулевой длины, если таких нет

getInitiatedClasses

Class[] getInitiatedClasses(ClassLoader loader)
Возвращает массив всех классов, которые loader может найти по имени с помощью ClassLoader::loadClass, Class::forName и связывания байткода. То есть все классы, для которых loader был записан как инициализирующий загрузчик. Если указанный loader является null, возвращаются классы, которые может найти загрузчик bootstrap по имени.

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

Параметры:
loader - загрузчик, чьи начальные классы будут возвращены
Возвращает:
массив, содержащий все классы, которые loader может найти по имени; массив нулевой длины, если таких нет

getObjectSize

long getObjectSize(Object objectToSize)
Возвращает специфичное для реализации приблизительное значение занимаемого объектом хранилища. Результат может включать часть или весь объект издержек, поэтому он полезен для сравнения внутри одной реализации, но не между реализациями. Оценка может изменяться в течение одного вызова JVM.
Параметры:
objectToSize - объект для определения размера
Возвращает:
специфичное для реализации приблизительное значение занимаемого объектом хранилища
Исключения:
NullPointerException - если предоставленный объект null.

appendToBootstrapClassLoaderSearch

void appendToBootstrapClassLoaderSearch(JarFile jarfile)
Указывает JAR-файл с классами инструментирования, которые будут определены загрузчиком bootstrap.

Когда встроенный загрузчик классов виртуальной машины, известный как "загрузчик bootstrap", безуспешно ищет класс, записи в JAR file будут также проверяться.

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

Агент должен позаботиться о том, чтобы JAR-файл не содержал никаких классов или ресурсов, кроме тех, которые должны быть определены загрузчиком bootstrap для целей инструментирования. Несоблюдение этого предупреждения может привести к непредсказуемому поведению, которое сложно диагностировать. Например, предположим, что существует загрузчик L, и родитель L для делегирования — загрузчик bootstrap. Кроме того, метод в классе C, классе, определённом L, ссылается на класс-аксессор C$1, который не является общедоступным. Если JAR-файл содержит класс C$1, то делегирование загрузчику bootstrap приведёт к определению C$1 загрузчиком bootstrap. В этом примере будет выброшено IllegalAccessError , которое может привести к сбою приложения. Один из подходов к предотвращению подобных проблем — использовать уникальное имя пакета для классов инструментирования.

Спецификация виртуальной машины Java определяет, что последующая попытка разрешить символическую ссылку, которую виртуальная машина Java ранее безуспешно пыталась разрешить, всегда завершается неудачей с той же ошибкой, которая была выброшена в результате первоначальной попытки разрешения. Следовательно, если JAR-файл содержит запись, соответствующую классу, для которого виртуальная машина Java безуспешно пыталась разрешить ссылку, последующие попытки разрешить эту ссылку завершатся той же ошибкой, что и первоначальная попытка.

Параметры:
jarfile - JAR-файл, который будет проверяться при безуспешном поиске класса загрузчиком bootstrap.
Исключения:
NullPointerException - если jarfile является null.
С тех пор:
1.6
См. также:
  • appendToSystemClassLoaderSearch(java.util.jar.JarFile)
  • ClassLoader
  • JarFile

appendToSystemClassLoaderSearch

void appendToSystemClassLoaderSearch(JarFile jarfile)
Указывает JAR-файл с классами инструментирования, которые должны быть определены загрузчиком системных классов. Когда загрузчик системных классов для делегирования (см. getSystemClassLoader()) безуспешно ищет класс, записи в JarFile также будут просматриваться.

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

Агент должен позаботиться о том, чтобы JAR-файл не содержал никаких классов или ресурсов, кроме тех, которые должны быть определены загрузчиком системных классов для целей инструментирования. Несоблюдение этого предупреждения может привести к непредсказуемому поведению, которое трудно диагностировать (см. appendToBootstrapClassLoaderSearch).

Загрузчик системных классов поддерживает добавление JAR-файла для поиска, если он реализует метод с именем appendToClassPathForInstrumentation, который принимает один параметр типа java.lang.String. Метод не обязан иметь public доступ. Имя JAR-файла получается путем вызова метода getName() для jarfile и предоставляется в качестве параметра методу appendToClassPathForInstrumentation.

Спецификация виртуальной машины Java указывает, что последующая попытка разрешить символическую ссылку, которую виртуальная машина Java ранее безуспешно пыталась разрешить, всегда завершается неудачей с той же ошибкой, которая была сгенерирована в результате первоначальной попытки разрешения. Следовательно, если JAR-файл содержит запись, соответствующую классу, для которого виртуальная машина Java безуспешно пыталась разрешить ссылку, то последующие попытки разрешить эту ссылку завершатся той же ошибкой, что и первоначальная попытка.

Этот метод не изменяет значение java.class.path system property.

Parameters:
jarfile - JAR-файл, который будет просматриваться, когда загрузчик системных классов безуспешно ищет класс.
Throws:
UnsupportedOperationException - Если загрузчик системных классов не поддерживает добавление JAR-файла для поиска.
NullPointerException - Если jarfile является null.
Since:
1.6
See Also:
  • appendToBootstrapClassLoaderSearch(java.util.jar.JarFile)
  • ClassLoader.getSystemClassLoader()
  • JarFile

isNativeMethodPrefixSupported

boolean isNativeMethodPrefixSupported()
Возвращает, поддерживает ли текущая конфигурация JVM установку префикса для методов нативных. Возможность установки префикса для методов нативных является необязательной возможностью JVM. Установка префикса для методов нативных будет поддерживаться только в том случае, если атрибут Can-Set-Native-Method-Prefix манифеста установлен в true в JAR-файле агента (как описано в спецификации пакета) и JVM поддерживает эту возможность. В течение одной инстанциации одной JVM многократные вызовы этого метода всегда будут возвращать один и тот же ответ.
Returns:
true, если текущая конфигурация JVM поддерживает установку префикса для методов нативных, false — если нет.
Since:
1.6
See Also:
  • setNativeMethodPrefix(java.lang.instrument.ClassFileTransformer, java.lang.String)

setNativeMethodPrefix

void setNativeMethodPrefix(ClassFileTransformer transformer, String prefix)
Этот метод изменяет обработку ошибок при разрешении методов нативных, позволяя повторную попытку с применением префикса к имени. При использовании с ClassFileTransformer это позволяет инструментировать методы нативных.

Так как методы нативные не могут быть напрямую инструментированы (у них нет байткодов), они должны быть обернуты с помощью метода не нативного, который может быть инструментирован. Например, если у нас есть:

   native boolean foo(int x);

Мы можем преобразовать файл класса (с ClassFileTransformer во время первоначального определения класса) таким образом, чтобы это стало:

   boolean foo(int x) {
     ... record entry to foo ...
     return wrapped_foo(x);
   }

   native boolean wrapped_foo(int x);

Где foo становится оболочкой для фактического нативного метода с добавленным префиксом "wrapped_". Обратите внимание, что "wrapped_" — плохой выбор префикса, так как он может случайно образовывать имя существующего метода, поэтому что-то вроде "$$$MyAgentWrapped$$$_" было бы лучше, но сделало бы примеры менее читаемыми.

Оболочка позволит собирать данные о вызове нативного метода, но теперь проблема заключается в связывании обернутого метода с нативным реализацией. То есть метод wrapped_foo должен быть разрешен до нативной реализации foo, которая может быть:

   Java_somePackage_someClass_foo(JNIEnv* env, jint x)

Эта функция позволяет указать префикс и обеспечить правильное разрешение. В частности, когда стандартное разрешение терпит неудачу, разрешение повторяется, учитывая префикс. Существует два способа разрешения, явное разрешение с функцией JNI RegisterNatives и обычное автоматическое разрешение. Для RegisterNatives, JVM попытается установить это соответствие:


   method(foo) -> nativeImplementation(foo)
 

Когда это терпит неудачу, разрешение будет повторено с указанным префиксом, добавленным к имени метода, что приведет к правильному разрешению:


   method(wrapped_foo) -> nativeImplementation(foo)
 

Для автоматического разрешения JVM попытается:


   method(wrapped_foo) -> nativeImplementation(wrapped_foo)
 

Когда это терпит неудачу, разрешение будет повторено с указанным префиксом, удаленным из имени реализации, что приведет к правильному разрешению:


   method(wrapped_foo) -> nativeImplementation(foo)
 

Обратите внимание, что так как префикс используется только при неудаче стандартного разрешения, методы нативные могут быть обернуты выборочно.

Поскольку каждый ClassFileTransformer может выполнять свои преобразования байткодов, может быть применено несколько слоев оболочек. Таким образом, каждый преобразователь требует собственного префикса. Так как преобразования применяются в порядке, префиксы, если они применяются, применяются в том же порядке (см. addTransformer). Таким образом, если три преобразователя применили оболочки, foo может стать $trans3_$trans2_$trans1_foo. Но если, скажем, второй преобразователь не применил оболочку к foo, он будет просто $trans3_$trans1_foo. Чтобы эффективно определить последовательность префиксов, промежуточный префикс применяется только в том случае, если существует его оболочка не нативного метода. Таким образом, в последнем примере, даже если $trans1_foo не является нативным методом, префикс $trans1_ применяется, так как $trans1_foo существует.

Parameters:
transformer - ClassFileTransformer, который обертывает с этим префиксом.
prefix - Префикс, применяемый к обернутым нативным методам при повторной попытке разрешения нативного метода. Если префикс — null или пустая строка, то повторные попытки разрешения нативных методов для этого преобразователя не предпринимаются.
Throws:
NullPointerException - если передан null преобразователь.
UnsupportedOperationException - если текущая конфигурация JVM не позволяет устанавливать префикс для методов нативных (isNativeMethodPrefixSupported() равно false).
IllegalArgumentException - если преобразователь не зарегистрирован (см. addTransformer).
Since:
1.6

Переопределить модуль

void redefineModule(Module module, Set<Module> extraReads, Map<String,Set<Module>> extraExports, Map<String,Set<Module>> extraOpens, Set<Class<?>> extraUses, Map<Class<?>,List<Class<?>>> extraProvides)
Переопределяет модуль для расширения набора модулей, которые он читает, набора пакетов, которые он экспортирует или открывает, или сервисов, которые он использует или предоставляет. Этот метод облегчает внедрение кода в именованные модули, когда это внедрение требует изменений в наборе читаемых модулей, пакетов, которые экспортируются или открываются, или сервисов, которые используются или предоставляются.

Этот метод не может уменьшить набор модулей, которые читает модуль, ни уменьшить набор пакетов, которые он экспортирует или открывает, ни уменьшить набор сервисов, которые он использует или предоставляет. Этот метод является бесполезным, когда вызывается для переопределения безымянного модуля.

При расширении сервисов, которые использует или предоставляет модуль, агент несёт ответственность за обеспечение того, что тип сервиса будет доступен в каждом месте внедрения, где тип сервиса используется. Этот метод не проверяет, является ли тип сервиса членом модуля или пакетом, экспортированным в модуль другим модулем, который он читает.

Параметр extraExports — это карта дополнительных пакетов для экспорта. Параметр extraOpens — это карта дополнительных пакетов для открытия. В обоих случаях, ключ карты — это полное имя пакета, определённое в разделе 6.5.3 спецификации языка Java, например, "java.lang". Значение карты — это непустой набор модулей, которым пакет должен быть экспортирован или открыт.

Параметр extraProvides — это дополнительные поставщики сервисов для предоставления модулем. Ключ карты — это тип сервиса. Значение карты — это непустой список типов реализации, каждый из которых является членом модуля и реализацией сервиса.

Этот метод безопасен для одновременного использования и позволяет множеству агентов внедрять и обновлять один и тот же модуль примерно в одно и то же время.

Параметры:
module - модуль для переопределения
extraReads - возможно пустой набор дополнительных модулей для чтения
extraExports - возможно пустая карта дополнительных пакетов для экспорта
extraOpens - возможно пустая карта дополнительных пакетов для открытия
extraUses - возможно пустой набор дополнительных сервисов для использования
extraProvides - возможно пустая карта дополнительных сервисов для предоставления
Исключения:
IllegalArgumentException - Если extraExports или extraOpens содержат ключ, который не является пакетом в модуле; если extraExports или extraOpens отображает ключ на пустой набор; если значение в карте extraProvides содержит тип поставщика сервиса, который не является членом модуля или реализацией сервиса; или extraProvides отображает ключ на пустой список
UnmodifiableModuleException - если модуль не может быть изменён
NullPointerException - если любой из аргументов null или любой из наборов или карт содержит ключ или значение null
С:
9
См. также:
  • isModifiableModule(Module)

isModifiableModule

boolean isModifiableModule(Module module)
Проверяет, можно ли изменить модуль с помощью redefineModule. Если модуль изменяем, этот метод возвращает true. Если модуль не изменяем, этот метод возвращает false. Этот метод всегда возвращает true когда модуль безымянный (поскольку переопределение безымянного модуля является бесполезным действием).
Параметры:
module - модуль для проверки возможности изменения
Возвращает:
true если модуль изменяем, в противном случае false
Исключения:
NullPointerException - если модуль null
С:
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/Instrumentation.html

Spec-Zone.ru

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