JDK源码-java.lang.instrument-第一部分-源码学习

本文深入探讨Java SE 6新增的Instrumentation特性,介绍如何利用这一特性监控和修改JVM上运行的Java程序的字节码,包括ClassFileTransformer接口及Instrumentation接口的详细说明。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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;
}

}


Java Agent是Arthas使用的技术,是Skywalking使用的技术,是一份十分重要的技术。 课程的稀缺性在此之前,市面上并没有针对Java Agent进行系统介绍的课程。 通过搜索引擎查找,会发现与Java Agent相关的内容大多是个人知识总结分享的内容。这些内容有如下特点:内容质量不一详略程度不一学习难度千差万别总体上来说,学习者很难有一个整体认知、系统学习的过程。 课程的设计目标 在构思课程内容时,本课程带有以下目标:课程学习梯度:从简单到复杂,让学习者有一个循序渐进的理解过程。构造完整、统一的知识体系:不是零散的知识点堆砌,而是有一个统一的贯穿始终的知识框架。具有可操作性的代码示例,不只是讲概念,更注意于实践。课程内容安排 本课程通过四章内容对Java Agent相关知识进行讲解:第一章,介绍Agent Jar的三个组成部分:Manifest、Agent Class和ClassFileTransformer。第二章,介绍Agent Jar的两种启动方式:从命令行启动和使用Attach机制启动。第三章,介绍如何利用Instrumentation API来实现Agent Jar的功能。第四章,Java Agent的应用与技巧。 通过本课程的学习,让同学们更好地建立起一个完整的知识体系:  讲师介绍我叫刘森,南京师范大学研究生毕业,2015年获得信息系统项目管理师(高级),2014年获得系统集成项目管理工程师(中级)。 目前,我的课程都是围绕着“Java字节码”技术展开: 《Java Agent基础篇》是在一个运行JVM当中提供修改字节码的机会《Java ASM系列》(免费课程)是一个操作字节码的类库《Java 8 ClassFile》专注于字节码的理论知识,入选为“51CTO数字化人才证书项目认证课程” 因此,我对字节码技术有较为深入的研究和理解,大家想学习字节码的技术可以找我:字节码技术找刘森,轻松学习又省心~~~ 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值