Kotlin: ProGuard erases properties attributes

穿精又带淫゛_ 提交于 2019-12-07 16:10:33

问题


TL;DR: with proguard enabled, when using reflection, my properties look private, non-nullable and without annotations, despite proguard config that should keep all these attributes.

I have some simple data classes with public properties to serve as data models in my Android app. Later, when doing generic [de]serialization of said classes, I filter the property list like this:

val properties = instance::class.memberProperties
        .filter { it.visibility == KVisibility.PUBLIC } // && some other conditions, unrelated here
        .filterIsInstance<KMutableProperty<*>>()

It works normally on my debug builds (I mean it selects the properties I want it to). But, when doing a release build, where proguard is active, the result is empty. To check why, I logged all the relevant stuff about the properties of one class -- turns out their visibility field reads PRIVATE (and all other attributes remain the same as on a debug build).

I already have a line in proguard config to keep all the models:

-keepclassmembers class * extends com.models.package.name.BaseModel { *; }

I tried this one before, with same result:

-keep class com.models.package.name.** { *; }

Why/how does proguard affect property visibility? Should I modify the config somehow? Or am I missing something else here?


UPDATE: It seems like visibility is not the only thing. prop.returnType.isMarkedNullable also doesn't work, it returns false for properties declared nullable. And annotations also seem to get lost, even though I asked proguard to keep them. Is there any way to work around this? It pretty much renders 2 weeks of my work useless...


回答1:


Thanks to the suggestion from @yole in question comments, I've been able to make this work. Even though my classes were configured to be kept by ProGuard, it stripped the kotlin.Metadata annotations from them. These annotatons are where Kotlin stores all the attributes I was missing. The solution is to prevent ProGuard from deleting them, adding to configuration:

-keep class kotlin.Metadata { *; }

(on a side note: it's weird that it's not included in the default config, at least if you're using the kotlin.reflect.full package. Or at least it should be mentioned clearly somewhere in the docs...)



来源:https://stackoverflow.com/questions/43565633/kotlin-proguard-erases-properties-attributes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!