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

Working with Guava.ListenableFuture issues #535

Closed
jpobst opened this issue Apr 19, 2022 · 0 comments
Closed

Working with Guava.ListenableFuture issues #535

jpobst opened this issue Apr 19, 2022 · 0 comments

Comments

@jpobst
Copy link
Contributor

jpobst commented Apr 19, 2022

Context: xamarin/XamarinComponents#1365

Due to some recent updates with Xamarin.Google.Guava and Xamarin.Google.Guava.ListenableFuture NuGet packages, projects may being hitting R8 errors that looks something like:

Caused by: com.android.tools.r8.internal.b: Type com.google.common.util.concurrent.ListenableFuture is defined multiple times: 
/Users/imac/.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/132/jl/libs/FCEFAF10B0757418.jar:com/google/common/util/concurrent/ListenableFuture.class

TL;DR

New packages have "escape hatch" MSBuild properties that prevent the NuGet copy of guava.jar or guava-listenablefuture.jar from being added to your project. These may fix the issue if there are not differing versions of guava*.jar packages being pulled in as embedded resources from other binding libraries.

First, ensure the project is using the most recent Guava NuGet package versions by explicitly referencing them:

<PackageReference Include="Xamarin.Google.Guava" Version="31.1.0.1" />
<PackageReference Include="Xamarin.Google.Guava.ListenableFuture" Version="1.0.0.7" />

Instruct the project system to omit the NuGet guava-listenablefuture.jar from the build by adding this property to your .csproj file:

<XamarinGoogleGuavaListenableFutureOptOut>true</XamarinGoogleGuavaListenableFutureOptOut>

If that does not fix the issue, the following line can be tried (with or without the previous property) to omit the NuGet guava.jar:

<XamarinGoogleGuavaOptOut>true</XamarinGoogleGuavaOptOut>

If neither of these properties work, there are likely conflicting versions embedded in binding libraries that are being used. These libraries will need to be updated to the latest Guava packages.

Details

Duplicate Versions of guava.jar

The Xamarin.Google.Guava NuGet was originally configured so that when a binding library referenced it, it would embed a copy of that guava.jar inside the binding library, which is then automatically included in the user's final application (<EmbeddedReferenceJar>). This works fine when all binding libraries that do this reference the same version because the build system detects they are the same and removes the duplicate versions.

However if each binding library references a different version of guava.jar, this creates a problem. Both versions of guava.jar are compiled into the final application, which causes duplicate types to exist, which cause an R8 error.

As of Xamarin.Google.Guava 31.1.0.1, guava.jar is now added to binding libraries as <AndroidJavaLibrary> which does not add an embedded copy of guava.jar to the binding library. Instead, the final application adds the guava.jar from the NuGet.

The long-term fix for this is for the ecosystem of binding libraries to update to the latest version of Guava NuGets so they no longer include embedded guava.jar's.

Unfortunately this may make things worse in the interim. An application that references an "old-style" binding library and a "new-style" library will be getting both the "old" embedded guava.jar and the NuGet guava.jar. For this case we have added the <XamarinGoogleGuavaOptOut> MSBuild property to the Guava NuGet which can be used to prevent the NuGet copy from being added to the application. This can be used until all binding libraries have been updated, at which time it should be removed to allow the NuGet version to be used.

Ensure the application is using the updated Guava NuGet:

<PackageReference Include="Xamarin.Google.Guava" Version="31.1.0.1" />

Declare that the NuGet guava.jar should not be added:

<XamarinGoogleGuavaOptOut>true</XamarinGoogleGuavaOptOut>

Note that if the project contains references to multiple "old-style" binding libraries that embed incompatible guava.jar versions the only fix will be to obtain updated binding libraries.

ListenableFuture.class Conflicts

A different but similar looking issue occurs due to the way Google packaged guava-listenablefuture.jar.

After Guava was shipped, Google copied the ListenableFuture type to a separate package for users who did not want to bring in all of Guava. However, this type is also still in the Guava package. Referencing both of these packages causes both the guava.jar and guava-listenablefuture.jar packages to be added to the final application.

This creates a conflict as both contain ListenableFuture.class. As a temporary fix for this conflict, an "escape hatch" has also been added to Xamarin.Google.Guava.ListenableFuture 1.0.0.7. This will instruct the build system to omit the guava-listenablefuture.jar from the application, preventing the conflict.

Ensure the application is using the updated Guava.ListenableFuture NuGet:

<PackageReference Include="Xamarin.Google.Guava.ListenableFuture" Version="1.0.0.7" />

Declare that the NuGet guava.jar should not be added:

<XamarinGoogleGuavaListenableFutureOptOut>true</XamarinGoogleGuavaListenableFutureOptOut>

We are working on a better, automatic fix for this issue in future packages, but this workaround should unblock applications today.

UPDATE: Newer versions of Guava packages have been released, which should avoid this issue. If you are still experiencing this, ensure that your project is using https://www.nuget.org/packages/Xamarin.Google.Guava/31.1.0.2 or newer.

@jpobst jpobst pinned this issue Apr 19, 2022
@jpobst jpobst closed this as completed Apr 19, 2022
@dotnet dotnet locked and limited conversation to collaborators May 24, 2022
@jpobst jpobst unpinned this issue May 2, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant