编写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方法,控制台会打印方法名
网友评论