Skip to content

Fixing: Type XYZ is defined multiple times || packages generated by more than one managed type #764

@moljac

Description

@moljac

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:

  1. update AndroidX and GooglePlayServices-Firebase-MLKit to the latest
    sometimes updating AndroidX 1st could help, but recommendation is to update all PackageReferences
  2. some users report that they had to close Visual Studio (IDE) and delete bin/ and obj folders, 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)

#1127

#1068

#938

#935

#926

#918

#861

#805

#800

#797

#793

#788

#752

#749

#747

#742

#717

#634

#525

#509

#505

#756 (comment)

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

dotnet/android#9698

dotnet/maui#26963

dotnet/maui#25261

dotnet/maui#20561

dotnet/maui#18665

dotnet/maui#18118

dotnet/maui#17935

dotnet/maui#16448

dotnet/maui#14954

dotnet/maui#11353 (comment)

Diverse (Plugins)

marcojak/MauiMTAdmob#113

More references

https://stackoverflow.com/questions/77487528/net-maui-push-notifications-with-firebase-cloud-mesaging

firebase/firebase-android-sdk#5997

firebase/firebase-android-sdk#5999

https://stackoverflow.com/questions/66344110/r8-says-type-is-defined-multiple-times-in-build-transforms-and-in-build-tmp-ko/

Steps to Reproduce

N/A

Did you find any workaround?

Workaround steps:

  1. update AndroidX and GooglePlayServices-Firebase-MLKit to the latest
    sometimes updating AndroidX 1st could help, but recommendation is to update all PackageReferences
  2. some users report that they had to close Visual Studio (IDE) and delete bin/ and obj folders, restore and then build

Relevant log output

see related issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions