'Android Gradle Plugin 4.2.x changed behavior for assumenosideeffects

I noticed a behaviour change using the Android Gradle Plugin 4.2.x regarding the ProGuard assumenosideeffects rule. I use this rule in my Android library project to remove all trace and debug calls from the SLF4J logging facility.

Using Android Gradle Plugin version 4.1.x the org.slf4j.Logger.trace method call is removed as expected from my wrapper class when building a release variant. To be more specific: The line of code is not available anymore in the classes.jar of the resulting AAR file.

Using AGP 4.2.x the line is still present. This is reproduceable by changing the version number from 4.2.x to 4.1.x with the setup below.

I added the android.util.Log dependency for testing reasons. The d method is removed after compilation in both AGP versions.

I would expect that the same rule works in both AGP versions. What I'm missing here? Is there something needed in addition?

In addition, why is the rule working for the android.util.Log example but not for org.slf4j.Logger.trace?

Here's a setup to reproduce this scenario. Just create a new library project from scratch in Android Studio and add the following config where necessary.

project build.gradle

buildscript {
    ext.kotlin_version = "1.5.20"
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:4.2.2"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

module build.gradle

android {
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation 'org.slf4j:slf4j-api:1.7.31'
}

Wrapper implementation

import android.util.Log;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyLoggerWrapper {

    private final Logger logger;

    private MyLoggerWrapper(Logger logger) {
        this.logger = logger;
    }

    public static MyLoggerWrapper getLogger(Class<?> clazz) {
        return new MyLoggerWrapper(LoggerFactory.getLogger(clazz));
    }


    public void trace(String message) {
        logger.trace(message);
    }

    public void anotherTrace(String message) {
        Log.d("MYTAG",message);
    }
}

ProGuard / R8 rules

-keep class com.example.myapplication.MyLoggerWrapper { *; }

-assumenosideeffects public interface org.slf4j.Logger {
    public *** trace(...);
    public *** debug(...);
}

-assumenosideeffects public class android.util.Log {
    public *** d(...);
}


Solution 1:[1]

If you use Gradle Kotlin DSL, you need to add a file in your module directory.

For example: libs/someAndroidArchive.aar

After just write this in your module build.gradle.kts in the dependency block:

**implementation(files("libs/someAndroidArchive.aar"))**

Option 1:

  1. Open your Android Studio and navigate to the Create New Module window by File -> New -> New Module

  2. Select the Import .JAR/.AAR Package item and click the Next button

  3. Add a dependency in the build.gradle file that belongs to your app module.

dependencies { ... implementation project(path: ':your aar lib name') }

Option 2

  1. Create a folder in libs directory, such as aars.

  2. Put your aar lib into the aars folder.

  3. Add the code snippet

repositories {
    flatDir {
        dirs 'libs/aars'
    }
}

into your build.gradle file belongs to the app module.

  1. Add a dependency in the build.gradle file that belongs to your app module.

    dependencies {

    ...
    implementation (name:'your aar lib name', ext:'aar') 
    

    }

Solution 2:[2]

I'm having a similar issue. In my case the library is my own and R8 seems to refuse to remove my logging calls using assumenosideeffect.

My best result so far is to disable R8 when building the library using android.enableR8=false.

I'm not happy with this answer but it's the best that I have found so far.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Nadeem Taj
Solution 2 dalton