raphw / byte-buddy

Runtime code generation for the Java virtual machine.
https://bytebuddy.net
Apache License 2.0
6.22k stars 802 forks source link

Consultation on implementing a similar functionality to javassist's instrument feature. #1673

Open zhangzhen91 opened 2 months ago

zhangzhen91 commented 2 months ago

@raphw firstly thanks to your great job

We were previously using the javassist framework and implemented the functionality to print out which methods were called within the getName method, as well as the ability to add a line of code before internal method calls, such as the length method, using instrument.

However, I've noticed that bytebuddy doesn't seem to have a direct way to achieve this functionality. Could you please guide me on how to implement this in bytebuddy?

`public class MethodTest {

public static String getName() {
    String action = "start";
    int length = action.length();
    int hashCode = action.hashCode();
    return "hello";
}

public static void updateMethod() throws Exception {
    ClassPool pool = ClassPool.getDefault();
    CtClass ctClass = pool.get("com.jd.jr.sgm.client.MethodTest");
    CtMethod getName = ctClass.getDeclaredMethod("getName", new CtClass[]{});
    getName.instrument(
            new ExprEditor() {
                @Override
                public void edit(MethodCall m) throws CannotCompileException {
                    System.out.println(m.getClassName());
                    System.out.println(m.getMethodName());

// if (m.getClassName().equals("java.lang.String") // && m.getMethodName().equals("length")) { // m.replace("$_ = 100;"); // } } } ); ctClass.toBytecode(); MethodTest.getName(); }

public static void main(String[] args) throws Exception {
    updateMethod();
}

}`

raphw commented 3 days ago

Sorry, I missed that. Byte Buddy has MemberSubstitution where you can match the method and replace it with a constant value, so this already works.

Byte Buddy does not offer a string-compiler for similar reasons to DSLs for SQL to avoid injection. Advice is the closest you would get.