0

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.

MichaelThePotato
  • 1,523
  • 2
  • 10
  • 19

1 Answers1

0

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!

r2rek
  • 2,083
  • 13
  • 16
  • Thanks for your response! I tried doing both of your suggestions (adding the command and the class itself to proguard) and haven't managed to get it right. Could you post the proguard commands to do that? – MichaelThePotato Nov 07 '19 at 15:54