dotnet / android

.NET for Android provides open-source bindings of the Android SDK for use with .NET managed languages such as C#
MIT License
1.93k stars 528 forks source link

CheckDuplicateJavaLibraries: error XA1014: JAR library references with identical file names but different contents were found: repackaged.jar #8326

Closed kenneththorman closed 9 months ago

kenneththorman commented 1 year ago

Android application type

Classic Xamarin.Android (MonoAndroid12.0, etc.)

Affected platform version

VS2022 17.7.3+34024.191, Xamarin17.7.0.216, Xamarin.Android SDK13.2.1.2

Description

In an Android project referencing the following

Building the project fails with

"error XA1014: JAR library references with identical file names but different contents were found: repackaged.jar. Please remove any conflicting libraries from EmbeddedJar, InputJar and AndroidJavaLibrary."

Steps to Reproduce

  1. Create a new Android application
  2. Add the Nuget package Xamarin.AndroidX.Emoji2
  3. Add a new Jar library binding project that in the Jars folder contains the https://dl.google.com/dl/android/maven2/androidx/health/connect/connect-client/1.1.0-alpha04/connect-client-1.1.0-alpha04.aar file (Build action: LibraryProjectZip)
  4. Add the following content to Transforms/Metadata.xml

    
    <!--
    This sample removes the class: android.support.v4.content.AsyncTaskLoader.LoadTask:
    <remove-node path="/api/package[@name='android.support.v4.content']/class[@name='AsyncTaskLoader.LoadTask']" />
    
    This sample removes the method: android.support.v4.content.CursorLoader.loadInBackground:
    <remove-node path="/api/package[@name='android.support.v4.content']/class[@name='CursorLoader']/method[@name='loadInBackground']" />
    -->
    <remove-node path="/api/package[starts-with (@name, 'androidx.health.platform')]" />
    <add-node path="/api/package[@name='androidx.health.connect.client.units']/class[@name='Length']">
    <method name="compareTo" return="int" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public">
    <parameter name="p0" type="java.lang.Object"/>
    </method>
    </add-node>
    <add-node path="/api/package[@name='androidx.health.connect.client.units']/class[@name='BloodGlucose']">
    <method name="compareTo" return="int" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public">
    <parameter name="p0" type="java.lang.Object"/>
    </method>
    </add-node>
    <add-node path="/api/package[@name='androidx.health.connect.client.units']/class[@name='Mass']">
    <method name="compareTo" return="int" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public">
    <parameter name="p0" type="java.lang.Object"/>
    </method>
    </add-node>
    <add-node path="/api/package[@name='androidx.health.connect.client.units']/class[@name='Energy']">
    <method name="compareTo" return="int" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public">
    <parameter name="p0" type="java.lang.Object"/>
    </method>
    </add-node>
    <add-node path="/api/package[@name='androidx.health.connect.client.units']/class[@name='Percentage']">
    <method name="compareTo" return="int" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public">
    <parameter name="p0" type="java.lang.Object"/>
    </method>
    </add-node>
    <add-node path="/api/package[@name='androidx.health.connect.client.units']/class[@name='Power']">
    <method name="compareTo" return="int" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public">
    <parameter name="p0" type="java.lang.Object"/>
    </method>
    </add-node>
    <add-node path="/api/package[@name='androidx.health.connect.client.units']/class[@name='Pressure']">
    <method name="compareTo" return="int" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public">
    <parameter name="p0" type="java.lang.Object"/>
    </method>
    </add-node>
    <add-node path="/api/package[@name='androidx.health.connect.client.units']/class[@name='Velocity']">
    <method name="compareTo" return="int" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public">
    <parameter name="p0" type="java.lang.Object"/>
    </method>
    </add-node>
    <add-node path="/api/package[@name='androidx.health.connect.client.units']/class[@name='Volume']">
    <method name="compareTo" return="int" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public">
    <parameter name="p0" type="java.lang.Object"/>
    </method>
    </add-node>
    <add-node path="/api/package[@name='androidx.health.connect.client.units']/class[@name='Temperature']">
    <method name="compareTo" return="int" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public">
    <parameter name="p0" type="java.lang.Object"/>
    </method>
    </add-node>

_(The transforms may not be needed for the reproducing of this problem, but I have added them to this issue anyway, to speed up the process)_
5. Reference this new Jar library binding project in the main android application
6. Build the Android application

Seems related to :  https://github.com/xamarin/xamarin-android/issues/5627

### Did you find any workaround?

No "nice" workaround found.
A "not-so-nice" workaround exists which requires  renaming the conflicting libs/jar files and recompiling the upstream aar file.

### Relevant log output

```shell
11>Target "_CheckDuplicateJavaLibraries: (TargetId:400)" in file "C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets" from project "D:\Users\Appinux\projects\dialogevent_2\DialogEvent\DialogEvent.Droid\DialogEvent.Droid.csproj" (target "_UpdateAndroidResgen" depends on it):
11>Using "CheckDuplicateJavaLibraries" task from assembly "C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Xamarin\Android\Xamarin.Android.Build.Tasks.dll".
11>Task "CheckDuplicateJavaLibraries" (TaskId:588)
11>  Task Parameter:
11>      JavaLibraries=
11>          D:\Users\Appinux\projects\dialogevent_2\DialogEvent\packages\Xamarin.AndroidX.ConstraintLayout.Core.1.0.1.3\build\monoandroid90\..\..\jar\androidx.constraintlayout.constraintlayout-core.jar
11>                  AndroidXSkipAndroidXMigration=true
11>          D:\Users\Appinux\projects\dialogevent_2\DialogEvent\packages\Xamarin.AndroidX.ConstraintLayout.Solver.2.0.4.2\build\monoandroid9.0\..\..\jar\androidx.constraintlayout.constraintlayout-solver.jar
11>                  AndroidXSkipAndroidXMigration=true
11>          D:\Users\Appinux\projects\dialogevent_2\DialogEvent\packages\Xamarin.AndroidX.Room.Common.2.3.0.6\build\monoandroid12.0\..\..\jar\androidx.room.room-common.jar
11>                  AndroidXSkipAndroidXMigration=true
11>          D:\Users\Appinux\projects\dialogevent_2\DialogEvent\packages\Xamarin.AndroidX.ResourceInspection.Annotation.1.0.1.2\build\monoandroid12.0\..\..\jar\androidx.resourceinspection.resourceinspection-annotation.jar
11>                  AndroidXSkipAndroidXMigration=true
11>          D:\Users\Appinux\projects\dialogevent_2\DialogEvent\packages\Xamarin.Jetbrains.Annotations.24.0.1.1\build\monoandroid12.0\..\..\jar\org.jetbrains.annotations-24.0.1.jar
11>          D:\Users\Appinux\projects\dialogevent_2\DialogEvent\packages\Xamarin.Kotlin.StdLib.Common.1.8.20.1\build\monoandroid12.0\..\..\jar\org.jetbrains.kotlin.kotlin-stdlib-common-1.8.20.jar
11>          D:\Users\Appinux\projects\dialogevent_2\DialogEvent\packages\Xamarin.Kotlin.StdLib.1.8.20.1\build\monoandroid12.0\..\..\jar\org.jetbrains.kotlin.kotlin-stdlib-1.8.20.jar
11>          D:\Users\Appinux\projects\dialogevent_2\DialogEvent\packages\Xamarin.AndroidX.Annotation.1.6.0.1\build\monoandroid12.0\..\..\jar\androidx.annotation.annotation.jar
11>                  AndroidXSkipAndroidXMigration=true
11>          D:\Users\Appinux\projects\dialogevent_2\DialogEvent\packages\Xamarin.AndroidX.Arch.Core.Common.2.2.0.1\build\monoandroid12.0\..\..\jar\androidx.arch.core.core-common.jar
11>                  AndroidXSkipAndroidXMigration=true
11>          D:\Users\Appinux\projects\dialogevent_2\DialogEvent\packages\Xamarin.AndroidX.Collection.1.2.0.7\build\monoandroid12.0\..\..\jar\androidx.collection.collection.jar
11>                  AndroidXSkipAndroidXMigration=true
11>          D:\Users\Appinux\projects\dialogevent_2\DialogEvent\packages\Xamarin.AndroidX.Concurrent.Futures.1.1.0.12\build\monoandroid12.0\..\..\jar\androidx.concurrent.concurrent-futures.jar
11>                  AndroidXSkipAndroidXMigration=true
11>          D:\Users\Appinux\projects\dialogevent_2\DialogEvent\packages\Xamarin.Kotlin.StdLib.Jdk7.1.8.20.1\build\monoandroid12.0\..\..\jar\org.jetbrains.kotlin.kotlin-stdlib-jdk7-1.8.20.jar
11>          D:\Users\Appinux\projects\dialogevent_2\DialogEvent\packages\Xamarin.Kotlin.StdLib.Jdk8.1.8.20.1\build\monoandroid12.0\..\..\jar\org.jetbrains.kotlin.kotlin-stdlib-jdk8-1.8.20.jar
11>          D:\Users\Appinux\projects\dialogevent_2\DialogEvent\packages\Xamarin.KotlinX.Coroutines.Core.Jvm.1.6.4.3\build\monoandroid12.0\..\..\jar\org.jetbrains.kotlinx.kotlinx-coroutines-core-jvm-1.6.4.jar
11>          D:\Users\Appinux\projects\dialogevent_2\DialogEvent\packages\Xamarin.KotlinX.Coroutines.Android.1.6.4.3\build\monoandroid12.0\..\..\jar\org.jetbrains.kotlinx.kotlinx-coroutines-android-1.6.4.jar
11>          D:\Users\Appinux\projects\dialogevent_2\DialogEvent\packages\Xamarin.AndroidX.Lifecycle.Common.2.6.1.1\build\monoandroid12.0\..\..\jar\androidx.lifecycle.lifecycle-common.jar
11>                  AndroidXSkipAndroidXMigration=true
11>          D:\Users\Appinux\projects\dialogevent_2\DialogEvent\packages\Xamarin.Android.Google.Code.Gson.2.8.8\build\..\jar\com.google.code.gson.gson.jar
11>          D:\Users\Appinux\projects\dialogevent_2\DialogEvent\packages\Xamarin.CheckerFramework.CheckerQual.3.34.0.1\build\monoandroid12.0\..\..\jar\checker-qual.jar
11>          D:\Users\Appinux\projects\dialogevent_2\DialogEvent\packages\Xamarin.Google.Guava.FailureAccess.1.0.1.11\build\monoandroid12.0\..\..\jar\guava-failureaccess.jar
11>          D:\Users\Appinux\projects\dialogevent_2\DialogEvent\packages\Xamarin.Google.J2Objc.Annotations.2.8.0.3\build\monoandroid12.0\..\..\jar\j2objc-annotations.jar
11>          D:\Users\Appinux\projects\dialogevent_2\DialogEvent\packages\Xamarin.Google.Guava.31.1.0.7\build\monoandroid12.0\..\..\jar\guava.jar (TaskId:588)
11>  Task Parameter:
11>      LibraryProjectJars=
11>          obj\Debug\130\lp\0\jl\androidsvg-1.2.1.jar
11>          obj\Debug\130\lp\1\jl\bin\classes.jar
11>          obj\Debug\130\lp\10\jl\fm.video.jar
11>          obj\Debug\130\lp\100\jl\firebase-encoders-proto.jar
11>          obj\Debug\130\lp\101\jl\bin\classes.jar
11>          obj\Debug\130\lp\102\jl\bin\classes.jar
11>          obj\Debug\130\lp\103\jl\bin\classes.jar
11>          obj\Debug\130\lp\104\jl\bin\classes.jar
11>          obj\Debug\130\lp\105\jl\bin\classes.jar
11>          obj\Debug\130\lp\106\jl\bin\classes.jar
11>          obj\Debug\130\lp\107\jl\bin\classes.jar
11>          obj\Debug\130\lp\108\jl\bin\classes.jar
11>          obj\Debug\130\lp\109\jl\bin\classes.jar
11>          obj\Debug\130\lp\11\jl\GraphView-4.0.0.jar
11>          obj\Debug\130\lp\111\jl\auto-value-annotations.jar
11>          obj\Debug\130\lp\113\jl\error_prone_annotations.jar
11>          obj\Debug\130\lp\116\jl\bin\classes.jar
11>          obj\Debug\130\lp\117\jl\bin\classes.jar
11>          obj\Debug\130\lp\118\jl\bin\classes.jar
11>          obj\Debug\130\lp\119\jl\bin\classes.jar
11>          obj\Debug\130\lp\12\jl\bin\classes.jar
11>          obj\Debug\130\lp\120\jl\bin\classes.jar
11>          obj\Debug\130\lp\121\jl\javax.inject.jar
11>          obj\Debug\130\lp\126\jl\bin\classes.jar
11>          obj\Debug\130\lp\127\jl\bin\classes.jar
11>          obj\Debug\130\lp\127\jl\libs\ogsccommunicationlibrary.jar
11>          obj\Debug\130\lp\127\jl\libs\soniccommunicationlibrary.jar
11>          obj\Debug\130\lp\128\jl\bin\classes.jar
11>          obj\Debug\130\lp\128\jl\libs\repackaged.jar   <---------------------- Emoji2
11>          obj\Debug\130\lp\129\jl\classes.jar
11>          obj\Debug\130\lp\13\jl\jsr305.jar
11>          obj\Debug\130\lp\130\jl\classes.jar
11>          obj\Debug\130\lp\131\jl\classes.jar
11>          obj\Debug\130\lp\132\jl\classes.jar
11>          obj\Debug\130\lp\133\jl\classes.jar
11>          obj\Debug\130\lp\134\jl\classes.jar
11>          obj\Debug\130\lp\135\jl\classes.jar
11>          obj\Debug\130\lp\136\jl\classes.jar
11>          obj\Debug\130\lp\137\jl\classes.jar
11>          obj\Debug\130\lp\138\jl\classes.jar
11>          obj\Debug\130\lp\139\jl\classes.jar
11>          obj\Debug\130\lp\140\jl\classes.jar
11>          obj\Debug\130\lp\141\jl\classes.jar
11>          obj\Debug\130\lp\142\jl\classes.jar
11>          obj\Debug\130\lp\143\jl\classes.jar
11>          obj\Debug\130\lp\144\jl\classes.jar
11>          obj\Debug\130\lp\145\jl\classes.jar
11>          obj\Debug\130\lp\146\jl\classes.jar
11>          obj\Debug\130\lp\147\jl\classes.jar
11>          obj\Debug\130\lp\148\jl\classes.jar
11>          obj\Debug\130\lp\149\jl\classes.jar
11>          obj\Debug\130\lp\150\jl\classes.jar
11>          obj\Debug\130\lp\151\jl\classes.jar
11>          obj\Debug\130\lp\152\jl\classes.jar
11>          obj\Debug\130\lp\153\jl\classes.jar
11>          obj\Debug\130\lp\154\jl\classes.jar
11>          obj\Debug\130\lp\155\jl\classes.jar
11>          obj\Debug\130\lp\156\jl\classes.jar
11>          obj\Debug\130\lp\157\jl\classes.jar
11>          obj\Debug\130\lp\157\jl\libs\repackaged.jar   <---------------------- connect-client1.1-alpha04
11>          obj\Debug\130\lp\158\jl\classes.jar
11>          obj\Debug\130\lp\159\jl\classes.jar
11>          obj\Debug\130\lp\160\jl\classes.jar
11>          obj\Debug\130\lp\161\jl\classes.jar
11>          obj\Debug\130\lp\162\jl\classes.jar
11>          obj\Debug\130\lp\163\jl\classes.jar
11>          obj\Debug\130\lp\164\jl\classes.jar
11>          obj\Debug\130\lp\165\jl\classes.jar
11>          obj\Debug\130\lp\166\jl\classes.jar
11>          obj\Debug\130\lp\167\jl\classes.jar
11>          obj\Debug\130\lp\168\jl\classes.jar
11>          obj\Debug\130\lp\169\jl\classes.jar
11>          obj\Debug\130\lp\170\jl\classes.jar
11>          obj\Debug\130\lp\171\jl\classes.jar
11>          obj\Debug\130\lp\172\jl\classes.jar
11>          obj\Debug\130\lp\173\jl\classes.jar
11>          obj\Debug\130\lp\174\jl\classes.jar
11>          obj\Debug\130\lp\175\jl\classes.jar
11>          obj\Debug\130\lp\176\jl\classes.jar
11>          obj\Debug\130\lp\177\jl\classes.jar
11>          obj\Debug\130\lp\178\jl\classes.jar
11>          obj\Debug\130\lp\179\jl\classes.jar
11>          obj\Debug\130\lp\180\jl\classes.jar
11>          obj\Debug\130\lp\181\jl\classes.jar
11>          obj\Debug\130\lp\182\jl\classes.jar
11>          obj\Debug\130\lp\183\jl\classes.jar
11>          obj\Debug\130\lp\184\jl\classes.jar
11>          obj\Debug\130\lp\185\jl\classes.jar
11>          obj\Debug\130\lp\186\jl\classes.jar
11>          obj\Debug\130\lp\187\jl\classes.jar
11>          obj\Debug\130\lp\188\jl\classes.jar
11>          obj\Debug\130\lp\189\jl\classes.jar
11>          obj\Debug\130\lp\190\jl\classes.jar
11>          obj\Debug\130\lp\191\jl\classes.jar
11>          obj\Debug\130\lp\192\jl\classes.jar
11>          obj\Debug\130\lp\193\jl\classes.jar
11>          obj\Debug\130\lp\194\jl\classes.jar
11>          obj\Debug\130\lp\195\jl\classes.jar
11>          obj\Debug\130\lp\196\jl\classes.jar
11>          obj\Debug\130\lp\197\jl\classes.jar
11>          obj\Debug\130\lp\198\jl\classes.jar
11>          obj\Debug\130\lp\199\jl\classes.jar
11>          obj\Debug\130\lp\200\jl\classes.jar
11>          obj\Debug\130\lp\22\jl\bin\classes.jar
11>          obj\Debug\130\lp\26\jl\libspiromagic0_6_targetsdk29.jar
11>          obj\Debug\130\lp\27\jl\library-1.0.19.jar
11>          obj\Debug\130\lp\28\jl\commons-math3-3.6.1.jar
11>          obj\Debug\130\lp\5\jl\bin\classes.jar
11>          obj\Debug\130\lp\6\jl\fm.audio.jar
11>          obj\Debug\130\lp\94\jl\firebase-annotations.jar
11>          obj\Debug\130\lp\95\jl\bin\classes.jar
11>          obj\Debug\130\lp\96\jl\bin\classes.jar
11>          obj\Debug\130\lp\97\jl\bin\classes.jar
11>          obj\Debug\130\lp\98\jl\firebase-encoders.jar
11>          obj\Debug\130\lp\99\jl\bin\classes.jar (TaskId:588)
11>C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(871,3): error XA1014: JAR library references with identical file names but different contents were found: repackaged.jar. Please remove any conflicting libraries from EmbeddedJar, InputJar and AndroidJavaLibrary.
11>Done executing task "CheckDuplicateJavaLibraries" -- FAILED. (TaskId:588)
11>Done building target "_CheckDuplicateJavaLibraries" in project "DialogEvent.Droid.csproj" -- FAILED.: (TargetId:400)
kenneththorman commented 1 year ago

@jonathanpeppers Based on your previous comment at https://github.com/xamarin/xamarin-android/issues/5627#issuecomment-779880577

This may not be a common problem but it seems that you cannot be certain that aar files only will have files named "classes.jar" inside.

I am not in charge of either of the bindings

So I am not in control of the name of the file "repackaged.jar" (in this case) unless I want to modify the upstream package (which I prefer to not do).

Thank you in advance. Regards Kenneth

kenneththorman commented 1 year ago

For now since I have a deadline looming, I will opt for the route of changing the name of the jar file and recompile the aar file, but this is something that I would prefer to not do, since I do not own the upstream package. It does allow for a lower priority on your end though.

jonathanpeppers commented 1 year ago

The error is:

error XA1014: JAR library references with identical file names but different contents were found: repackaged.jar. Please remove any conflicting libraries from EmbeddedJar, InputJar and AndroidJavaLibrary.

This .aar has libs/repackaged.jar:

https://dl.google.com/dl/android/maven2/androidx/health/connect/connect-client/1.1.0-alpha04/connect-client-1.1.0-alpha04.aar

This also has it xamarin.androidx.emoji2.1.3.0.3.nupkg/aar/androidx.emoji2.emoji2.aar/libs/:

https://www.nuget.org/packages/Xamarin.AndroidX.Emoji2/1.3.0.3

It feels like the XA1014 error should be removed? Or we make it ignore repackaged.jar? @dellis1972 what do you think?

dellis1972 commented 1 year ago

removing XA1014 would result in possible weird crashes at runtime. Its there for a reason. The problem here is repackaged.jar is probably required for both aar files? I think repackaging is probably the best bet. Also raise an issue upstream and try to get them to use a more unique name for that .jar file.

jonathanpeppers commented 1 year ago

They don't seem to mention repackaged.jar as the name of a special file here:

https://developer.android.com/studio/projects/android-library#aar-contents

dellis1972 commented 1 year ago

Its not a special name, its just two different publishers used the same name, that contain different contents.

kenneththorman commented 1 year ago

It would be very nice - if you decide to leave it as it is

  1. if the error details were more specific. Maybe something like
    • "More than one reference/package have internal libraries that do not follow the aar file specification, the packages are package1, package2 ... and the offending filenames are ... . According to the specification, jar files located in the libs folder in aar files should be named "classes.jar". Please contact the package maintainers ..."
  2. if the NuGet repository possibly could catch offending packages in the NuGet approval proces and prevent published packages from breaking this rule

It took a bit of digging to figure out what was wrong, since in the build log you see many duplicated jar filename, they just happen to be named "classes.jar". What caused me to further check before creating this issue was

(many developers are a bit reluctant to question Google, Microsoft offered packages, and then you spend time second guessing yourself)

@dellis1972 I will be showcasing my ignorance but I will ask anyway and appreciate any answer you can give

"removing XA1014 would result in possible weird crashes at runtime",

Why, and why not for classes.jar?

dellis1972 commented 1 year ago

The code in classes.jar is the code compiled for that specific aar. This will generally have a unique package name so you dond't get clashes.

The files in libs are dependencies, so you can totally have two different packages referencing different versions of the same "third party" package. What you then end up with are two different jar files (one from each aar in the libs folder) which contain different code for the same classes/packages. There might be code in the classes.jar which depends on code in the jars in the libs, so if the wrong version is loaded you will see runtime exceptions.

Note in this line https://github.com/xamarin/xamarin-android/blob/336ec802edb628bdcd2f44df74652b0af684effc/src/Xamarin.Android.Build.Tasks/Tasks/CheckDuplicateJavaLibraries.cs#L33C33-L33C55 we check the content of the files not just the filenames. So in this case the repackaged.jar have different contents.

I believe that is why we put this check in to start with, but I'd have to look up the commit and check the commit message to be sure.

jpobst commented 1 year ago

What you then end up with are two different jar files (one from each aar in the libs folder) which contain different code for the same classes/packages.

I think we may be protected against this error with the checks that javac does:

Error JAVA0000 Error in C:\Users\user\.nuget\packages\xamarin.androidx.lifecycle.common\2.6.1.2\buildTransitive\net6.0-android31.0\..\..\jar\androidx.lifecycle.lifecycle-common.jar:androidx/lifecycle/DispatchQueue.class:

Type androidx.lifecycle.DispatchQueue is defined multiple times: 
  C:\Users\user\.nuget\packages\xamarin.androidx.lifecycle.common\2.6.1.2\buildTransitive\net6.0-android31.0\..\..\jar\androidx.lifecycle.lifecycle-common.jar:androidx/lifecycle/DispatchQueue.class, 
  obj\Debug\net7.0-android\lp\136\jl\classes.jar:androidx/lifecycle/DispatchQueue.class

Compilation failed
kenneththorman commented 1 year ago

Responding to: https://github.com/xamarin/xamarin-android/issues/8326#issuecomment-1714291783

@dellis1972 Thank you for your answer

My question was unprecise and is in essence related to the reliance on the filename as deal breaker. The presence of the XA1014 error makes sense (either in implemented in MSBuild or relying on javac as posted in https://github.com/xamarin/xamarin-android/issues/8326#issuecomment-1714368161). The heavy emphasis on filename being the key factor in determining actual conflicting library contents, seems less than ideal.

https://github.com/xamarin/xamarin-android/blob/336ec802edb628bdcd2f44df74652b0af684effc/src/Xamarin.Android.Build.Tasks/Utilities/MonoAndroidHelper.cs#L247-L254

Just changing the filename for libs/repackaged.jar and repackaging client-connect.aar resolved the XA1014 error, which seems to indicate that the filename is indeed the deciding factor. (It is hard to argue that repackaged.jar for Xamarin.Android bindings for AndroidX - emoji2 and Google Health Connect connect-client-1.1-alpha04.aar are real conflicting libraries)

There is a strong argument for rejecting files that do not follow the spec (like in this case "libs/repackaged.jar" https://github.com/xamarin/xamarin-android/issues/8326#issuecomment-1714069000), and for this to happen at the time you build a Java Library Binding project or at the time of approving/publishing a NuGet package (fail fast). Alternatively for at more tolerant approach, to only reject libs/jar files when they indeed have identical namespaced libs where the contents are different, and place less emphasis on the name of the libs jar file since the filename seems to be a poor indication of real conflicting libraries.

jonathanpeppers commented 9 months ago

This should be fixed by: https://github.com/xamarin/xamarin-android/pull/8664

So this will be in .NET 9 Preview 1 and the next .NET 8 servicing release. Going forward you'll be able to add to the @(_AndroidExcludedDuplicateJavaLibraries) item group to ignore errors. We're still deciding if it's worth checking for filenames at all -- historically, it was helpful for customers with duplicate .jar files in class libraries and their app.