Spec-Zone.ru › OpenJDK 24

Пакет java.lang.instrument

package java.lang.instrument
Предоставляет сервисы, которые позволяют агентам языка программирования Java инструментировать программы, выполняющиеся в виртуальной машине Java (JVM). Механизм инструментирования — модификация байткода методов.

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

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

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

Запуск агента

Запуск агента, упакованного с приложением в исполняемом JAR-файле

Спецификация JAR-файлов определяет атрибуты манифеста для автономных приложений, упакованных как исполняемые JAR-файлы. Если реализация поддерживает механизм запуска приложения как исполняемого JAR-файла, то главный манифест JAR-файла может включать атрибут Launcher-Agent-Class для указания двоичного имени класса Java-агента, упакованного с приложением. Если атрибут присутствует, JVM запускает агента, загружая класс агента и вызывая его метод agentmain. Метод вызывается до вызова метода приложения main. Метод agentmain имеет одну из двух возможных сигнатур. JVM сначала пытается вызвать следующий метод в классе агента:

public static void agentmain(String agentArgs, Instrumentation inst)

Если класс агента не определяет этот метод, JVM попытается вызвать:

public static void agentmain(String agentArgs)

Значение параметра agentArgs всегда пустая строка. В первом методе параметр inst — объект Instrumentation, который агент может использовать для инструментирования кода.

Метод agentmain должен выполнить все необходимые инициализации для запуска агента и вернуть значение. Если агент нельзя запустить, например, класс агента нельзя загрузить, класс агента не определяет соответствующий метод agentmain, или метод agentmain вызывает необработанное исключение или ошибку, JVM завершит работу до вызова метода приложения main.

Запуск агента из командной строки

Там, где реализация предоставляет способ запуска агентов из командной строки, JAR-файл агента указывается с помощью следующей опции командной строки:

-javaagent:<jarpath>[=<options>]
где <jarpath> — путь к JAR-файлу агента, а <options> — параметры агента.

Главный манифест JAR-файла агента должен содержать атрибут Premain-Class. Значение этого атрибута — двоичное имя класса агента в JAR-файле. JVM запускает агента, загружая класс агента и вызывая его метод premain. Метод вызывается до вызова метода приложения main. Метод premain имеет одну из двух возможных сигнатур. JVM сначала пытается вызвать следующий метод в классе агента:

public static void premain(String agentArgs, Instrumentation inst)

Если класс агента не определяет этот метод, JVM попытается вызвать:

public static void premain(String agentArgs)

Параметры агента передаются агенту через параметр agentArgs. Параметры агента передаются как одна строка; агент сам должен выполнить любое дополнительное разбиение. В первом методе параметр inst — объект Instrumentation, который агент может использовать для инструментирования кода.

Если агент нельзя запустить (например, класс агента нельзя загрузить, класс агента не определяет соответствующий метод premain, или метод premain вызывает необработанное исключение или ошибку), JVM завершит работу до вызова метода приложения main.

Реализация не обязана предоставлять способ запуска агентов из командной строки. Когда она это делает, она поддерживает опцию -javaagent, как указано выше. Опция -javaagent может использоваться несколько раз в одной командной строке, тем самым запуская несколько агентов. Методы premain будут вызываться в порядке указания агентов в командной строке. Несколько агентов могут использовать один и тот же параметр <jarpath>.

Класс агента также может иметь метод agentmain для использования при запуске агента после запуска JVM (см. ниже). При запуске агента с помощью опции командной строки метод agentmain не вызывается.

Запуск агента в работающей JVM

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

  1. Класс агента должен быть упакован в JAR-файл агента. Главный манифест JAR-файла агента должен содержать атрибут Agent-Class. Значение этого атрибута — двоичное имя класса агента в JAR-файле.

  2. Класс агента должен определять публичный статический метод agentmain.

  3. JVM выводит предупреждение в стандартный поток ошибок для каждого агента, который она пытается запустить в работающей JVM. Если агент был запущен ранее (при запуске JVM или запущен в работающей JVM), то как ведёт себя JVM в случае повторной попытки запуска того же агента — зависит от реализации. Предупреждения можно отключить с помощью опции командной строки, специфичной для реализации.

    Примечание для реализации: Для виртуальной машины HotSpot используется опция командной строки JVM -XX:+EnableDynamicAgentLoading, чтобы разрешить динамическую загрузку агентов в работающую JVM. Эта опция подавляет предупреждение в стандартный поток ошибок при запуске агента в работающей JVM.

JVM запускает агента, загружая класс агента и вызывая его метод agentmain. Метод agentmain имеет одну из двух возможных сигнатур. JVM сначала пытается вызвать следующий метод в классе агента:

public static void agentmain(String agentArgs, Instrumentation inst)

Если класс агента не определяет этот метод, JVM попытается вызвать:

public static void agentmain(String agentArgs)

Параметры агента передаются агенту через параметр agentArgs. Параметры агента передаются как одна строка; агент сам должен выполнить любое дополнительное разбиение. В первом методе параметр inst — объект Instrumentation, который агент может использовать для инструментирования кода.

Метод agentmain должен выполнить все необходимые инициализации для запуска агента. По завершении запуска метод должен вернуть значение. Если агент нельзя запустить (например, потому что класс агента нельзя загрузить или потому что класс агента не имеет соответствующего метода agentmain), JVM не завершит работу. Если метод agentmain вызывает необработанное исключение, оно будет проигнорировано (но может быть залогировано JVM для отладки).

Класс агента может также иметь метод premain для использования, когда агент запускается с помощью опции командной строки. Метод premain не вызывается, когда агент запускается в работающей JVM.

Загрузка классов агента и модулей/классов, доступных классу агента

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

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

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

  • Классы, которые могут быть определены системным загрузчиком классов (обычно путем поиска по пути) для того, чтобы быть членами его безымянного модуля.

  • Любые классы, которые агент организует для определения загрузчиком bootstrap-классов, чтобы они были членами его безымянного модуля.

Если классам агентов необходимо связаться с классами в платформенных (или других) модулях, которые не находятся в слое загрузки, то приложение может потребоваться запустить таким образом, чтобы эти модули были в слое загрузки. Например, в реализации JDK опция командной строки --add-modules может использоваться для добавления модулей в набор корневых модулей, которые будут разрешены во время запуска.

Поддерживающие классы, которые агент организует для загрузки загрузчиком bootstrap-классов (с помощью appendToBootstrapClassLoaderSearch или атрибута Boot-Class-Path, указанного ниже), должны связываться только с классами, определёнными загрузчиком bootstrap-классов. Нет гарантии, что все платформенные классы могут быть определены загрузчиком bootstrap-классов.

Если настроен пользовательский загрузчик системных классов (при помощи системной переменной java.system.class.loader, как указано в методе getSystemClassLoader) , то он должен определить метод appendToClassPathForInstrumentation, как указано в appendToSystemClassLoaderSearch. Другими словами, пользовательский загрузчик системных классов должен поддерживать механизм добавления JAR-файла агента в поиск системного загрузчика классов.

Атрибуты манифеста JAR-файла

Следующие атрибуты в основной части манифеста JAR-файла приложения или агента определены для Java-агентов:

Launcher-Agent-Class
Если реализация поддерживает механизм запуска приложения в исполняемом JAR-файле, то этот атрибут, если присутствует, указывает имя двоичного класса агента, который упакован с приложением. Агент запускается путём вызова метода класса агента agentmain. Он вызывается до вызова метода приложения main.
Premain-Class
Если JAR-файл агента указан при запуске JVM, этот атрибут указывает имя двоичного класса агента в JAR-файле. Агент запускается путём вызова метода класса агента premain. Он вызывается до вызова метода приложения main. Если атрибут отсутствует, JVM завершит работу с ошибкой.
Agent-Class
Если реализация поддерживает механизм запуска агента в какой-то момент после запуска JVM, то этот атрибут указывает имя двоичного класса Java-агента в JAR-файле агента. Агент запускается путём вызова метода класса агента agentmain. Этот атрибут обязателен; если он отсутствует, агент не будет запущен.
Boot-Class-Path
Список путей, которые будут просматриваться загрузчиком начальных классов. Пути представляют собой каталоги или библиотеки (часто называемые JAR- или zip-библиотеками на многих платформах). Эти пути просматриваются загрузчиком начальных классов после того, как платформные механизмы поиска класса завершаются неудачно. Пути просматриваются в указанном порядке. Пути в списке разделены одной или несколькими пробелами. Путь имеет синтаксис компонента пути иерархического URI. Путь является абсолютным, если он начинается с символа косой черты ('/'), в противном случае он является относительным. Относительный путь разрешается относительно абсолютного пути JAR-файла агента. Неправильные и несуществующие пути игнорируются. Когда агент запускается в какой-то момент после запуска JVM, пути, которые не представляют собой JAR-файл, игнорируются. Этот атрибут необязателен.
Can-Redefine-Classes
Булево (true или false, регистр не важен). Требуется ли способность переопределять классы, необходимые этому агенту. Значения, отличные от true, считаются false. Этот атрибут необязателен, по умолчанию значение false.
Can-Retransform-Classes
Булево (true или false, регистр не важен). Требуется ли способность повторного преобразования классов, необходимых этому агенту. Значения, отличные от true, считаются false. Этот атрибут необязателен, по умолчанию значение false.
Can-Set-Native-Method-Prefix
Булево (true или false, регистр не важен). Требуется ли способность устанавливать префикс для методов нативного кода, необходимых этому агенту. Значения, отличные от true, считаются false. Этот атрибут необязателен, по умолчанию значение false.

JAR-файл агента может содержать как атрибут Premain-Class, так и атрибут Agent-Class в манифесте. Когда агент запускается в командной строке с использованием параметра -javaagent, то атрибут Premain-Class указывает имя двоичного класса агента, а атрибут Agent-Class игнорируется. Аналогично, если агент запускается в какой-то момент после запуска JVM, то атрибут Agent-Class указывает имя двоичного класса агента (значение атрибута Premain-Class игнорируется).

Инструментирование кода в модулях

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

С момента:
1.5
java.base
Модуль Пакет Описание
java.lang
Предоставляет классы, которые являются основополагающими для разработки языка программирования Java.
Класс Описание
ClassDefinition
Этот класс служит параметром для метода Instrumentation.redefineClasses.
ClassFileTransformer
Преобразователь файлов классов.
IllegalClassFormatException
Бросается реализацией ClassFileTransformer.transform, когда её входные параметры неверны.
Instrumentation
Этот класс предоставляет необходимые службы для инструментирования кода языка программирования Java.
UnmodifiableClassException
Бросается реализацией Instrumentation.redefineClasses, когда один из указанных классов не может быть изменён.
UnmodifiableModuleException
Бросается для указания, что модуль не может быть изменён.

© 1993, 2025, 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://download.java.net/java/early_access/jdk24/docs/api/java.instrument/java/lang/instrument/package-summary.html

Spec-Zone.ru

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