Статьи

Как написать агент Java

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

Начало

Создайте класс агента с помощью метода «static public static void premain (String args, Instrumentation inst)» ». Поместите этот класс в jar-файл с манифестом, указывающим на класс Agent. Предварительный метод будет вызван перед основным методом приложения.

01
02
03
04
05
06
07
08
09
10
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.9.2
Created-By: 1.8.0_05-b13 (Oracle Corporation)
Built-By: Thomas Krieger
Implementation-Vendor: Anarsoft
Implementation-Title: VMLens Agent
Implementation-Version: 2.0.0.201511181111
Can-Retransform-Classes: true
Premain-Class: com.anarsoft.trace.agent.Agent
Boot-Class-Path: agent_bootstrap.jar

Файл MANIFEST.MF от vmlens .

Класс загрузчик магическая часть 1

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

01
02
03
04
05
06
07
08
09
10
11
12
13
// remember the currently used classloader
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
         
// Create and set a special URLClassLoader
URLClassLoader classloader = new URLClassLoader(urlList.toArray(new URL[]{}) , null );
Thread.currentThread().setContextClassLoader(classloader);
     
// Load and execute the agent
String agentName = "com.anarsoft.trace.agent.runtime.AgentRuntimeImpl";
AgentRuntime agentRuntime  =  (AgentRuntime) classloader.loadClass(agentName).newInstance();
     
// reset the classloader
Thread.currentThread().setContextClassLoader(contextClassLoader);

Класс загрузчик магии часть 2

Теперь мы используем asm для добавления наших статических методов обратного вызова при обращении к полю. Чтобы убедиться, что классы видимы в любом другом классе, они должны быть загружены загрузчиком классов начальной загрузки. Для этого они должны быть в пакете java, а содержащий их jar — в пути к загрузочному классу.

1
2
3
4
5
6
7
8
package java.anarsoft.trace.agent.bootstrap.callback;
 
public class FieldAccessCallback {
 
public static  void getStaticField(int field,int methodId) {
 }
 
}

Класс обратного вызова от vmlens . Он должен быть в пространстве имен пакета java, чтобы быть видимым во всех классах.

1
Boot-Class-Path: agent_bootstrap.jar

Запись пути к загрузочному классу в файле MANIFEST.MF из vmlens .

VMLens , облегченная программа отслеживания состояния Java, создана как Java-агент. Мы знаем, что написание Java-агентов может быть сложным делом. Так что, если у вас есть какие-либо вопросы, просто задайте их в комментарии ниже.

Ссылка: Как написать java-агент от нашего партнера JCG Томаса Кригера в блоге Java Advent Calendar .