skip to Main Content

using Byte Buddy Android : ref offical link, never used it before.
is there any tutorial available for this?

code uses AndroidClassLoadingStrategy.Wrapping, which generates a .dex file in a writable location, typically in your app’s private directory (like /data/data/<your_app>), and attempts to execute it.
Android 10 and above enforce strict security policies to prevent apps from writing .dex or .jar files and executing them at runtime.

how can we use byte buddy android for the latest android versions?

    private fun runBuddyTest(context: Context) {

        val strategy = AndroidClassLoadingStrategy.Wrapping(applicationContext.getDir("generated", Context.MODE_PRIVATE))

// Create a dynamic type (subclass of Object) and modify the "toString" method
        val dynamicType = ByteBuddy()
            .subclass(Any::class.java)
            .method(ElementMatchers.named("toString"))
            .intercept(FixedValue.value("Hello World!"))
            .make()
            .load(this.javaClass.classLoader, strategy)
            .loaded

// Instantiate the dynamically created class and assert the "toString" method
        val instance = dynamicType.getDeclaredConstructor().newInstance()
        assert(instance.toString() == "Hello World!")
    }

getting this error

 FATAL EXCEPTION: main
Process: com.rnadigital.bytebuddyapplication, PID: 12815
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.rnadigital.bytebuddyapplication/com.rnadigital.bytebuddyapplication.MainActivity}: java.lang.SecurityException: Writable dex file '/data/user/0/com.rnadigital.bytebuddyapplication/app_generated/d7rUqolH.jar' is not allowed.
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3782)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3922)
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:139)
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:96)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2443)
    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)
Caused by: java.lang.SecurityException: Writable dex file '/data/user/0/com.rnadigital.bytebuddyapplication/app_generated/d7rUqolH.jar' is not allowed.
    at dalvik.system.DexFile.openDexFileNative(Native Method)
    at dalvik.system.DexFile.openDexFile(DexFile.java:406)
    at dalvik.system.DexFile.<init>(DexFile.java:128)
    at dalvik.system.DexFile.<init>(DexFile.java:101)
    at dalvik.system.DexPathList.loadDexFile(DexPathList.java:438)
    at dalvik.system.DexPathList.makeDexElements(DexPathList.java:397)
    at dalvik.system.DexPathList.<init>(DexPathList.java:166)
    at dalvik.system.BaseDexClassLoader.<init>(BaseDexClassLoader.java:160)
    at dalvik.system.BaseDexClassLoader.<init>(BaseDexClassLoader.java:105)
    at dalvik.system.DexClassLoader.<init>(DexClassLoader.java:55)
    at net.bytebuddy.android.AndroidClassLoadingStrategy$Wrapping.doLoad(AndroidClassLoadingStrategy.java:580)
    at net.bytebuddy.android.AndroidClassLoadingStrategy.load(AndroidClassLoadingStrategy.java:148)
    at net.bytebuddy.dynamic.TypeResolutionStrategy$Passive.initialize(TypeResolutionStrategy.java:101)
    at net.bytebuddy.dynamic.DynamicType$Default$Unloaded.load(DynamicType.java:6317)
    at com.rnadigital.bytebuddyapplication.MainActivity.generateDynamicClassInMemory(MainActivity.kt:79)
    at com.rnadigital.bytebuddyapplication.MainActivity.onCreate(MainActivity.kt:52)
    at android.app.Activity.performCreate(Activity.java:8595)
    at android.app.Activity.performCreate(Activity.java:8573)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1456)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3764)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3922) 
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103) 
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:139) 
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:96) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2443) 
    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)

this is gradle file

    plugins {
    alias(libs.plugins.android.application)
    alias(libs.plugins.jetbrains.kotlin.android)

}

android {
    namespace = "com.rnadigital.bytebuddyapplication"
    compileSdk = 34

    defaultConfig {
        applicationId = "com.rnadigital.bytebuddyapplication"
        minSdk = 24
        targetSdk = 34
        versionCode = 1
        versionName = "1.0"
        multiDexEnabled = true


        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
        vectorDrawables {
            useSupportLibrary = true
        }
    }

    buildTypes {
        release {
            isMinifyEnabled = false
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = "1.8"
    }
    buildFeatures {
        compose = true
    }
    composeOptions {
        kotlinCompilerExtensionVersion = "1.5.1"
    }
    packaging {
        resources {
            excludes += "/META-INF/{AL2.0,LGPL2.1}"
        }
    }
}

dependencies {

    implementation(libs.androidx.core.ktx)
    implementation(libs.androidx.lifecycle.runtime.ktx)
    implementation(libs.androidx.activity.compose)
    implementation(platform(libs.androidx.compose.bom))
    implementation(libs.androidx.ui)
    implementation(libs.androidx.ui.graphics)
    implementation(libs.androidx.ui.tooling.preview)
    implementation(libs.androidx.material3)
    testImplementation(libs.junit)
    androidTestImplementation(libs.androidx.junit)
    androidTestImplementation(libs.androidx.espresso.core)
    androidTestImplementation(platform(libs.androidx.compose.bom))
    androidTestImplementation(libs.androidx.ui.test.junit4)
    debugImplementation(libs.androidx.ui.tooling)
    debugImplementation(libs.androidx.ui.test.manifest)
//    implementation (libs.byte.buddy)
    implementation (libs.byte.buddy.android)

}

2

Answers


  1. Chosen as BEST ANSWER

    It was just an update issue, I upgraded the library with the latest version and it worked.

    implementation("net.bytebuddy:byte-buddy-android:1.15.5")


  2. Byte Buddy normally sets the file permissions to OWNER_READ. Have a look at the FileProcessor class where this is done. Is the processor not active? Possibly, you are running an older version of Byte Buddy where this is not taken into account. Android changes quite often, so only the newer versions will support more modern Android.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search