Reputation: 228
previously i asked the question here, got some suggestions from @Rafael Winterhalter. i applied those changes but stuck with new error.
this code is working with subclass but I want to replace all the OkHttpClient automatically with bytebuddy.
how should I approach this ?
here is my code
fun setupOkHttpBuilderByteBuddy(context: Context) {
val strategy = AndroidClassLoadingStrategy.Wrapping(
context.getDir("generated", Context.MODE_PRIVATE)
)
try {
val classLoader = context.classLoader ?: OkHttpClient::class.java.classLoader
val dynamicType = ByteBuddy().with(TypeValidation.DISABLED)
.redefine(OkHttpClient::class.java)
.method(ElementMatchers.named("newCall"))
.intercept(MethodDelegation.to(OkHttpInterceptor::class.java))
.make()
.load(classLoader, strategy)
.loaded
Log.d("OkHttpInterceptor", "ByteBuddy modification completed")
val instance = dynamicType.getDeclaredConstructor().newInstance()
// Log the class name to verify if it’s from the dynamically generated class
Log.d("OkHttpInterceptor", "Class name of instance: ${instance::class.java.name}")
// Check if the instance is an instance of OkHttpClient and the modified class
val isSubclass = OkHttpClient::class.java.isAssignableFrom(instance::class.java)
Log.d("OkHttpInterceptor", "Is instance a subclass of OkHttpClient? $isSubclass")
} catch (e: Exception) {
e.printStackTrace()
}
}
here is OkHttpInterceptor
class OkHttpInterceptor {
companion object {
@JvmStatic
fun intercept(
@SuperCall originalCall: Callable<Call>,
@Argument(0) request: Request
): Call {
// Log or modify the request here
Log.d("OkHttpInterceptor", "Intercept method request: $request")
val client = OkHttpClient.Builder()
.addInterceptor(NetworkInterceptor())
.build()
// Call the original method with the modified request
// return originalCall.call()
return client.newCall(request)
}
}
}
here is the error
java.lang.IllegalStateException: Could not locate class file for okhttp3.OkHttpClient
at net.bytebuddy.dynamic.ClassFileLocator$Resolution$Illegal.resolve(ClassFileLocator.java:130)
at net.bytebuddy.dynamic.scaffold.TypeWriter$Default$ForInlining.create(TypeWriter.java:4034)
at net.bytebuddy.dynamic.scaffold.TypeWriter$Default.make(TypeWriter.java:2246)
at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase$UsingTypeWriter.make(DynamicType.java:4057)
at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase.make(DynamicType.java:3741)
at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase$Delegator.make(DynamicType.java:3993)
at com.rnadigital.monita_android.MyApplicationKt.setupOkHttpBuilderByteBuddy(MyApplication.kt:90)
at com.rnadigital.monita_android.MyApplication.onCreate(MyApplication.kt:33)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1316)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6998)
at android.app.ActivityThread.-$$Nest$mhandleBindApplication(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2236)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:205)
at android.os.Looper.loop(Looper.java:294)
at android.app.ActivityThread.main(ActivityThread.java:8177)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)
loaded /vendor/lib64/egl/libEGL_emulation.so
Upvotes: 0
Views: 54
Reputation: 44032
Runtime redefinition is not supported by Android. The next best thing would be to instrument your code during build time. Here you will need to instrument the code using Byte Buddy's Android Gradle plugin.
Upvotes: 0