java.lang.instrument包结构
代理监控JVM运行的JAVA程序,对字节码修改
ClassFileTransformer(接口)
//转换类文件的代理接口
public interface ClassFileTransformer {
//protectionDomain - 要定义或重定义的类的保护域
//classfileBuffer - 类文件格式的输入字节缓冲区(不得修改)
byte[]
transform( ClassLoader loader,
String className,
Class<?> classBeingRedefined,
ProtectionDomain protectionDomain,
byte[] classfileBuffer)
throws IllegalClassFormatException;
}
*** ###Instrumentation(接口) Java SE 6新特性, 获取 Instrumentation 接口的实例有两种方式: 1. 当 JVM 以指示一个代理类的方式启动时,将传递给代理类的 premain 方法一个 Instrumentation 实例。 2. 当 JVM 提供某种机制在 JVM 启动之后某一时刻启动代理时,将传递给代理代码的 agentmain 方法一个 Instrumentation 实例
源码解释:
//提供检测 Java 编程语言代码所需的服务。检测是向方法中添加字节码
//以搜集各种工具所使用的数据
public interface Instrumentation {
/**
* 注册提供的转换器。
*/
void
addTransformer(ClassFileTransformer transformer, boolean canRetransform);
/**
* 注册提供的转换器。
*/
void
addTransformer(ClassFileTransformer transformer);
/**
* 注销提供的转换器
*/
boolean
removeTransformer(ClassFileTransformer transformer);
/**
* 返回当前 JVM 配置是否支持类的重转换。
*/
boolean
isRetransformClassesSupported();
/**
* 重转换提供的类集
*/
void
retransformClasses(Class<?>... classes) throws UnmodifiableClassException;
/**
* 返回当前 JVM 配置是否支持类的重定义
*/
boolean
isRedefineClassesSupported();
/**
* 使用提供的类文件重定义提供的类集
*/
void
redefineClasses(ClassDefinition... definitions)
throws ClassNotFoundException, UnmodifiableClassException;
/**
* 确定一个类是否可以被 retransformation 或 redefinition 修改。
*/
boolean
isModifiableClass(Class<?> theClass);
/**
* 返回 JVM 当前加载的所有类的数组
*/
Class[]
getAllLoadedClasses();
/**
* 返回所有初始化加载器是 loader 的类的数组。
*/
Class[]
getInitiatedClasses(ClassLoader loader);
/**
* 返回指定对象使用的特定于实现的近似存储量。
*/
long
getObjectSize(Object objectToSize);
/**
* 指定 JAR 文件,检测类由引导类加载器定义
*/
void
appendToBootstrapClassLoaderSearch(JarFile jarfile);
/**
* 指定 JAR 文件,检测类由系统类加载器定义。
*/
void
appendToSystemClassLoaderSearch(JarFile jarfile);
/**
* 返回当前 JVM 配置是否支持设置本机方法前缀。
*/
boolean
isNativeMethodPrefixSupported();
/**
* 通过允许重试,将前缀应用到名称,此方法修改本机方法解析的失败处理
*/
void setNativeMethodPrefix(ClassFileTransformer transformer, String prefix);
}
IllegalClassFormatException(异常)
ClassFileTransformer.transform 的实现抛出该异常。抛出此异常的原因或者由于初始类文件字节无效,或者由于以前应用的转换损坏了字节
UnmodifiableClassException(异常)
在无法修改指定类之一时,由 Instrumentation.redefineClasses 的实现抛出此异常。
ClassDefinition
public final class ClassDefinition {
/**
* 自身class
*/
private final Class mClass;
/**
* 本地class文件
*/
private final byte[] mClassFile;
/**
* 使用提供的类和类文件字节创建一个新的 ClassDefinition 绑定
*/
public
ClassDefinition( Class<?> theClass,
byte[] theClassFile) {
if (theClass == null || theClassFile == null) {
throw new NullPointerException();
}
mClass = theClass;
mClassFile = theClassFile;
}
/**
* 返回该类。
*/
public Class<?>
getDefinitionClass() {
return mClass;
}
/**
* 返回包含新的类文件的 byte 数组。
*/
public byte[]
getDefinitionClassFile() {
return mClassFile;
}
}