javaAgent初探

agent 初探 premain 命令式 在main方法之前执行 agentmain 以Attach的方式载入,在Java程序启动后执行,1.6提供 public interface Instrumentation { /** * 添加Transformer(转换器) * ClassFileTransformer类是一个接口,通常用户只需实现这个接口的 byte[] transform()方法即可; * transform这个方法会返回一个已经转换过的对象的byte[]数组 * @param transformer 拦截器 * @return canRetransform 是否能重新转换 */ void addTransformer(ClassFileTransformer transformer, boolean canRetransform); /** * 重新触发类加载, * 该方法可以修改方法体、常量池和属性值,但不能新增、删除、重命名属性或方法,也不能修改方法的签名 * @param classes Class对象 * @throws UnmodifiableClassException 异常 */ void retransformClasses(Class<?>... classes) throws UnmodifiableClassException; /** * 直接替换类的定义 * 重新转换某个对象,并已一个新的class格式,进行转化。 * 该方法可以修改方法体、常量池和属性值,但不能新增、删除、重命名属性或方法,也不能修改方法的签名 * @param definitions ClassDefinition对象[Class定义对象] * @throws ClassNotFoundException,UnmodifiableClassException 异常 */ void redefineClasses(ClassDefinition... definitions)throws ClassNotFoundException, UnmodifiableClassException; /** * 获取当前被JVM加载的所有类对象 * @return Class[] class数组 */ Class[] getAllLoadedClasses(); } premain方法介绍 public class AgentWithTransFormer { public static void premain(String agentOps, Instrumentation instrumentation) { System.out.println("premian start 。。"); System.out.println("agentOps = " + agentOps); instrumentation.addTransformer(new DefineTransformer(),true); } /** * */ static class DefineTransformer implements ClassFileTransformer { @Override public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { System.out.println("premain load class :" + className); return classfileBuffer; } } } premain方法会拦截大部分类(不包含有些系统类),实现类DefineTransformer需要实现transform方法,比如我们可以拦截某个类,将某个类的class文件修改,可以整个文件替换或者利用javassist自定义添加或者删除方法。 ...

September 28, 2022 · 4 min
总访问量 总访客数