Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace Method Code #1583

Open
rupinder10 opened this issue Jan 22, 2024 · 3 comments
Open

Replace Method Code #1583

rupinder10 opened this issue Jan 22, 2024 · 3 comments
Assignees
Labels
Milestone

Comments

@rupinder10
Copy link

rupinder10 commented Jan 22, 2024

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.

@raphw
Copy link
Owner

raphw commented Jan 23, 2024

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 raphw self-assigned this Jan 23, 2024
@raphw raphw added the question label Jan 23, 2024
@raphw raphw added this to the 1.14.11 milestone Jan 23, 2024
@rupinder10
Copy link
Author

Advice.NonDefaultValue.class

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

skipOn = Advice.NonDefaultValue.class

@raphw
Copy link
Owner

raphw commented Jan 28, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants