sam
sam

Reputation: 228

Could not locate class file for okhttp3.OkHttpClient with ByteBuddy android

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

Answers (1)

Rafael Winterhalter
Rafael Winterhalter

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

Related Questions