Spec-Zone .ru
спецификации, руководства, описания, API
|
public interface Instrumentation
Есть два способа получить экземпляр Instrumentation
интерфейс:
Когда JVM запускается в пути, который указывает на класс агента. В этом случае Instrumentation
экземпляр передают к premain
метод класса агента.
Когда JVM обеспечивает механизм, чтобы запустить агенты когда-то после того, как JVM запускается. В этом случае Instrumentation
экземпляр передают к agentmain
метод кода агента.
Эти механизмы описываются в спецификации пакета.
Как только агент получает Instrumentation
экземпляр, агент может вызвать методы на экземпляре в любое время.
Модификатор и Тип | Метод и Описание |
---|---|
void |
addTransformer(ClassFileTransformer transformer)
Регистрирует предоставленный преобразователь.
|
void |
addTransformer(ClassFileTransformer transformer, boolean canRetransform)
Регистрирует предоставленный преобразователь.
|
void |
appendToBootstrapClassLoaderSearch(JarFile jarfile)
Определяет файл JAR с классами инструментария, которые будут определены загрузчиком класса начальной загрузки.
|
void |
appendToSystemClassLoaderSearch(JarFile jarfile)
Определяет файл JAR с классами инструментария, которые будут определены системным загрузчиком класса.
|
Класс[] |
getAllLoadedClasses()
Возвращает массив всех классов, в настоящий момент загруженных JVM.
|
Класс[] |
getInitiatedClasses(ClassLoader loader)
Возвращает массив всех классов для который
loader загрузчик инициирования. |
long |
getObjectSize(Object objectToSize)
Возвращает специфичное для реализации приближение количества хранения, использованного указанным объектом.
|
boolean |
isModifiableClass(Class<?> theClass)
Определяет, является ли класс поддающимся изменению перепреобразованием или переопределением.
|
boolean |
isNativeMethodPrefixSupported()
Возвраты, поддерживает ли текущая конфигурация JVM установку собственного префикса метода.
|
boolean |
isRedefineClassesSupported()
Возвраты, поддерживает ли текущая конфигурация JVM переопределение классов.
|
boolean |
isRetransformClassesSupported()
Возвраты, поддерживает ли текущая конфигурация JVM перепреобразование классов.
|
void |
redefineClasses(ClassDefinition... definitions)
Пересмотрите предоставленный набор классов, используя предоставленные файлы класса.
|
boolean |
removeTransformer(ClassFileTransformer transformer)
Нерегистрирует предоставленный преобразователь.
|
void |
retransformClasses(Class<?>... classes)
Повторно преобразуйте предоставленный набор классов.
|
void |
setNativeMethodPrefix(ClassFileTransformer transformer, String prefix)
Этот метод изменяет обработку отказа собственного разрешения метода, позволяя повторную попытку с префиксом, которому применяются к имя.
|
void addTransformer(ClassFileTransformer transformer, boolean canRetransform)
canRetransform
истина, когда они повторно преобразовываются. См. ClassFileTransformer.transform
для порядка вызовов преобразования. Если преобразователь выдаст исключение во время выполнения, то JVM все еще вызовет другие зарегистрированные преобразователи в порядке. Тот же самый преобразователь может быть добавлен не раз, но ему строго обескураживают - избегают этого, создавая новый экземпляр класса преобразователя. Этот метод предназначается для использования в инструментарии, как описано в спецификации класса.
transformer
- преобразователь, чтобы зарегистрироватьсяcanRetransform
- могут преобразования этого преобразователя быть повторно преобразованнымиNullPointerException
- если передано a null
преобразовательUnsupportedOperationException
- если canRetransform
истина, и текущая конфигурация JVM не позволяет перепреобразование (isRetransformClassesSupported()
ложь),void addTransformer(ClassFileTransformer transformer)
То же самое как addTransformer(transformer, false)
.
transformer
- преобразователь, чтобы зарегистрироватьсяNullPointerException
- если передано a null
преобразовательaddTransformer(ClassFileTransformer,boolean)
boolean removeTransformer(ClassFileTransformer transformer)
transformer
- преобразователь, чтобы незарегистрироватьсяNullPointerException
- если передано a null
преобразовательboolean isRetransformClassesSupported()
Can-Retransform-Classes
явный атрибут устанавливается в true
в файле JAR агента (как описано в спецификации пакета) и JVM поддерживает эту возможность. Во время единственного инстанцирования единственной JVM множественные вызовы этого метода будут всегда давать тот же самый ответ.retransformClasses(java.lang.Class<?>...)
void retransformClasses(Class<?>... classes) throws UnmodifiableClassException
Эта функция облегчает инструментарий уже загруженных классов. Когда классы первоначально загружаются или когда они пересматриваются, начальные байты файла класса могут быть преобразованы с ClassFileTransformer
. Эта функция запускает повторно процесс преобразования (произошло ли преобразование ранее). Это перепреобразование следует за этими шагами:
canRetransform
ложь, байты, возвращенные transform
во время последнего класса загружают или пересматривают, снова используются как вывод преобразования; отметьте, что это эквивалентно повторному применению предыдущего преобразования, неизменно; за исключением того, что transform
не вызывается canRetransform
истина, transform
метод вызывают в этих преобразователях Порядок преобразования описывается в transform
метод. Этот тот же самый порядок используется в автоматическом переприложении перепреобразования неспособные преобразования.
Начальные байты файла класса представляют байты, которым передают ClassLoader.defineClass
или redefineClasses
(прежде, чем любые преобразования были применены), однако они не могли бы точно соответствовать им. У постоянного пула не могло бы быть того же самого расположения или содержания. Постоянный пул может иметь больше или меньше записей. Постоянные записи пула могут быть в различном порядке; однако, постоянные индексы пула в байт-кодах методов будут соответствовать. Некоторые атрибуты, возможно, не присутствуют. Где порядок не значим, например порядок методов, порядок не мог бы быть сохранен.
Этот метод работает на наборе, чтобы позволить взаимозависимые изменения больше чем одному классу одновременно (перепреобразование класса A может потребовать перепреобразования класса B).
Если у повторно преобразованного метода есть активные стековые фреймы, те активные фреймы продолжают выполнять байт-коды исходного метода. Повторно преобразованный метод будет использоваться на новом, вызывает.
Этот метод не вызывает инициализации за исключением того, что, который произошел бы под общепринятой семантикой JVM. Другими словами пересмотр класса не заставляет свои инициализаторы быть выполненными. Значения статических переменных останутся, как они были до вызова.
На экземпляры повторно преобразованного класса не влияют.
Перепреобразование может изменить тела метода, постоянный пул и атрибуты. Перепреобразование не должно добавить, удалить или переименовать поля или методы, изменить подписи методов, или наследование изменения. Эти ограничения возможно быть снятым в будущих версиях. Байты файла класса не проверяются, проверяются и устанавливаются, пока преобразования не были применены, если результирующие байты будут по ошибке этим методом, то выдаст исключение.
Если этот метод выдает исключение, никакие классы не были повторно преобразованы.
Этот метод предназначается для использования в инструментарии, как описано в спецификации класса.
classes
- массив классов, чтобы повторно преобразовать; массиву нулевому длиной разрешают, в этом случае, этот метод ничего не делаетUnmodifiableClassException
- если указанный класс не может быть изменен (isModifiableClass(java.lang.Class<?>)
возвратился бы false
)UnsupportedOperationException
- если текущая конфигурация JVM не позволяет перепреобразование (isRetransformClassesSupported()
ложь), или перепреобразование, предпринятое, чтобы произвести неподдерживаемые измененияClassFormatError
- если данные не содержали допустимый классNoClassDefFoundError
- если имя в файле класса не равно имени классаUnsupportedClassVersionError
- если номера версий файла класса не поддерживаютсяClassCircularityError
- если новые классы содержат зацикливаниеLinkageError
- если ошибка редактирования происходитNullPointerException
- если предоставленный массив классов или какой-либо из его компонентов null
.isRetransformClassesSupported()
, addTransformer(java.lang.instrument.ClassFileTransformer, boolean)
, ClassFileTransformer
boolean isRedefineClassesSupported()
Can-Redefine-Classes
явный атрибут устанавливается в true
в файле JAR агента (как описано в спецификации пакета) и JVM поддерживает эту возможность. Во время единственного инстанцирования единственной JVM множественные вызовы этого метода будут всегда давать тот же самый ответ.redefineClasses(java.lang.instrument.ClassDefinition...)
void redefineClasses(ClassDefinition... definitions) throws ClassNotFoundException, UnmodifiableClassException
Этот метод используется, чтобы заменить определение класса независимо от существующих байтов файла класса, как можно было бы сделать, перекомпилировав из источника для отладки фиксировать-и-продолжать. Где существующие байты файла класса должны быть преобразованы (например в инструментарии байт-кода) retransformClasses
должен использоваться.
Этот метод работает на наборе, чтобы позволить взаимозависимые изменения больше чем одному классу одновременно (переопределение класса A может потребовать переопределения класса B).
Если у пересмотренного метода есть активные стековые фреймы, те активные фреймы продолжают выполнять байт-коды исходного метода. Пересмотренный метод будет использоваться на новом, вызывает.
Этот метод не вызывает инициализации за исключением того, что, который произошел бы под общепринятой семантикой JVM. Другими словами пересмотр класса не заставляет свои инициализаторы быть выполненными. Значения статических переменных останутся, как они были до вызова.
На экземпляры пересмотренного класса не влияют.
Переопределение может изменить тела метода, постоянный пул и атрибуты. Переопределение не должно добавить, удалить или переименовать поля или методы, изменить подписи методов, или наследование изменения. Эти ограничения возможно быть снятым в будущих версиях. Байты файла класса не проверяются, проверяются и устанавливаются, пока преобразования не были применены, если результирующие байты будут по ошибке этим методом, то выдаст исключение.
Если этот метод выдает исключение, никакие классы не были пересмотрены.
Этот метод предназначается для использования в инструментарии, как описано в спецификации класса.
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
boolean isModifiableClass(Class<?> theClass)
true
. Если класс не является поддающимся изменению тогда этот метод возвраты false
. Для класса, который будет повторно преобразован, isRetransformClassesSupported()
должна также быть истина. Но значение isRetransformClassesSupported()
не влияет на значение, возвращенное этой функцией. Для класса, который будет пересмотрен, isRedefineClassesSupported()
должна также быть истина. Но значение isRedefineClassesSupported()
не влияет на значение, возвращенное этой функцией.
Примитивные классы (например, java.lang.Integer.TYPE
) и классы массива никогда не являются поддающимися изменению.
NullPointerException
- если указанный класс null
.retransformClasses(java.lang.Class<?>...)
, isRetransformClassesSupported()
, redefineClasses(java.lang.instrument.ClassDefinition...)
, isRedefineClassesSupported()
Class[] getAllLoadedClasses()
Class[] getInitiatedClasses(ClassLoader loader)
loader
загрузчик инициирования. Если предоставленный загрузчик null
, возвращаются классы, инициируемые загрузчиком класса начальной загрузки.loader
- загрузчик, инициируемый список учащихся которого будет возвращенlong getObjectSize(Object objectToSize)
objectToSize
- объект измеритьNullPointerException
- если предоставленный Объект null
.void appendToBootstrapClassLoaderSearch(JarFile jarfile)
Когда встроенный загрузчик класса виртуальной машины, известный как "загрузчик класса начальной загрузки", неудачно ищет класс, записи в JAR file
будет искаться также.
Этот метод может использоваться многократно, чтобы добавить многократные файлы JAR, которые будут искаться в порядке, что этот метод был вызван.
Агент должен заботиться, чтобы гарантировать, что JAR не содержит классов или ресурсов кроме тех, чтобы быть определенным загрузчиком класса начальной загрузки с целью инструментария. Отказ наблюдать это предупреждение мог привести к неожиданному поведению, которое трудно диагностировать. Например, предположите, что есть загрузчик L, и родитель Л для делегации является загрузчиком класса начальной загрузки. Кроме того метод в классе C, класс, определенный L, ссылается на непубличный класс средства доступа 1 C$. Если файл JAR будет содержать класс 1 C$ тогда, то делегация загрузчика класса начальной загрузки заставит 1 C$ быть определенным загрузчиком класса начальной загрузки. В этом примере IllegalAccessError
будет брошен, который может заставить приложение перестать работать. Один подход к уходу от этих типов проблем, должен использовать уникальное имя пакета для классов инструментария.
Спецификация Виртуальной машины Java™ определяет, что последующая попытка разрешить символьную ссылку, что виртуальная машина Java ранее неудачно попыталась разрешить всегда сбои с той же самой ошибкой, которая была брошена в результате начальной попытки разрешения. Следовательно, если файл JAR содержит запись, которая соответствует классу, для которого виртуальная машина Java неудачно попыталась разрешить ссылку, тогда последующие попытки разрешить, что ссылка перестанет работать с той же самой ошибкой как начальная попытка.
jarfile
- Файл JAR, который будет искаться, когда загрузчик класса начальной загрузки неудачно ищет класс.NullPointerException
- Если jarfile
null
.appendToSystemClassLoaderSearch(java.util.jar.JarFile)
, ClassLoader
, JarFile
void appendToSystemClassLoaderSearch(JarFile jarfile)
getSystemClassLoader()
) неудачно поиски класса, записей в JarFile
будет искаться также. Этот метод может использоваться многократно, чтобы добавить многократные файлы JAR, которые будут искаться в порядке, что этот метод был вызван.
Агент должен заботиться, чтобы гарантировать, что JAR не содержит классов или ресурсов кроме тех, чтобы быть определенным системным загрузчиком класса с целью инструментария. Отказ наблюдать это предупреждение мог привести к неожиданному поведению, которое трудно диагностировать (см. appendToBootstrapClassLoaderSearch
).
Системный загрузчик класса поддерживает добавление файла JAR, который будет искаться, если это реализует названный метод appendToClassPathForInstrumentation
который берет единственный параметр типа java.lang.String
. Метод не обязан иметь public
доступ. Имя файла JAR получается, вызывая getName()
метод на jarfile
и это обеспечивается как параметр для appendToClassPathForInstrumentation
метод.
Спецификация Виртуальной машины Java™ определяет, что последующая попытка разрешить символьную ссылку, что виртуальная машина Java ранее неудачно попыталась разрешить всегда сбои с той же самой ошибкой, которая была брошена в результате начальной попытки разрешения. Следовательно, если файл JAR содержит запись, которая соответствует классу, для которого виртуальная машина Java неудачно попыталась разрешить ссылку, тогда последующие попытки разрешить, что ссылка перестанет работать с той же самой ошибкой как начальная попытка.
Этот метод не изменяет значение java.class.path
system property
.
jarfile
- Файл JAR, который будет искаться, когда системный загрузчик класса неудачно ищет класс.UnsupportedOperationException
- Если системный загрузчик класса не поддерживает добавление файл JAR, который будет искаться.NullPointerException
- Если jarfile
null
.appendToBootstrapClassLoaderSearch(java.util.jar.JarFile)
, ClassLoader.getSystemClassLoader()
, JarFile
boolean isNativeMethodPrefixSupported()
Can-Set-Native-Method-Prefix
явный атрибут устанавливается в true
в файле JAR агента (как описано в спецификации пакета) и JVM поддерживает эту возможность. Во время единственного инстанцирования единственной JVM множественные вызовы этого метода будут всегда давать тот же самый ответ.setNativeMethodPrefix(java.lang.instrument.ClassFileTransformer, java.lang.String)
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
становится оберткой для фактического собственного метода с добавленным префиксом, "обернутым _ ". Отметьте, что "обернутый _" был бы плохой выбор префикса, так как он мог бы очевидно сформировать имя существующего метода таким образом, что-то как" $ $ $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
существует.transformer
- ClassFileTransformer, который обертывает использование этого префикса.prefix
- Префикс, чтобы примениться к обернутым собственным методам, повторяя отказавшее собственное разрешение метода. Если префикс также null
или пустая строка, затем отказавшие собственные разрешения метода не повторяются для этого преобразователя.NullPointerException
- если передано a null
преобразователь.UnsupportedOperationException
- если текущая конфигурация JVM не позволяет устанавливать собственный префикс метода (isNativeMethodPrefixSupported()
ложь).IllegalArgumentException
- если преобразователь не регистрируется (см. addTransformer
).
Для дальнейшей ссылки API и документации разработчика, см.
Авторское право © 1993, 2011, Oracle и/или его филиалы. Все права защищены.