Menu

#182 Support Kotlin class files

Some sunny day
open
None
5
2019-10-03
2017-02-08
No

Generally ProGuard works fine with class files produced by Kotlin. Sometimes, however, it obfuscates or removes declarations which are needed for compilation (if the processed class files were in a library) or for Kotlin reflection. Currently, ProGuard has no way of knowing which declarations are needed for Kotlin code to operate correctly and which not. I propose to support this.

For example, one issue that has come up recently is related to synthetic methods which the Kotlin compiler is generating to store annotations on properties on. If you declare a property and annotate it with something, a new method is generated in the class file, annotated with these annotations. This synthetic method is private and unused, so ProGuard happily strips it from the resulting jar, which leads to Kotlin reflection not finding the annotation at runtime. Note that this exact case has been worked around on our side, but other similar problems remain.

Without delving into too much details, what I propose to implement is the following: for class files annotated with the kotlin.Metadata (github.com) annotation, load the strings from its "d2" field and treat them in the same way as the obfuscatable method/field names in the class file. For example, if Metadata.d2 contains a string "abacaba" and there's a method named "abacaba" in the class file that is going to be renamed to "z" by ProGuard, then also change the string value in Metadata.d2 from "abacaba" to "z".

Discussion

  • Eric Lafortune

    Eric Lafortune - 2018-03-29

    Thanks for the heads up. This feels like a very random convention to me... For the time being you'll have to keep the method with its original name. For example:

    -keepclassmembers class com.example.SomeClass {
        *** abacaba(...);
    }
    

    In general, the following is overly conservative but it should work:

    -keep,allowobfuscation @interface kotlin.Metadata
    -keepclassmembers @kotlin.Metadata class * {
        <methods>;
    }
    
     
  • Eric Lafortune

    Eric Lafortune - 2018-03-29
    • assigned_to: Eric Lafortune
     
  • Alexander Udalov

    Thanks. I was expecting that this convention had little chance to end up in the ProGuard source. Is there maybe a way to write an extension or a plugin for ProGuard, implementing the described convention, so that Kotlin users would benefit from a more reliable (in terms of Kotlin-specific introspection tools) obfuscation?

     
  • Dmitriy Startsev

    A big +1 for supporting @kotlin.Metadata. Currently, any renaming of fields or methods in a kotlin class results in the class losing its integrity, thus leading to strange errors when you try to use kotlin reflection tools with this class.

     
  • T. Neidhart

    T. Neidhart - 2019-10-03

    DexGuard the commercial variant of ProGuard already has initial support for processing of kotlin.Metadata annotations for shrinking / obfuscation steps. We plan to add this to ProGuard as well, if you are interested in testing this feature, please send me a personal message to thomas.neidhart@guardsquare.com.

     

Log in to post a comment.

MongoDB Logo MongoDB