byte-buddy icon indicating copy to clipboard operation
byte-buddy copied to clipboard

Replace Method Code

Open rupinder10 opened this issue 2 years ago • 3 comments

I have a method with some complex logic. Deep in the code there is an operation on a field value that I would like to change. I thought of implementing this with an Advice class with a onMethodExit. The problem with that is that then the original code executes and then the modified code executes. This is pretty inefficient because the original code is pretty complex. This is an already loaded class.

protected Set cache = Collections.synchronizedSet(new HashSet());
   
private boolean updateCache(File jarDir) {
  zFile = new ZipFile(jarDir);
  Enumeration zipEntry = zFile.entries();

  while(zipEntry.hasMoreElements()) {
    ZipEntry entry = (ZipEntry)zipEntry.nextElement();
    if (!entry.isDirectory()) {
      this.cache.add(entry.getName()); // This is the line I would like to change with some alternate logic
    }
  }
  return true;
}

The other option is to use MethodDelegation but then I am not sure how that can refer to the class fields. We use the field cache in this case. What is the best way to achieve this kind of instrumentation.

rupinder10 avatar Jan 22 '24 18:01 rupinder10

In advice, you can skip the original code. Look at: OnMethodEnter(skipOn = ...).

A common way of doing this is:

class MyAdvice {
  @Advice.OnMethodEnter(skipOn = Advice.NonDefaultValue.class)
  static boolean onEnter(@Advice.Local Object returnValue) {
    if (...) {
      // do alternative
      returnValue = ...;
      return true;
     } else {
       return false;
     }
  }

  @Advice.OnMethodExit
   static void exit(@Advice.Enter boolean skipped, @Advice.Local Object returnValue, @Advice.Return Object returnedValue) {
     if (skipped) {
       returnedValue = returnValue;
     }
   }
}

raphw avatar Jan 23 '24 20:01 raphw

Advice.NonDefaultValue.class

This worked. Thanks @raphw. I do have a question about what exactly does this mean ?

skipOn = Advice.NonDefaultValue.class

rupinder10 avatar Jan 25 '24 14:01 rupinder10

The default value is null, false or 0. It means that if this default value is returned, the method is not skipped, in this case. It's also explained in the javadoc.

raphw avatar Jan 28 '24 09:01 raphw