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

Can 'private final method' in 'public final class' be redefined? #1591

Closed
zzhlhc opened this issue Feb 12, 2024 · 4 comments
Closed

Can 'private final method' in 'public final class' be redefined? #1591

zzhlhc opened this issue Feb 12, 2024 · 4 comments
Assignees
Labels
Milestone

Comments

@zzhlhc
Copy link

zzhlhc commented Feb 12, 2024

Sorry for asking such a simple question, but I really couldn't find the relevant answer.

Below is my current code:

public class DispatcherDelegation {
    public static Boolean promoteAndExecute(@This Dispatcher dispatcher){.....}
}

public class AgentMain {
   void redefineDispatcher(Instrumentation instrumentation) {
        byte[] newBytes = new ByteBuddy()
                .redefine(Dispatcher.class)
                .method(named("promoteAndExecute"))
                .intercept(MethodDelegation.to(DispatcherDelegation.class))
                .make()
                .getBytes();
        ClassDefinition classDefinition = new ClassDefinition(Dispatcher.class, newBytes);
        instrumentation.redefineClasses(classDefinition);
  }
}

Error is:

Caused by: java.lang.IllegalArgumentException: None of [public static java.lang.Boolean org.example.DispatcherDelegation.promoteAndExecute(...)] allows for delegation from private final boolean okhttp3.Dispatcher.promoteAndExecute()

How can I solve this problem? thank you very much! orz...

@raphw
Copy link
Owner

raphw commented Feb 13, 2024

Can you show your imports? I wonder if you imported the Advice version.

@raphw raphw self-assigned this Feb 13, 2024
@raphw raphw added the question label Feb 13, 2024
@raphw raphw modified the milestones: 0.4.1, 1.14.11 Feb 13, 2024
@zzhlhc
Copy link
Author

zzhlhc commented Feb 13, 2024

Sure, DispatcherDelegation's imports :

import net.bytebuddy.implementation.bind.annotation.FieldValue;
import net.bytebuddy.implementation.bind.annotation.This;
import okhttp3.Dispatcher;
import okhttp3.internal.connection.RealCall;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;

AgentMain's imports:

import javassist.ClassClassPath;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.dynamic.scaffold.TypeValidation;
import net.bytebuddy.implementation.MethodDelegation;
import okhttp3.Dispatcher;
import okhttp3.internal.connection.RealCall;

import java.lang.instrument.ClassDefinition;
import java.lang.instrument.Instrumentation;
import java.lang.instrument.UnmodifiableClassException;

import static net.bytebuddy.matcher.ElementMatchers.named;

byte-buddy's version:

<dependency>
            <groupId>net.bytebuddy</groupId>
            <artifactId>byte-buddy</artifactId>
            <version>1.11.22</version>
        </dependency>

@zzhlhc
Copy link
Author

zzhlhc commented Feb 13, 2024

Solved, from your reply I realized that it might be a problem with the method parameters, deleted the executorService below, and succeeded

public class DispatcherDelegation {
      public static Boolean promoteAndExecute(@This Dispatcher dispatcher
                , @FieldValue("executorService") ExecutorService executorService)
}

The executorService in Dispatcher.kt:

  private var executorServiceOrNull: ExecutorService? = null

  @get:Synchronized
  @get:JvmName("executorService") val executorService: ExecutorService
    get() {
      if (executorServiceOrNull == null) {
        executorServiceOrNull = ThreadPoolExecutor(0, Int.MAX_VALUE, 60, TimeUnit.SECONDS,
            SynchronousQueue(), threadFactory("$okHttpName Dispatcher", false))
      }
      return executorServiceOrNull!!
    }

I'm new to both byte-buddy and kotlin, anyway the problem is solved, thanks!!

@raphw
Copy link
Owner

raphw commented Feb 13, 2024

I think the field is executorServiceOrNull, the other one is the method. so you'd use rhe first as field name.

@zzhlhc zzhlhc closed this as completed Feb 15, 2024
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