Fix Java-generic name-clash in AdLoadCallback subclasses (issue #1491)#1492
Open
jonathanpeppers wants to merge 3 commits into
Open
Fix Java-generic name-clash in AdLoadCallback subclasses (issue #1491)#1492jonathanpeppers wants to merge 3 commits into
jonathanpeppers wants to merge 3 commits into
Conversation
The base `AdLoadCallback<AdT>` in play-services-ads-lite declares
`onAdLoaded(AdT)` which erases to `onAdLoaded(Object)` in bytecode.
The binding generator therefore exposes only
`virtual OnAdLoaded(Java.Lang.Object)` on every concrete subclass
(`AdManagerInterstitialAdLoadCallback`, `InterstitialAdLoadCallback`,
`RewardedAdLoadCallback`, `RewardedInterstitialAdLoadCallback`,
`AppOpenAd.AppOpenAdLoadCallback`).
When a user override that in C#, the generated Java ACW stub emits
`public void onAdLoaded(java.lang.Object p0)`, which javac rejects with
error: name clash: onAdLoaded(Object) in MyCallback and
onAdLoaded(AdManagerInterstitialAd) in AdLoadCallback have the same
erasure, yet neither overrides the other
because after generic substitution the parent's method is the specialized
one.
Add a specialized `onAdLoaded(SpecificAd)` method on each concrete
subclass via <add-node> so the binding exposes a properly-typed
`virtual OnAdLoaded(SpecificAd)` with a specialized JNI registration.
Users can now override the specialized overload, and the resulting ACW
stub emits the specialized Java signature that correctly overrides the
parent -- matching how Google's docs show the callback being subclassed
in Java.
Fixes #1491.
Co-authored-by: Copilot App <[email protected]>
There was a problem hiding this comment.
Pull request overview
This PR updates the play-services-ads-lite binding metadata to address a Java generic-erasure name-clash that prevents apps from compiling when users override AdLoadCallback<AdT>.onAdLoaded(...) via the currently-exposed OnAdLoaded(Java.Lang.Object) in C# (issue #1491). The approach is to inject properly-specialized onAdLoaded(SpecificAd) methods onto each concrete *AdLoadCallback subclass so the binding surfaces typed OnAdLoaded(SpecificAd) overloads with specialized JNI registrations.
Changes:
- Add
<add-node>metadata entries that introduce specializedonAdLoaded(SpecificAd)methods for each affected*AdLoadCallbackconcrete subclass. - Record the resulting new typed virtual overloads in
PublicAPI.Unshipped.txtfor API tracking.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| source/com.google.android.gms/play-services-ads-lite/Transforms/Metadata.xml | Adds specialized onAdLoaded(SpecificAd) methods to concrete AdLoadCallback<AdT> subclasses to avoid Java name-clash from generic erasure. |
| source/com.google.android.gms/play-services-ads-lite/PublicAPI/PublicAPI.Unshipped.txt | Captures the new typed OnAdLoaded(SpecificAd) virtual overloads as public API additions. |
Ship the AdLoadCallback binding fix from the previous commit (fixes #1491) as a new NuGet revision. Co-authored-by: Copilot App <[email protected]>
The customer's project uses the Google.Android.Gms.Ads.* namespace, which comes from Xamarin.GooglePlayServices.Ads.Api (transitively via Xamarin.GooglePlayServices.Ads), not Xamarin.GooglePlayServices.Ads.Lite. Apply the same <add-node> metadata fix to the -api binding so that the five concrete AdLoadCallback<AdT> subclasses expose a specialized OnAdLoaded(SpecificAd) overload, avoiding the javac name-clash on ACW generation when users override the callback. Also bump Xamarin.GooglePlayServices.Ads and Xamarin.GooglePlayServices.Ads.Api by 0.0.0.1 so consumers pick up the fix. Co-authored-by: Copilot App <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1491.
Problem
AdLoadCallback<AdT>declarespublic void onAdLoaded(AdT ad), which erases toonAdLoaded(Object)in bytecode. The binding therefore only exposesvirtual OnAdLoaded(Java.Lang.Object p0)on every concrete subclass:AdManagerInterstitialAdLoadCallbackInterstitialAdLoadCallbackRewardedAdLoadCallbackRewardedInterstitialAdLoadCallbackAppOpenAd.AppOpenAdLoadCallbackWhen a user overrides that in C#, the generated ACW Java stub emits
public void onAdLoaded(java.lang.Object p0), and javac rejects it:After generic substitution the parent's real method is the specialized one, so the erased override doesn't satisfy javac.
Fix
For each concrete
*AdLoadCallbacksubclass, add a specializedonAdLoaded(SpecificAd)method via<add-node>in the binding'sTransforms/Metadata.xml. The binding now surfaces a properly-typedvirtual OnAdLoaded(SpecificAd)with a specialized JNI registration, e.g.:Users override the specialized overload, and the resulting ACW stub emits the specialized Java signature that correctly overrides the parent — matching how Google's docs show the callback being subclassed in Java.
The same fix is applied in both bindings that ship these types:
play-services-ads-lite—Android.Gms.Ads.*namespace (used byXamarin.GooglePlayServices.Ads.Litedirect consumers).play-services-ads-api—Google.Android.Gms.Ads.*namespace (pulled in transitively byXamarin.GooglePlayServices.Ads, which is what the issue reporter uses).Both
.aars independently contain the*AdLoadCallback.classfiles and each produces its own set of .NET types, so the metadata must be added in both places.Version bumps
Xamarin.GooglePlayServices.Ads.Lite:124.0.0.6→124.0.0.7Xamarin.GooglePlayServices.Ads.Api:125.4.0.1→125.4.0.2Xamarin.GooglePlayServices.Ads:125.4.0.1→125.4.0.2User-facing migration
Users hitting
javac.exe error JAVAC0000from #1491 should change:to the specialized overload, e.g.:
Verification
dotnet cake --target=metadata-verifypasses.com.google.android.gms.play-services-ads-liteandcom.google.android.gms.play-services-ads-apilocally (against a project-referencedAds.Basesince the publishedAds.Base 124.0.0.1NuGet does not yet targetnet10.0-android36) — build succeeded, 0 warnings, 0 errors.*AdLoadCallback.csin each project'sobj/contains the specializedvirtual void OnAdLoaded(SpecificAd p0)with the expected[Register("onAdLoaded", "(Lcom/.../SpecificAd;)V", ...)].PublicAPI.Unshipped.txtfor both packages by the analyzer.