MichaelThePotato
MichaelThePotato

Reputation: 1525

DelegatedProperty reflection doesn't work on release build

During runtime I need to access properties in the delegated property's delegate instance.

When I compile the following code in debug, it works just fine:

class Potato {
    val somePropGoesHere: Int by PotatoDeletgate("This is the key", 0)

    fun getKey(property: KProperty1<Potato, *>): String {
        property.isAccessible = true
        val delegate = property.getDelegate(this)

        return when (delegate) {
            is PotatoDeletgate<*> -> delegate.key
            else -> throw IllegalStateException("Can't observe the property - ${property.name}")
        }
    }

    class PotatoDeletgate<T>(val key: String,
                             defaultValue: T) {
        private var innerValue = defaultValue

        operator fun getValue(thisRef: Any?, property: KProperty<*>): T {
            // more logic
            return innerValue
        }

        operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
            // more logic
            innerValue = value
        }
    }
}

class PotatoShredder {
    fun doStuff() {
        val potato = Potato()
        val key = potato.getKey(Potato::somePropGoesHere)
    }
}

When I'll call the "doStuff" method in debug, the "key" val will get the "This is the key" string.

However, when I'll compile this code in release, I get the error:

2019-11-07 16:16:04.141 7496-7496/? E/AndroidRuntime: FATAL EXCEPTION: main Process: com.trax.retailexecution, PID: 7496

e.a.a.a.j0: Property 'somePropGoesHere' (JVM signature: getSomePropGoesHere()I) not resolved in class com.trax.retailexecution.util.Potato

at e.a.a.a.p.c(KDeclarationContainerImpl.kt:40)

at e.a.a.a.z$d.invoke(KPropertyImpl.kt:4)

at e.a.a.a.l0.a(ReflectProperties.java:4)

at e.a.a.a.z.e(KPropertyImpl.kt:2)

I'm not sure how

at e.a.a.a.z$e.invoke(KPropertyImpl.kt:1)

at e.a.a.a.m0.a(ReflectProperties.java:3)

at e.a.a.a.z.i(KPropertyImpl.kt:1)

at c.m.a.b.a.a(DefaultConfigurationFactory.java:82)

at c.m.a.b.a.a(DefaultConfigurationFactory.java:153)

at com.trax.retailexecution.util.Potato.getKey(Potato.kt:1)

at mynamespacegoeshere.PotatoShredder.doStuff(Potato.kt:2)

I thought that it has something to do with proguard, since the class and/or the methods we're deleted during the compression/shrinking but I couldn't really find a way to properly fix the problem.

Upvotes: 0

Views: 310

Answers (1)

r2rek
r2rek

Reputation: 2233

It is indeed connected to proguard - your somePropGoesHere can't be found in obfuscated code.

Don't have any workaround for it though except for not using reflection :)(and I would suggest that)

You could also add your PotatoDelegate to proguard rules :)

Cheers!

Upvotes: 0

Related Questions