美文网首页
JAVAssist打印被调用方法的名称

JAVAssist打印被调用方法的名称

作者: ShrJanLan | 来源:发表于2024-04-19 23:32 被阅读0次
编写JavassistMethodPrinter.java
package com.shrjanlan.javassist;

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import java.io.ByteArrayInputStream;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.lang.instrument.Instrumentation;
import java.security.ProtectionDomain;

public class JavassistMethodPrinter {

    public static void premain(String agentArgs, Instrumentation inst) {
        inst.addTransformer(new ClassFileTransformer() {
            @Override
            public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
                if (className != null && !className.startsWith("java/")) { // 替换为要监控的类的名称
                    try {
                        ClassPool pool = ClassPool.getDefault();
                        CtClass ctClass = pool.makeClass(new ByteArrayInputStream(classfileBuffer));
                        CtMethod[] declaredMethods = ctClass.getDeclaredMethods();
                        for (CtMethod method : declaredMethods) {
                            //if (!Modifier.isStatic(method.getModifiers())) { // 排除静态方法
                            if (method.getMethodInfo().getCodeAttribute() != null) { //检查是否有方法体
                                String newClassName = className.replace("/", ".");
                                String methodName = method.getName();
                                method.insertBefore("System.out.println(\"JAVAssist=>" + newClassName + ":" + methodName + "\");");
                            }
                        }
                        ctClass.writeFile();
                        return ctClass.toBytecode();
                    } catch (Exception e) {
                        e.printStackTrace();
                        String errorMessage = e.getMessage();
                        if (errorMessage == null || errorMessage.isEmpty()) {
                            errorMessage = e.toString();
                        }
                        System.out.println("JAVAssist=errorMessage=>"+errorMessage);
                    }
                }
                return null;
            }
        });
    }
}
编辑清单文件MANIFEST.MF,指定Premain-Class为JavassistMethodPrinter.java
Manifest-Version: 1.0
Can-Redefine-Classes: true
Can-Retransform-Classes: true
Premain-Class: com.shrjanlan.javassist.JavassistMethodPrinter
将JavassistMethodPrinter.java和MANIFEST.MF打包成JavassistMethodPrinter.jar
Java服务启动时指定-javaagent:JavassistMethodPrinter.jar所在路径
执行Java方法,控制台会打印方法名

相关文章

网友评论

      本文标题:JAVAssist打印被调用方法的名称

      本文链接:https://www.haomeiwen.com/subject/vgguxjtx.html