kotlin.reflect.jvm.internal.KotlinReflectionInternalError when minifyEnabled - kotlin

I get a problem.
when my app minifyenabled is true , it crashed ! and the error is following:
kotlin.reflect.jvm.internal.KotlinReflectionInternalError: This callable does not support a default call: public constructor LoginResultBean
I think there must be some relationships with moshi and R8. I need help...

As this seems to be caused by reflective code, you might need more keep rules for your program. See https://developer.android.com/studio/build/shrink-code for more information.

Related

Kotlin constructor reference in Intellij

It is not really a Kotlin question, maybe an Intellij question, I don't know.
Assume we have a data class
data class Person(val name: String = "untitled", val age: Int = 20)
And we have a function
fun factory(cstr: ()->Person) : Person {
return cstr()
}
Then we can invoke factory(::Person) and obtain an instance of Person class with default constructor parameters.
The fun factory can be invoked successfully wherever. But in IntelliJ I get a red underline error
Look like the IDE failed to recognize that there is a default constructor.
However, If I change the code like that, the error goes away. Everything runs perfectly and no error is shown in the IDE.
I am using IntelliJ 2020.2 and Kotlin 1.4.10.
Maybe it is about some IntelliJ inspection rules, but I cannot find one related.
Further, it is a piece of old code that showed no error before (maybe 5 months ago). I am not sure what has bee change since then caused the error.
So the problem is why is Intellij show error for lambda version and not for KFunction version?
I assume invoking factory like this works fine:
factory(() -> Person())
Then it seems your version of the Kotlin IDE plugin does not handle constructor references well in this case. The compiler does, since the code works. If the IDE plugin version is the latest, please file a bug at https://youtrack.jetbrains.com/issues/KT
I reproduced the problem with old inference enabled in the build.gradle file: freeCompilerArgs += ["-XXLanguage:-NewInference"]. Please make sure you're using new (default) type inference in Kotlin 1.4+. So, remove the compiler argument, that should fix the IDE highlighting after Gradle project reimport into IDEA.

ClassCastException after obfuscation internal classes with suspend functions

I'm building a kotlin AAR library which I need to obfuscate before publishing. I have the following structure:
package com.example.token
interface TokenManager {
suspend fun getTokenStatus(): String
}
The above is a public interface available for the api client. The implementation is moved to an internal package:
package com.example.token.internal
internal class RestApiTokenManager: TokenManager {
override suspend fun getTokenStatus(): String {
//....
}
}
My obfuscation exception includes only the public interface package:
-keep class com.example.token.*{*;}
Unfortunately this results in a class cast exception:
java.lang.ClassCastException: e.e.a.a.l.d.e$a cannot be cast to c.a.a.e.a.a$a
In order to fix this I need to add an obfuscation exception for the implementation package, which I want to avoid.
Now the true weird problem is that the ClassCastException disappears as soon as I remove the suspend modifier.
I tried adding -keeptkotlinmetadata but I get R8: Unknown option error.
I've been stuck with this for a long time now, without a solution which won't force me to add an exception for my internal implementation classes.
This could be a bug in R8, and I have opened issue 167373399 to track this.
Please follow up there with information on the version of Android Studio / R8 you are currently using?
Please also take a look at this Medium post, which has more details on shrinking Kotlin code with R8.
The discussion continued and was concluded on the issuetracker 167373399

Kotlin Coroutines dependency going into Overload Resolution Ambiguity

I'm having a production ready Kotlin code and I want to refactor it from changing all CompletableFuture requests to Coroutines, but when I add the compile('org.jetbrains.kotlinx:kotlinx-coroutines-core:1.1.0') dependecy tu build.gradle, all my kotlin.collections imports are going into "Overload resolution ambiguity". Does anybody knows how to deal with this problem?
Here is a snippet from my code:
TX!
Generally this happens when indexes get stale in IDEA. Try to build with gradle to ensure there is no real clashes. Running File -> Invalidate caches / Restart should help.

When can Proguard optimize enums out?

https://www.guardsquare.com/en/proguard/manual/optimizations says
class/unboxing/enum
Simplifies enum types to integer constants, whenever possible.
But the obvious question is, when is it possible? I assume the enum must not have fields/methods? Does it apply only to local variables or to method arguments as well?
In particular, if I have a enum with a field and a getter for this field, I could convert it to a static method switching on the enum; will this enable the optimization?
Optimization
Your assumption is correct, for the Proguard to optimize an enum, that enum should not have methods and associated values(fields). Proguard converts these simple enums to ints so, you get the type-safety of the enums at compile-time and the performance of ints at runtime.
It applies both to variables as well as method arguments.
So for your case where you have a field in an enum, the optimization won't apply.
Jake Wharton who worked for the Android team and others have discussed enum optimization in this Reddit post.
Proguard Settings
The Proguard settings should look like following:
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
Note the inclusion of the proguard-android-optimize.txt file and not the proguard-android.txt file.
ProguardEnumIntDefTest is a sample project on Github that tries to find out if Proguard converts enums into ints.

Is it really a limitation to use interfaces such as IList<T>.someMethod in AOT code?

In the mono project documentation this limitation is outlined:
Limitation: Generic Interface Instantiation
The following class of interface dispatch is not supported in FullAOT
mode:
interface IFoo<T> {
...
void SomeMethod ();
}
Since Mono has no way of determining from the static analysis what
method will implement IFoo.SomeMethod this particular pattern is
not supported.
We have been using code like this unbeknownst to this limitation, and are currently attempting to figure out if some stability issues and this are related. This seems to function as expected, and so we are skeptical this is an issue still. Our code compiles to AOT with no errors, and runs without throwing any errors. Is this just old documentation?
An added bonus question: If this isn't supposed to work...why does it work for the built-in C# classes such as IList without issue but it shouldn't work otherwise?