Status Update
Comments
mg...@google.com <mg...@google.com> #2
Hi Sebastian
You are right that R8 is doing the same desugaring of default interface methods as D8. Can you provide a bit more information on what you are seeing? Which version of D8/R8 are you using? Are you invoking D8/R8 from the command line or are you using a build system? If you are using it from the command-line, can you give an example of the command-line that you are using? With R8 you should use one invocation with all the class files as input in one go to build the final dex. Could it be that you end up merging things together where parts of it has been built with desugaring and the other part has not? If you can provide a reproduction either here on the bug or privately to
Thanks, Mads
ap...@google.com <ap...@google.com> #3
I build R8/D8 from source, it should be just a few commits behind master. I needed to apply a minimal patch to avoid a NPE, because R8 should process a java.lang.Object class, you can find it here:
I wanted to contribute it back, but my CLA wasn't processed yet. But I also don't think that the patch is related to the behavior I noticed.
What I do is that I have 3 jars that I want to dex. When I do it with d8 all works fine (command line can be seen in the reproducer). When I just switch d8 with r8 it fails with the exception mentioned in my first message, but as far as I understand it at the dexing point.
I appended a reproducer, but it includes the used jars from my project, therefor it is pretty large. If a minimal reproducer is needed I can try to provide one in the next days.
In the reproducer there are two shell scripts, that should show the issue I'm facing. When executing the d8 script all does fine, when executing the r8 script it fails with the exception mentioned above.
Kind regards,
Sebastian
na...@google.com <na...@google.com> #4
Having java.lang.Object
in your inputs is not really a supported use-case for R8. What is your use case here? Are you building some kind of custom Android system image? If you are building a regular Android app, you should usually not put java.*
types in your APK and they will never be used anyway. The system will take the java.lang.Object
from the bootclasspath and not the one in your app.
That said, it is indeed interesting that the desugaring goes wrong here. Filtering out all the java/android classes in the input and adding android.jar as --lib input and running R8 with assertions enabled, here is the stack trace:
Error: java.lang.AssertionError
Compilation failed with an internal error.
Exception in thread "main" java.lang.RuntimeException: com.android.tools.r8.CompilationFailedException: Compilation failed to complete
at com.android.tools.r8.utils.ExceptionUtils.withMainProgramHandler(ExceptionUtils.java:189)
at com.android.tools.r8.R8.main(R8.java:1125)
at com.android.tools.r8.SwissArmyKnife.main(SwissArmyKnife.java:63)
Caused by: com.android.tools.r8.CompilationFailedException: Compilation failed to complete
at Version.fakeStackEntry(Version_main.java:0)
at com.android.tools.r8.utils.ExceptionUtils.failWithFakeEntry(ExceptionUtils.java:139)
at com.android.tools.r8.utils.ExceptionUtils.failCompilation(ExceptionUtils.java:89)
at com.android.tools.r8.utils.ExceptionUtils.withCompilationHandler(ExceptionUtils.java:83)
at com.android.tools.r8.utils.ExceptionUtils.withR8CompilationHandler(ExceptionUtils.java:69)
at com.android.tools.r8.R8.run(R8.java:1109)
at com.android.tools.r8.R8.lambda$main$26(R8.java:1125)
at com.android.tools.r8.utils.ExceptionUtils.withMainProgramHandler(ExceptionUtils.java:186)
... 2 more
Caused by: java.lang.AssertionError
at com.android.tools.r8.utils.collections.DexClassAndMethodSetBase.add(DexClassAndMethodSetBase.java:38)
at com.android.tools.r8.shaking.Enqueuer.addToPendingDesugaring(Enqueuer.java:3839)
at com.android.tools.r8.shaking.Enqueuer.traceNonDesugaredCode(Enqueuer.java:4609)
at com.android.tools.r8.shaking.Enqueuer.markMethodAsLive(Enqueuer.java:4553)
at com.android.tools.r8.shaking.EnqueuerWorklist$MarkMethodLiveAction.run(EnqueuerWorklist.java:166)
at com.android.tools.r8.shaking.Enqueuer.trace(Enqueuer.java:4213)
at com.android.tools.r8.shaking.Enqueuer.traceApplication(Enqueuer.java:3496)
at com.android.tools.r8.R8.runEnqueuer(R8.java:1015)
at com.android.tools.r8.R8.run(R8.java:372)
at com.android.tools.r8.R8.run(R8.java:258)
at com.android.tools.r8.R8.lambda$run$25(R8.java:1110)
at com.android.tools.r8.utils.ExceptionUtils.withCompilationHandler(ExceptionUtils.java:80)
... 6 more
We should have a look at that and figure out what is going on there.
Description
saveable
has built-in support for Coroutines'MutableStateFlow
, supporting the following use case:It does this by providing an overloaded function that handles
MutableStateFlow.value
and serializes it when needed.To help people migrate from
saveable
tosaved
, we want to supportMutableStateFlow
in our KotlinX serialization support.While working on getMutableStateFlow CL, I experimented with this idea and created a naive
KSerializer
implementation to handleMutableStateFlow
.Here’s what it could look like:
For serialization, we would use
(value as MutableStateFlow<T>).value
+valueSerializer
to serialize the content. Deserialization works in the opposite direction.Here’s a usage example:
However, calling this without the serializer would cause an exception.
Our variant should work like
saveable
: ifT
(the generic type insaved
) is serializable, it should work without needing the serializer.The goal is to find the best way to support
MutableStateFlow
insaved
.Related to b/378895074 .