Fixed
Status Update
Comments
se...@google.com <se...@google.com> #2
Thank you for this feedback. The team may reach out for more information on triaging or reproducing this issue.
yb...@google.com <yb...@google.com> #3
I have tried the example project you've provided, it does not reproduce.
Could you please try running with -Pandroid.useDexArchive=false? This disables the new dexing pipeline, and fallbacks to the old one.
Could you please try running with -Pandroid.useDexArchive=false? This disables the new dexing pipeline, and fallbacks to the old one.
yb...@google.com <yb...@google.com> #4
@Mario Did you get a chance to try the build with -Pandroid.useDexArchive=false flag?
yb...@google.com <yb...@google.com> #5
I'm the college of @Mario and I make it work without issues and without using -Pandroid.useDexArchive=false by using alpha6 and removing retrolambda
da...@gmail.com <da...@gmail.com> #6
Sorry my comment from Apr 21, 2017 12:41PM was wrong.
With -Pandroid.useDexArchive=false it looks like this
:app:transformClassesWithDesugarForNonpayItalyCompatDebugAndroidTest
:app:transformClassesWithPreDexForNonpayItalyCompatDebugAndroidTest
Dex: warning: Ignoring InnerClasses attribute for an anonymous inner class
(org.ccil.cowan.tagsoup.Parser$1) that doesn't come with an
associated EnclosingMethod attribute. This class was probably produced by a
compiler that did not target the modern .class file format. The recommended
solution is to recompile the class from source, using an up-to-date compiler
and without specifying any "-target" type options. The consequence of ignoring
this warning is that reflective operations on this class will incorrectly
indicate that it is *not* an inner class.
:app:transformDexWithDexForNonpayItalyCompatDebugAndroidTest FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:transformDexWithDexForNonpayItalyCompatDebugAndroidTest'.
> com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: java.util.concurrent.ExecutionException: com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536
With -Pandroid.useDexArchive=false it looks like this
:app:transformClassesWithDesugarForNonpayItalyCompatDebugAndroidTest
:app:transformClassesWithPreDexForNonpayItalyCompatDebugAndroidTest
Dex: warning: Ignoring InnerClasses attribute for an anonymous inner class
(org.ccil.cowan.tagsoup.Parser$1) that doesn't come with an
associated EnclosingMethod attribute. This class was probably produced by a
compiler that did not target the modern .class file format. The recommended
solution is to recompile the class from source, using an up-to-date compiler
and without specifying any "-target" type options. The consequence of ignoring
this warning is that reflective operations on this class will incorrectly
indicate that it is *not* an inner class.
:app:transformDexWithDexForNonpayItalyCompatDebugAndroidTest FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:transformDexWithDexForNonpayItalyCompatDebugAndroidTest'.
> com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: java.util.concurrent.ExecutionException: com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536
yb...@google.com <yb...@google.com> #7
We updated our example repo https://github.com/originx/Gradle_troubles_android_enteprise where you can see the issue.
Just run
./gradlew spoonGermanyDebugAndroidTest
or
./gradlew spoonGermanyDebugAndroidTest -Pandroid.useDexArchive=false
and you will see the issue
Just run
./gradlew spoonGermanyDebugAndroidTest
or
./gradlew spoonGermanyDebugAndroidTest -Pandroid.useDexArchive=false
and you will see the issue
ap...@google.com <ap...@google.com> #8
Your tests do not fit into a single dex file. I've tried plugin 2.3.0 (I've also had to enable retrolambda for app, core, and pay modules), and the number of references that are generated is higher than 64k.
Please note that if you are using plugin's internal or Retrolamba support for Java 8 language features, for each lambda expression you will generate 3 additional references, so it might affect your reference count quite significantly.
Please note that if you are using plugin's internal or Retrolamba support for Java 8 language features, for each lambda expression you will generate 3 additional references, so it might affect your reference count quite significantly.
Description
Version used: 2.2.0-alpha01
Devices/Android versions reproduced on: Android 9
I'm having some random crashes due to CoroutineLiveData
```
Fatal Exception: java.lang.IllegalArgumentException: This source was already added with the different observer
at androidx.lifecycle.MediatorLiveData.addSource + 89(MediatorLiveData.java:89)
at androidx.lifecycle.CoroutineLiveDataKt.addDisposableSource + 102(CoroutineLiveDataKt.java:102)
at androidx.lifecycle.CoroutineLiveData.emitSource$lifecycle_livedata_ktx_release + 200(CoroutineLiveData.java:200)
at androidx.lifecycle.LiveDataScopeImpl$emitSource$2.invokeSuspend + 89(LiveDataScopeImpl.java:89)
at androidx.lifecycle.LiveDataScopeImpl$emitSource$2.invoke(LiveDataScopeImpl.java:11)
at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn + 91(UndispatchedKt.java:91)
at kotlinx.coroutines.BuildersKt__Builders_commonKt.withContext + 156(BuildersKt__Builders_commonKt.java:156)
at kotlinx.coroutines.BuildersKt.withContext + 1(BuildersKt.java:1)
at androidx.lifecycle.LiveDataScopeImpl.emitSource + 88(LiveDataScopeImpl.java:88)
at com.geekorum.ttrss.articles_list.FeedsViewModel$refreshed$1.invokeSuspend + 90(FeedsViewModel.java:90)
at com.geekorum.ttrss.articles_list.FeedsViewModel$refreshed$1.invoke(FeedsViewModel.java:8)
at androidx.lifecycle.BlockRunner$maybeRun$1.invokeSuspend + 147(BlockRunner.java:147)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith + 33(BaseContinuationImpl.java:33)
at kotlinx.coroutines.DispatchedTask.run + 241(DispatchedTask.java:241)
at android.os.Handler.handleCallback + 873(Handler.java:873)
at android.os.Handler.dispatchMessage + 99(Handler.java:99)
at android.os.Looper.loop + 193(Looper.java:193)
at android.app.ActivityThread.main + 6898(ActivityThread.java:6898)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run + 537(RuntimeInit.java:537)
at com.android.internal.os.ZygoteInit.main + 858(ZygoteInit.java:858)
```
From what I understand of CoroutineLiveData source code, when calling `LiveDataScope.emitSource()` the previous source is removed before adding the new one on MediatorLiveData.
```
@MainThread
internal fun emitSource(source: LiveData<T>): DisposableHandle {
clearSource()
val newSource = addDisposableSource(source)
emittedSource = newSource
return newSource
}
```
However the removing is done by launching a new coroutine
```
internal fun <T> MediatorLiveData<T>.addDisposableSource(
source: LiveData<T>
): DisposableHandle {
val disposed = AtomicBoolean(false)
addSource(source) {
if (!disposed.get()) {
value = it
} else {
removeSource(source)
}
}
return object : DisposableHandle {
override fun dispose() {
if (disposed.compareAndSet(false, true)) {
CoroutineScope(Dispatchers.Main).launch {
removeSource(source)
}
}
}
}
}
```
So there is no guarantee that `MediatorLiveData.addSource()` will be called after the removing coroutine is executed. This leads to the IllegalArgumentException in `MediatorLiveData.addSource()`
```
@MainThread
public <S> void addSource(@NonNull LiveData<S> source, @NonNull Observer<? super S> onChanged) {
Source<S> e = new Source<>(source, onChanged);
Source<?> existing = mSources.putIfAbsent(source, e);
if (existing != null && existing.mObserver != onChanged) {
throw new IllegalArgumentException(
"This source was already added with the different observer");
}
if (existing != null) {
return;
}
if (hasActiveObservers()) {
e.plug();
}
}
```