-
Notifications
You must be signed in to change notification settings - Fork 63
Description
TL:DR - Fixes
If you are seeing a Java compilation error of the form:
Type androidx.lifecycle.DispatchQueue is defined multiple times: ...
Type kotlin.internal.jdk7.JDK7PlatformImplementations is defined multiple times: ...
Type androidx.collection.ArrayMapKt is defined multiple times: ...
Solution 1
This may be fixable by simply updating your NuGet packages to the latest. This is the preferred solution.
Solution 2
This solution adds an explicit <PackageReference> to the needed transitive package version.
Note: You will need to use versions that match the version of the primary package that is referenced.
If the problematic type starts with androidx.lifecycle, add this to your csproj:
<!-- Should match version of the referenced 'Xamarin.AndroidX.Activity' package -->
<PackageReference Include="Xamarin.AndroidX.Activity.Ktx" Version="1.7.2.1" />
If the problematic type starts with kotlin.internal.jdk7 or kotlin.internal.jdk8, add this to your csproj:
<!-- Should match version of the referenced 'Xamarin.Kotlin.StdLib' package -->
<PackageReference Include="Xamarin.Kotlin.StdLib.Jdk8" Version="1.9.0.1" />
If the problematic type starts with androidx.collection, add this to your csproj:
<!-- Should match version of the referenced 'Xamarin.AndroidX.Collection' package -->
<PackageReference Include="Xamarin.AndroidX.Collection.Jvm" Version="1.4.0.1" />
<PackageReference Include="Xamarin.AndroidX.Collection.Ktx" Version="1.4.0.1" />
How did we get here?
Let's take androidx.lifecycle.DispatchQueue as an example.
The type has always existed in the Java package androidx.lifecycle.lifecycle-runtime-ktx. However, with the 2.6.0 release, Android moved this type to the androidx.lifecycle.lifecycle-common Java package. This is fine if you reference matching versions of the NuGet packages:
<PackageReference Include="Xamarin.AndroidX.Lifecycle.Common" Version="2.6.1.3" /><PackageReference Include="Xamarin.AndroidX.Lifecycle.Runtime.Ktx" Version="2.6.1.3" />
However, because these dependencies are referenced by other packages, and NuGet resolves transitive dependencies to the lowest version that satisfies the requirement, you can end up with mismatched references like:
<PackageReference Include="Xamarin.AndroidX.Lifecycle.Common" Version="2.6.1.3" /><PackageReference Include="Xamarin.AndroidX.Lifecycle.Runtime.Ktx" Version="2.5.1.1" />
This is not fine, as both packages contain the androidx.lifecycle.DispatchQueue type, resulting in the type being duplicated:
java.exe error JAVA0000: Type androidx.lifecycle.DispatchQueue is defined multiple times:
C:\.tools\.nuget\packages\xamarin.androidx.lifecycle.common\2.6.1.3\buildTransitive\net6.0-android31.0\..\..\jar\androidx.lifecycle.lifecycle-common.jar:androidx/lifecycle/DispatchQueue.class,
obj\Release\net7.0-android\lp\139\jl\classes.jar:androidx/lifecycle/DispatchQueue.class
Specifically, in MAUI, this occurs because MAUI references Xamarin.AndroidX.Navigation.Common 2.5.2.1, which references Xamarin.AndroidX.Lifecycle.Runtime.Ktx 2.5.1.1:
<PackageReference Include="Xamarin.AndroidX.Navigation.Common" Version="2.5.2.1" />
-> Xamarin.AndroidX.Lifecycle.Runtime.Ktx (>= 2.5.1.1)
And the user adds a package like Xamarin.AndroidX.Activity 1.7.2.1 which eventually references Xamarin.AndroidX.Lifecycle.Common 2.6.1.3:
<PackageReference Include="Xamarin.AndroidX.Activity" Version="1.7.2.1" />
-> Xamarin.AndroidX.Lifecycle.Runtime (>= 2.6.1.3)
-> Xamarin.AndroidX.Lifecycle.Common (>= 2.6.1.3)
How does Java/Maven handle this?
Java/Maven avoids this issue by requiring an exact version match between androidx.lifecycle.lifecycle-runtime-ktx and androidx.lifecycle.lifecycle-common. That is, the POM file for androidx.lifecycle.lifecycle-runtime-ktx lists its dependency as:
<!-- lifecycle-runtime-ktx-2.6.1.pom -->
<dependency>
<groupId>androidx.lifecycle</groupId>
<artifactId>lifecycle-runtime</artifactId>
<version>[2.6.1]</version>
<scope>compile</scope>
<type>aar</type>
</dependency>The square brackets ([]) denote an exact match, rather than a greater than or equal match.
Our NuGet packages allow greater than or equal match, which allows the version to incorrectly differ from each other.
Long-term fix
In order to handle this long-term and help prevent this issue from recurring when other types move in the future, we need to duplicate Java/Maven's "exact match".
Unfortunately, publishing fixed packages will not make this error go away yet, because the fixed package needs to be referenced by MAUI. After fixed packages are published, MAUI will need to reference them and make a new release.
Thus, we will be living with the issue for a while.
Caveats
Using "exact match" versions will fix the androidx.lifecycle case (and potential future cases), but it will not fix the kotlin.internal case, as the Kotlin POM does not specify an "exact match" for this case:
<!-- kotlin-stdlib-jdk8-1.9.0.pom -->
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>1.9.0</version>
<scope>compile</scope>
</dependency>Original Details
Certain PackageReference constellations can cause 2 errors:
- type XYZ is defined multiples times
or - packages generated by more than one managed type
Basically, the problem is that maven package authors (Google, JetBrains) move types from version to version, from Maven artifact to another Maven artifact. So, in rare cases even trivial transitive dependencies cause such errors if nugets transitively reference nugets with bindings where the same type rasides, but under different version.
Team does publish "alingment bumps" to put transitive dependencies "in order", but probability for hitting these issues is still high on real world projects, especially with 3rd party libraries that depend on older AndroidX and GooglePlayServices-Firebase-MLKit (not regularly updated).
Workaround steps:
- update AndroidX and GooglePlayServices-Firebase-MLKit to the latest
sometimes updating AndroidX 1st could help, but recommendation is to update allPackageReferences - some users report that they had to close Visual Studio (IDE) and delete
bin/andobjfolders, restore and then build
If you still encounter these issues open issue in AndroidX and/or GooglePlayServices-Firebase-MLKit repos and please add list of PackageRererences.
Related/Duplicates:
This issue is project specific (PackagesReferences dependent), so finding workaround is based on experience.
Finding newer issues - search for;
Error JAVA0000 java.exe: Error in Type androidx.collection.ArrayMapKt is defined multiple times
Thus list of the similar issues:
AX (AndroidX)
GPS-FB-MLKit (GooglePlayServices, Firebase, ML Kit)
xamarin/GooglePlayServicesComponents#909
xamarin/GooglePlayServicesComponents#898
xamarin/GooglePlayServicesComponents#897
xamarin/GooglePlayServicesComponents#889
xamarin/GooglePlayServicesComponents#852
xamarin/GooglePlayServicesComponents#825
xamarin/GooglePlayServicesComponents#475
xamarin/GooglePlayServicesComponents#379
MAUI
Diverse (Plugins)
More references
firebase/firebase-android-sdk#5997
firebase/firebase-android-sdk#5999
Steps to Reproduce
N/A
Did you find any workaround?
Workaround steps:
- update AndroidX and GooglePlayServices-Firebase-MLKit to the latest
sometimes updating AndroidX 1st could help, but recommendation is to update allPackageReferences - some users report that they had to close Visual Studio (IDE) and delete
bin/andobjfolders, restore and then build
Relevant log output
see related issues