Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I target kotlin `internal` classes with proguard?

I'd like to proguard (obfuscate) any classes marked with the kotlin internal visibility modifier.

Kotlin internal classes are public on the JVM, so they are visible and usable from Java source. I don't want these classes to be used or appear in autocomplete, so I would like to obsfuscate them to discourage their use.

What proguard rule can I apply to target internal classes?

like image 658
ZakTaccardi Avatar asked Apr 03 '18 14:04

ZakTaccardi


2 Answers

Just use this for the class you want to show, everything else will be Obfuscated / Optimized.

-keep class package.for.class.MyPublicClass {
    public <methods>;
 }

In your module build.gradle

buildTypes {
    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
    debug {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
}
like image 108
user3826696 Avatar answered Nov 03 '22 19:11

user3826696


As explained in the Kotlin reference guide:

internal declarations become public in Java. Members of internal classes go through name mangling, to make it harder to accidentally use them from Java and to allow overloading for members with the same signature that don't see each other according to Kotlin rules;

Looking at the generated bytecode of an internal class (com.example.Test with an internal field c) shows this:

Compile from "Test.kt"
public final class com.example.Test
minor version: 0
major version: 50
flags: ACC_PUBLIC, ACC_FINAL, ACC_SUPER

private final int c;
  descriptor: I
  flags: ACC_PRIVATE, ACC_FINAL
  ConstantValue: int 3

public final int getC$Kotlin_debug();
  descriptor: ()I
  flags: ACC_PUBLIC, ACC_FINAL
  Code:
    stack=1, locals=1, args_size=1
       0: aload_0
       1: getfield      #11                 // Field c:I
       4: ireturn

The internal field has a name-mangled getter, which could be used to target it with a ProGuard rule, but the internal class itself is just a plain public class in Java bytecode and there seems to be no way to target it specifically with ProGuard.

like image 42
T. Neidhart Avatar answered Nov 03 '22 21:11

T. Neidhart