Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dotnet new mauilib redistributes guava-listenablefuture.jar #1312

Closed
jonathanpeppers opened this issue Dec 20, 2021 · 10 comments · Fixed by #1313
Closed

dotnet new mauilib redistributes guava-listenablefuture.jar #1312

jonathanpeppers opened this issue Dec 20, 2021 · 10 comments · Fixed by #1313

Comments

@jonathanpeppers
Copy link
Member

If you do:

$ mkdir foo ; cd foo
$ dotnet new mauilib
$ dotnet pack

You get a weird .jar file included in your library:

image

I tracked this down to here:

<ItemGroup>
<AndroidJavaLibrary Include="$(MSBuildThisFileDirectory)..\..\jar\*.jar" />
</ItemGroup>

I believe this needs to check Condition=" '$(AndroidApplication)' == 'true' ", same as:

https://github.com/xamarin/AndroidX/blob/ef55d3c8c31c322fedf7fd328afc58ea576035ce/source/AndroidXTargets.cshtml#L51-L53

@jonathanpeppers
Copy link
Member Author

jonathanpeppers commented Dec 20, 2021

@jpobst / @moljac I can fix this, is Guava one of the NuGet packages that moved to the AndroidX repo?

@moljac
Copy link
Member

moljac commented Dec 20, 2021

@jpobst / @moljac I can fix this, is Guava one of the NuGet packages that moved to the AndroidX repo?

yes

https://github.com/xamarin/AndroidX/tree/template-sets-guava

but I am having issues with binderator limitations and guava versioning (binderator wants 9999.0-empty-to-avoid-conflict-with-guava, but our bindings were against 1.0)

@filipnavara
Copy link

binderator wants 9999.0-empty-to-avoid-conflict-with-guava, but our bindings were against 1.0

That's already discussed to no end in xamarin/GooglePlayServicesComponents#379.

I assume it would make sense to create the "empty" 9999.0-empty-to-avoid-conflict-with-guava NuGet for parity with what Google does in the Maven world. I am not sure what are the NuGet rules for version upgrading though and whether it would lead to inadvertently consuming this version of the asset. Alternatively you could probably introduce some property to force any version of Xamarin.Android.Guava.ListenableFuture [from now on] to be no-op. Then use this new property in dependencies instead of the 9999.0-empty-to-avoid-conflict-with-guava package version.

@moljac
Copy link
Member

moljac commented Dec 20, 2021

@filipnavara I am afraid that would be ABI breakage, because it was built against 1.0 which is full API (correct me if I am wrong)

https://github.com/xamarin/XamarinComponents/blob/main/Android/Guava/build.cake#L8

@filipnavara
Copy link

My idea was to build both 1.0.x NuGet like you do now but also the manually build the fake empty 9999.0-empty-to-avoid-conflict-with-guava version of the NuGet and publish both. I am not particularly familiar with Bindinator and NuGet versioning rules so it's quite possible that I am missing something important here.

It's an orthogonal, but related, to this issue though. One can already fake the reference to 9999.0-empty-to-avoid-conflict-with-guava with <PackageReference Include="Xamarin.Android.Guava.ListenableFuture" ExcludeAssets="build;buildTransitive" />. First problem with that approach is that it doesn't work transitively so it's not really usable for libraries. Second problem is that now we have plenty of unrelated packages distributing the ListenableFuture.aar asset which is tracked in this issue. It needs to be fixed prior to any solution to the problem with the 9999 version, otherwise you will still get the ListenableFuture.aar anyway from unrelated NuGet packages.

@moljac
Copy link
Member

moljac commented Dec 20, 2021

binderator analyzes POM files and determines dependencies

Guava bindings were done manually, so v1.0 was chosen (why? I can only guess, most likely with best intentions).

Google leaves an option to pick, so we could do that only I am breaking my head how to build both 1.0 and 9999 with binderator AND leave 1.0 as dependency for packages.

jonathanpeppers added a commit to jonathanpeppers/XamarinComponents that referenced this issue Dec 21, 2021
Fixes: xamarin#1312

If you do:

    $ mkdir foo ; cd foo
    $ dotnet new mauilib
    $ dotnet pack

You end up redistributing `com.google.common.util.concurrent.ListenableFuture`
in your MAUI class library NuGet package:

* `foo.1.0.0.nupkg`
    * `lib\net6.0-android31.0\foo.aar`
        * `libs\78C2212B1AE12Ed.jar`
            * `com\google\common\util\concurrent\ListenableFuture.class`

I tracked this down to here:

https://github.com/xamarin/XamarinComponents/blob/3a9b39733fbd5a5359386ccecbd5f890eb391b1f/Android/Guava/source/Guava.ListenableFuture/Guava.ListenableFuture.targets#L3-L5

I believe this needs to check `'$(AndroidApplication)' == 'true'`,
same as we do in AndroidX:

https://github.com/xamarin/AndroidX/blob/ef55d3c8c31c322fedf7fd328afc58ea576035ce/source/AndroidXTargets.cshtml#L51-L53

Let's fix this one package for now, and it might be worth auditing
other packages in this repo later on.
jonathanpeppers added a commit that referenced this issue Dec 21, 2021
Fixes: #1312

If you do:

    $ mkdir foo ; cd foo
    $ dotnet new mauilib
    $ dotnet pack

You end up redistributing `com.google.common.util.concurrent.ListenableFuture`
in your MAUI class library NuGet package:

* `foo.1.0.0.nupkg`
    * `lib\net6.0-android31.0\foo.aar`
        * `libs\78C2212B1AE12Ed.jar`
            * `com\google\common\util\concurrent\ListenableFuture.class`

I tracked this down to here:

https://github.com/xamarin/XamarinComponents/blob/3a9b39733fbd5a5359386ccecbd5f890eb391b1f/Android/Guava/source/Guava.ListenableFuture/Guava.ListenableFuture.targets#L3-L5

I believe this needs to check `'$(AndroidApplication)' == 'true'`,
same as we do in AndroidX:

https://github.com/xamarin/AndroidX/blob/ef55d3c8c31c322fedf7fd328afc58ea576035ce/source/AndroidXTargets.cshtml#L51-L53

Let's fix this one package for now, and it might be worth auditing
other packages in this repo later on.
jonathanpeppers added a commit to jonathanpeppers/AndroidX that referenced this issue Dec 21, 2021
Context: xamarin/XamarinComponents#1312
Context: xamarin/XamarinComponents@0874b32
Context: https://www.nuget.org/packages/Xamarin.Google.Guava.FailureAccess/1.0.1.5
Context: https://www.nuget.org/packages/Xamarin.Google.Guava.ListenableFuture/1.0.0.5

If you do:

    $ mkdir foo ; cd foo
    $ dotnet new mauilib
    $ dotnet pack

You end up redistributing `com.google.common.util.concurrent.ListenableFuture`
in your MAUI class library NuGet package:

* `foo.1.0.0.nupkg`
    * `lib\net6.0-android31.0\foo.aar`
        * `libs\78C2212B1AE12Ed.jar`
            * `com\google\common\util\concurrent\ListenableFuture.class`

This was fixed in XamarinComponents and pushed to NuGet.org, but we
need to update the AndroidX dependencies for the new versions.
@Mephisztoe
Copy link

I am working with .NET MAUI and recently migrated from Preview 14 to the current RC1 branch. When trying to compile my app, I get an error that also references listenablefuture.class... is this in any way connected to the issue discussed here?

This is my build output:
Rebuild started...
1>------ Rebuild All started: Project: SIT, Configuration: Debug Any CPU ------
Restored C:\Users*\source\repos\\SIT\SIT.csproj (in 1,67 sec).
1>You are using a preview version of .NET. See: https://aka.ms/dotnet-core-preview
1>C:\Users\
\source\repos\\SIT\Code\Helpers\ObservableRangeCollection.cs(150,90,150,91): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
1>SIT -> C:\Users\
\source\repos\\SIT\bin\Debug\net6.0-android\SIT.dll
1>Exception in thread "main" java.lang.RuntimeException: com.android.tools.r8.CompilationFailedException: Compilation failed to complete, origin: C:\Users\
.nuget\packages\xamarin.google.guava.listenablefuture\1.0.0.5\buildTransitive\net6.0-android31.0....\jar\guava-listenablefuture.jar:com/google/common/util/concurrent/ListenableFuture.class
1> at com.android.tools.r8.internal.oO0.a(SourceFile:92)
1> at com.android.tools.r8.D8.main(D8.java:4)
1>Caused by: com.android.tools.r8.CompilationFailedException: Compilation failed to complete, origin: C:\Users\
.nuget\packages\xamarin.google.guava.listenablefuture\1.0.0.5\buildTransitive\net6.0-android31.0....\jar\guava-listenablefuture.jar:com/google/common/util/concurrent/ListenableFuture.class
1> at Version.fakeStackEntry(Version_3.1.51.java:0)
1> at com.android.tools.r8.internal.oO0.a(SourceFile:68)
1> at com.android.tools.r8.internal.oO0.a(SourceFile:28)
1> at com.android.tools.r8.internal.oO0.a(SourceFile:27)
1> at com.android.tools.r8.internal.oO0.b(SourceFile:3)
1> at com.android.tools.r8.D8.a(D8.java:17)
1> at com.android.tools.r8.D8.a(D8.java:15)
1> at com.android.tools.r8.internal.oO0.a(SourceFile:84)
1> ... 1 more
1>Caused by: com.android.tools.r8.internal.b: Type com.google.common.util.concurrent.ListenableFuture is defined multiple times: C:\Users\
.nuget\packages\xamarin.google.guava.listenablefuture\1.0.0.5\buildTransitive\net6.0-android31.0....\jar\guava-listenablefuture.jar:com/google/common/util/concurrent/ListenableFuture.class, obj\Debug\net6.0-android\lp\159\jl\libs\31DC00DFF80FA577.jar:com/google/common/util/concurrent/ListenableFuture.class
1> at com.android.tools.r8.internal.il1.a(SourceFile:14)
1> at com.android.tools.r8.internal.il1.a(SourceFile:22)
1> at com.android.tools.r8.internal.lf1.b(SourceFile:6)
1> at com.android.tools.r8.internal.lf1.a(SourceFile:23)
1> at com.android.tools.r8.internal.lf1.a(SourceFile:10)
1> at java.base/java.util.concurrent.ConcurrentHashMap.merge(ConcurrentHashMap.java:2048)
1> at com.android.tools.r8.internal.lf1.a(SourceFile:6)
1> at com.android.tools.r8.graph.r2$a.f(SourceFile:4)
1> at com.android.tools.r8.dex.b.a(SourceFile:96)
1> at com.android.tools.r8.dex.b.a(SourceFile:21)
1> at com.android.tools.r8.D8.a(D8.java:21)
1> at com.android.tools.r8.D8.d(D8.java:11)
1> at com.android.tools.r8.D8.c(D8.java:1)
1> at com.android.tools.r8.internal.oO0.a(SourceFile:24)
1> ... 5 more
1>C:\Program Files\dotnet\packs\Microsoft.Android.Sdk.Windows\32.0.300-rc.1.4\tools\Xamarin.Android.D8.targets(79,5): error : java.lang.RuntimeException: com.android.tools.r8.CompilationFailedException: Compilation failed to complete, origin: C:\Users\
*.nuget\packages\xamarin.google.guava.listenablefuture\1.0.0.5\buildTransitive\net6.0-android31.0....\jar\guava-listenablefuture.jar : com/google/common/util/concurrent/ListenableFuture.class
1>Done building project "SIT.csproj" -- FAILED.
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========

@Csaba8472
Copy link

@Mephisztoe I have the same issue, have you found any solution?

@jonathanpeppers
Copy link
Member Author

@Mephisztoe @Csaba8472 it probably means one of your dependencies was built with an older Xamarin.Google.Guava.ListenableFuture, and it needs to be rebuilt now. You probably have a package that "accidentially" redistributed that .jar and the app ends up with two.

@Csaba8472
Copy link

Csaba8472 commented Apr 15, 2022

I'm working on a MAUI app which needs Microsoft.Identity.Client. Before rc1 it worked properly with my modifications, and as you've written after I've rebuilt Xamarin.Google.Guava.ListenableFuture and added to the project it works again. Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants