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

Ima Ads not playing with exception ADS_LOADER.REQUEST_ADS #700

Closed
1 task
chinmaym14 opened this issue Oct 5, 2023 · 16 comments
Closed
1 task

Ima Ads not playing with exception ADS_LOADER.REQUEST_ADS #700

chinmaym14 opened this issue Oct 5, 2023 · 16 comments
Assignees

Comments

@chinmaym14
Copy link

chinmaym14 commented Oct 5, 2023

Version

Media3 1.1.1

More version details

We have recently migrated to media3 version 1.1.1 and found that IMA ads are not getting played. After looking at the logcat we got below exception in IMA sdk. Can you help us in finding out what can cause this exception.

Exception in ADS_LOADER.REQUEST_ADS
com.google.ads.interactivemedia.v3.internal.zzwa: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.contains(java.lang.CharSequence)' on a null object reference
	at com.google.ads.interactivemedia.v3.internal.zzvi.zza(com.google.ads.interactivemedia.v3:interactivemedia@@3.30.3:7)
	at com.google.ads.interactivemedia.v3.internal.zzvd.zzb(com.google.ads.interactivemedia.v3:interactivemedia@@3.30.3:2)
	at com.google.ads.interactivemedia.v3.internal.zzhb.run(com.google.ads.interactivemedia.v3:interactivemedia@@3.30.3:1)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
	at java.lang.Thread.run(Thread.java:764)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.contains(java.lang.CharSequence)' on a null object reference
	at com.google.ads.interactivemedia.v3.internal.zzgt.zza(com.google.ads.interactivemedia.v3:interactivemedia@@3.30.3:1)
	at com.google.ads.interactivemedia.v3.internal.zzgx.zza(com.google.ads.interactivemedia.v3:interactivemedia@@3.30.3:13)
	at com.google.ads.interactivemedia.v3.internal.zzdq.call(com.google.ads.interactivemedia.v3:interactivemedia@@3.30.3:1)
	at com.google.ads.interactivemedia.v3.internal.zzvy.zza(com.google.ads.interactivemedia.v3:interactivemedia@@3.30.3:1)
	at com.google.ads.interactivemedia.v3.internal.zzvp.run(com.google.ads.interactivemedia.v3:interactivemedia@@3.30.3:4)
	at com.google.ads.interactivemedia.v3.internal.zzvz.run(com.google.ads.interactivemedia.v3:interactivemedia@@3.30.3:1)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) 
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) 
	at java.lang.Thread.run(Thread.java:764) 

We are creating ad tag xml ourselves and giving it to the sdk. Before migrating to media3 it was working fine. Below is the sample xml/tag that we are using.

<vmap:VMAP xmlns:vmap="http://www.iab.net/videosuite/vmap" version="1.0">
 <vmap:AdBreak timeOffset="start" breakType="linear" breakId="preroll">
  <vmap:AdSource id="preroll-ad-1" allowMultipleAds="false" followRedirects="true">
   <vmap:AdTagURI templateType="vast3"><![CDATA[https://pubads.g.doubleclick.net/gampad/ads?slotname=/124319096/external/ad_rule_samples&sz=640x480&ciu_szs=300x250&cust_params=sar%3Da0f2&url=https://developers.google.com/interactive-media-ads/docs/sdks/html5/tags&unviewed_position_start=1&output=xml_vast3&impl=s&env=vp&gdfp_req=1&ad_rule=0&vad_type=linear&vpos=preroll&pod=1&ppos=1&lip=true&min_ad_duration=0&max_ad_duration=30000&sarid=4576&sf=2&sfu=vid&vrid=4576&npa=false&kfa=0&tfcd=0]]></vmap:AdTagURI>
  </vmap:AdSource>
 </vmap:AdBreak>
</vmap:VMAP>

Devices that reproduce the issue

LG G6(But should be reproducible in all devices)

Devices that do not reproduce the issue

No response

Reproducible in the demo app?

Yes

Reproduction steps

Try to play IMA ads at preroll

Expected result

Preroll ad should play

Actual result

Ad not playing eventually blocking content playback.

Media

Attaching ad tag that we are using

<vmap:VMAP xmlns:vmap="http://www.iab.net/videosuite/vmap" version="1.0"> <vmap:AdBreak timeOffset="start" breakType="linear" breakId="preroll"> <vmap:AdSource id="preroll-ad-1" allowMultipleAds="false" followRedirects="true"> <vmap:AdTagURI templateType="vast3"><![CDATA[https://pubads.g.doubleclick.net/gampad/ads?slotname=/124319096/external/ad_rule_samples&sz=640x480&ciu_szs=300x250&cust_params=sar%3Da0f2&url=https://developers.google.com/interactive-media-ads/docs/sdks/html5/tags&unviewed_position_start=1&output=xml_vast3&impl=s&env=vp&gdfp_req=1&ad_rule=0&vad_type=linear&vpos=preroll&pod=1&ppos=1&lip=true&min_ad_duration=0&max_ad_duration=30000&sarid=4576&sf=2&sfu=vid&vrid=4576&npa=false&kfa=0&tfcd=0]]></vmap:AdTagURI> </vmap:AdSource> </vmap:AdBreak> </vmap:VMAP>

Bug Report

@marcbaechinger
Copy link
Contributor

Thanks for your report.

The obfuscated stack trace is difficult to interpret, but at first sight I don't think this is something related to a change in Media3 except that your migration caused a change in the version of the IMA SDK version that's used by the library.

We are creating ad tag xml ourselves and giving it to the sdk.

How do you setup the media source for your stream when you are doing this? Are you using the IMA extension of ExoPlayer? You need to give us a bit more context on how you are doing that. I don't know how to achieve this with the IMA extension, so I'm unclear whether this is MEdia3 issue, an SDK issue or an issue with the custom integration you are doing.

We have recently migrated to media3 version 1.1.1

Where did you migrate from, or more importantly what IMA SDK library version were you using before? If you know the IMA version you were using before you can verify whether this is an issue with the different SDK by setting the SDK version what you were using before. This would rule out problems with Media3 and confirm the problem is in the interaction with the SDK and your VAST file:

https://docs.gradle.org/current/userguide/dependency_constraints.html#sec:adding-constraints-transitive-deps

@google-oss-bot
Copy link
Collaborator

Hey @chinmaym14. We need more information to resolve this issue but there hasn't been an update in 14 weekdays. I'm marking the issue as stale and if there are no new updates in the next 7 days I will close it automatically.

If you have more information that will help us get to the bottom of this, just add a comment!

@danish241194
Copy link

danish241194 commented Oct 27, 2023

Hi, we are also facing same issue when using vast xml in base64 encoeded format

Adding Sample Code :

Dependencies :

    implementation("androidx.media3:media3-exoplayer:1.1.1")
    implementation ("androidx.media3:media3-exoplayer-dash:1.1.1")
    implementation ("androidx.media3:media3-ui:1.1.1")
    implementation ("androidx.media3:media3-exoplayer-ima:1.1.1")

 private AdsLoader getClientSideAdsLoader(MediaItem.AdsConfiguration adsConfiguration) {
        // The ads loader is reused for multiple playbacks, so that ad playback can resume.
        if (clientSideAdsLoader == null) {
            clientSideAdsLoader = new ImaAdsLoader.Builder(/* context= */ this)
                    .build();
        }

        clientSideAdsLoader.setPlayer(player);
        return clientSideAdsLoader;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        PlayerView playerView = findViewById(R.id.playerview);
        String base64EncodedVastResponse = "<our vast xml response in base 64 format>"; // example : data:vast;base64,PHZtYXA6Vk1BUCB2ZXJzaW9u..........
        MediaSource.Factory mediaSourceFactory =
                new DefaultMediaSourceFactory(this)
                        .setLocalAdInsertionComponents(this::getClientSideAdsLoader, /* adViewProvider= */ playerView);

        player = new ExoPlayer.Builder(this)
                .setMediaSourceFactory(mediaSourceFactory)
                .build();

        playerView.setPlayer(player);

        MediaItem mediaItem =
                new MediaItem.Builder()
                        .setUri("mpd-url")
                        .setAdsConfiguration(
                                new MediaItem.AdsConfiguration.Builder(Uri.parse(line)).build())
                        .build();

        player.setMediaItem(mediaItem);
        player.prepare();
        player.play();
   }
    E  Exception in ADS_LOADER.REQUEST_ADS
    com.google.ads.interactivemedia.v3.internal.zzwa: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.contains(java.lang.CharSequence)' on a null object reference
    at com.google.ads.interactivemedia.v3.internal.zzvi.zza(com.google.ads.interactivemedia.v3:interactivemedia@@3.30.3:7)
    at com.google.ads.interactivemedia.v3.internal.zzvd.zzb(com.google.ads.interactivemedia.v3:interactivemedia@@3.30.3:2)
    at com.google.ads.interactivemedia.v3.internal.zzhb.run(com.google.ads.interactivemedia.v3:interactivemedia@@3.30.3:1)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
    at java.lang.Thread.run(Thread.java:1012)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean 

@icbaker
Copy link
Collaborator

icbaker commented Oct 27, 2023

I think this is only happening with data:// URIs partly due to this if/else here:

if (DataSchemeDataSource.SCHEME_DATA.equals(adTagDataSpec.uri.getScheme())) {
DataSchemeDataSource dataSchemeDataSource = new DataSchemeDataSource();
try {
dataSchemeDataSource.open(adTagDataSpec);
request.setAdsResponse(Util.fromUtf8Bytes(DataSourceUtil.readToEnd(dataSchemeDataSource)));
} finally {
dataSchemeDataSource.close();
}
} else {
request.setAdTagUrl(adTagDataSpec.uri.toString());
}

When the URL is data:// scheme then we only call IMA's AdsRequest.setAdsResponse instead of AdsRequest.setAdTagUrl.

From the IMA docs, this looks like a legit calling pattern, because setAdsResponse is documented as follows (emphasis mine):

Specifies a VAST, VMAP, or ad rules response to be used instead of making a request through an ad tag URL.

However, setAdTagUrl does say:

This parameter is required.


This issue would be a lot more obvious if the IMA SDK failed-fast if adTagUrl wasn't set. Specifically here, where we pass the AdsRequest into the IMA SDK's AdsLoader.requestAds method (which also documents the tag URL as being required):


It seems we should be always setting the tag URL, even if the response is already available. I will update our code.

@chinmaym14
Copy link
Author

We resolved this issue by downgrading the IMA sdk version to 3.29.0. They have some unexpected NPE in latest version(same exception we were facing) and recommended to downgrade the version.
Thanks for your help!

@icbaker
Copy link
Collaborator

icbaker commented Oct 27, 2023

Despite the documentation, the IMA SDK seems to deliberately allow either ad tag URL or body to be set on the AdsRequest passed to AdsLoader.requestAds (and fails-fast if they're both absent) - so this is looking more like an IMA SDK bug to me (and they should update their documentation to make it clear the URL isn't always required).

@danish241194
Copy link

danish241194 commented Oct 27, 2023

@icbaker thanks for the detailed info. I tried to pass both vmap xml response and adTag url. if we pass both adResponse and adTagurl and above exception Exception in ADS_LOADER.REQUEST_ADS is not occuring but ImaUtil is giving preference to adTagUrl and not adResponse.

String vmapXMLString = "<vmap:VMAP ........";
String adTagUrl = "https://pubads......";
 MediaItem mediaItem =
                new MediaItem.Builder()
                        .setUri("https://d19v8js95lli3t.cloudfront.net/final-1697538058820/dash/final.mpd")
                        .setAdsConfiguration(
                                new MediaItem.AdsConfiguration.Builder(Util.getDataUriForString("text/xml",vmapXMLString)).build())
                        .setAdTagUri(Uri.parse(adTagUrl))
                        .build();

if condition is failing and hence going to else statement

if (DataSchemeDataSource.SCHEME_DATA.equals(adTagDataSpec.uri.getScheme())) {
DataSchemeDataSource dataSchemeDataSource = new DataSchemeDataSource();
try {
dataSchemeDataSource.open(adTagDataSpec);
request.setAdsResponse(Util.fromUtf8Bytes(DataSourceUtil.readToEnd(dataSchemeDataSource)));
} finally {
dataSchemeDataSource.close();
}
} else {
request.setAdTagUrl(adTagDataSpec.uri.toString());
}
.

Is there any way ima uses the response passed and not url.

@icbaker
Copy link
Collaborator

icbaker commented Oct 30, 2023

@danish241194 Ah I think we're talking at different API levels.

I was suggesting in #700 (comment) that ExoPlayer should populate the ad tag URI in the IMA AdsRequest object even for data:// scheme URIs where we can also populate the body. This would be a change to the if/else you linked in ImaUtil. I wasn't suggesting you change the way you're passing info to ExoPlayer.

Your code snippet just sets media3's MediaItem.AdsConfiguration.adTagUri twice (once from the MediaItem.Builder.AdsConfiguration constructor, and once from the (deprecated) MediaItem.Builder.setAdTagUri method), so the second value overwrites the first. media3's AdsConfiguration API has no explicit 'set response' method, using a data:// URI is the expected way to do that.

However - given that, despite the documentation, IMA's validation explicitly allows only AdsRequest.adsResponse without AdsRequest.adTagUri, I think the bug is in IMA if they throw an NPE deeper in their library.


@chinmaym14 Can you try bumping to 3.31.0? That's the IMA version used in media3 1.2.0 alpha02 onwards (since b4d03a9). It's possible this is already fixed.

@LloydBlv
Copy link

Hey @icbaker, This is happening on media3 1.2.0 too, Is this under your radar to fix?

@LloydBlv
Copy link

LloydBlv commented Dec 16, 2023

 com.google.ads.interactivemedia.v3.internal.zztg: java.lang.NullPointerException: 
Attempt to invoke virtual method 'boolean java.lang.String.contains(java.lang.CharSequence)' on a null object reference at com.google.ads.interactivemedia.v3.internal.zzso.zza(com.google.ads.interactivemedia.v3:interactivemedia@@3.31.0:7)
                                                                                                    	at com.google.ads.interactivemedia.v3.internal.zzsj.zzb(com.google.ads.interactivemedia.v3:interactivemedia@@3.31.0:2)
                                                                                                    	at com.google.ads.interactivemedia.v3.internal.zzef.run(com.google.ads.interactivemedia.v3:interactivemedia@@3.31.0:1)
                                                                                                    	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
                                                                                                    	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
                                                                                                    	at java.lang.Thread.run(Thread.java:1012)
                                                                                                    Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.contains(java.lang.CharSequence)' on a null object reference
                                                                                                    	at com.google.ads.interactivemedia.v3.internal.zzdw.zza(com.google.ads.interactivemedia.v3:interactivemedia@@3.31.0:1)
                                                                                                    	at com.google.ads.interactivemedia.v3.internal.zzea.zza(com.google.ads.interactivemedia.v3:interactivemedia@@3.31.0:14)
                                                                                                    	at com.google.ads.interactivemedia.v3.impl.zzn.call(com.google.ads.interactivemedia.v3:interactivemedia@@3.31.0:1)
                                                                                                    	at com.google.ads.interactivemedia.v3.internal.zzte.zza(com.google.ads.interactivemedia.v3:interactivemedia@@3.31.0:1)
                                                                                                    	at com.google.ads.interactivemedia.v3.internal.zzsv.run(com.google.ads.interactivemedia.v3:interactivemedia@@3.31.0:4)
                                                                                                    	at com.google.ads.interactivemedia.v3.internal.zztf.run(com.google.ads.interactivemedia.v3:interactivemedia@@3.31.0:1)
                                                                                                    	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
                                                                                                    	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) 
                                                                                                    	at java.lang.Thread.run(Thread.java:1012) 

@icbaker
Copy link
Collaborator

icbaker commented Dec 18, 2023

@LloydBlv Based on my understanding above, there is no fix to be made for this issue in the media3 library - the NPE happens when interacting with the IMA library in a supported way (i.e. this is a bug inside the IMA SDK).

That said, I'm not able to reproduce. I tried setting a data:// ad URI in the demo app using the XML from the original comment. This is how I'm building the MediaItem:

new MediaItem.Builder()
    .setUri(
        "https://storage.googleapis.com/exoplayer-test-media-1/mkv/android-screens-lavf-56.36.100-aac-avc-main-1280x720.mkv")
    .setAdsConfiguration(
        new MediaItem.AdsConfiguration.Builder(
                Util.getDataUriForString(
                    "text/xml",
                    "<vmap:VMAP xmlns:vmap=\"http://www.iab.net/videosuite/vmap\""
                        + " version=\"1.0\"> <vmap:AdBreak timeOffset=\"start\""
                        + " breakType=\"linear\" breakId=\"preroll\"> <vmap:AdSource"
                        + " id=\"preroll-ad-1\" allowMultipleAds=\"false\""
                        + " followRedirects=\"true\"> <vmap:AdTagURI"
                        + " templateType=\"vast3\"><![CDATA[https://pubads.g.doubleclick.net/gampad/ads?slotname=/124319096/external/ad_rule_samples&sz=640x480&ciu_szs=300x250&cust_params=sar%3Da0f2&url=https://developers.google.com/interactive-media-ads/docs/sdks/html5/tags&unviewed_position_start=1&output=xml_vast3&impl=s&env=vp&gdfp_req=1&ad_rule=0&vad_type=linear&vpos=preroll&pod=1&ppos=1&lip=true&min_ad_duration=0&max_ad_duration=30000&sarid=4576&sf=2&sfu=vid&vrid=4576&npa=false&kfa=0&tfcd=0]]></vmap:AdTagURI>"
                        + " </vmap:AdSource> </vmap:AdBreak> </vmap:VMAP>"))
            .build())
    .build());

The pre-roll ad plays fine, then the content plays.


How are you reproducing the issue? Please provide a complete code snippet I can adapt for the demo app.

@iddqdidkfaidclip
Copy link

iddqdidkfaidclip commented Jan 19, 2024

I too have obfuscated exception in ADS_LOADER.REQUEST_ADS when i try pass Data Uri intead of android.net.Uri.parse(https://link). With link it work how i expected, but now i need to pass raw xml VAST 3.0 data.

Exception in ADS_LOADER.REQUEST_ADS
                                                         com.google.ads.interactivemedia.v3.internal.zztg: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.contains(java.lang.CharSequence)' on a null object reference
                                                         	at com.google.ads.interactivemedia.v3.internal.zzso.zza(com.google.ads.interactivemedia.v3:interactivemedia@@3.31.0:7)
                                                         	at com.google.ads.interactivemedia.v3.internal.zzsj.zzb(com.google.ads.interactivemedia.v3:interactivemedia@@3.31.0:2)
                                                         	at com.google.ads.interactivemedia.v3.internal.zzef.run(com.google.ads.interactivemedia.v3:interactivemedia@@3.31.0:1)
                                                         	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
                                                         	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
                                                         	at java.lang.Thread.run(Thread.java:764)
                                                         Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.contains(java.lang.CharSequence)' on a null object reference
                                                         	at com.google.ads.interactivemedia.v3.internal.zzdw.zza(com.google.ads.interactivemedia.v3:interactivemedia@@3.31.0:1)
                                                         	at com.google.ads.interactivemedia.v3.internal.zzea.zza(com.google.ads.interactivemedia.v3:interactivemedia@@3.31.0:14)
                                                         	at com.google.ads.interactivemedia.v3.impl.zzn.call(com.google.ads.interactivemedia.v3:interactivemedia@@3.31.0:1)
                                                         	at com.google.ads.interactivemedia.v3.internal.zzte.zza(com.google.ads.interactivemedia.v3:interactivemedia@@3.31.0:1)
                                                         	at com.google.ads.interactivemedia.v3.internal.zzsv.run(com.google.ads.interactivemedia.v3:interactivemedia@@3.31.0:4)
                                                         	at com.google.ads.interactivemedia.v3.internal.zztf.run(com.google.ads.interactivemedia.v3:interactivemedia@@3.31.0:1)
                                                         	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) 
                                                         	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) 
                                                         	at java.lang.Thread.run(Thread.java:764) 

Little bit modified snippet of my code with player setup. But in general it equal to upper comment i think.

val source = https://stream....../index.m3u8
val vastTag = MyOwnUtil.getVast()
val adUri = Util.getDataUriForString("text/xml", vastTag)

 val adsConfig = 
            MediaItem.AdsConfiguration
                .Builder(adUri)
                .build()

val mediaItem = MediaItem.Builder()
            .setUri(source)
            .setAdsConfiguration(adsConfig)
            .build()

val dataSourceFactory: DataSource.Factory = DefaultHttpDataSource.Factory()

val hlsMediaSource: HlsMediaSource = HlsMediaSource.Factory(dataSourceFactory)
            .setAllowChunklessPreparation(false)
            .createMediaSource(mediaItem)

val adsLoader = ImaAdsLoader.Builder(context)
                .apply {
                    setDebugModeEnabled(BuildConfig.DEBUG)
                    setFocusSkipButtonWhenAvailable(true)
                }
                .setAdEventListener(adsListener)
                .build()
                .apply { setPlayer(myExoPlayerInstance) }

val mediaSourceWithAds = adsLoader?.let { adsLoader ->
            vastTag?.let {
                AdsMediaSource(
                    hlsMediaSource,
                    DataSpec(adUri),
                    "myOwnAd",
                    DefaultMediaSourceFactory(requireContext()),
                    adsLoader,
                    binding.playerView
                )
            }
        }

 myExoPlayerInstance?.apply {
            setMediaSource(mediaSourceWithAds ?: hlsMediaSource)
            prepare()
            addListener(playerErrorHandler)
            playWhenReady = true
        }

versions of dependencies

...
implementation("androidx.media3:media3-ui:1.2.1")
    implementation("androidx.media3:media3-exoplayer:1.2.1")
    implementation("androidx.media3:media3-exoplayer-dash:1.2.1")
    implementation("androidx.media3:media3-exoplayer-hls:1.2.1")
    implementation("androidx.media3:media3-exoplayer-ima:1.2.1")
    implementation("androidx.browser:browser:1.7.0")
    implementation("com.google.ads.interactivemedia.v3:interactivemedia:3.31.0")
...

@stevemayhew
Copy link
Contributor

stevemayhew commented May 1, 2024

@icbaker you are correct, this is a bug in the IMA SDK itself not ExoPlayer's supplied IMA Extension.

We are using data URL as well, ExoPlayer handles these just fine. ExoPlayer uses the DataSchemeDataSource to set the decoded VAST XML directly in AdsRequest.setAdsResponse(). The SDK Docs say either setAdTagUrl() or the response is required.

I see different behavior with latest version of SDK (3.33.0), it still reports the error:

05-01 15:11:44.868 22608 22793 E IMASDK  : Error during initialization
05-01 15:11:44.868 22608 22793 E IMASDK  : java.util.concurrent.ExecutionException: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.contains(java.lang.CharSequence)' on a null object reference
05-01 15:11:44.868 22608 22793 E IMASDK  : 	at com.google.ads.interactivemedia.v3.internal.zzrq.zzx(com.google.ads.interactivemedia.v3:interactivemedia@@3.33.0:4)
05-01 15:11:44.868 22608 22793 E IMASDK  : 	at com.google.ads.interactivemedia.v3.internal.zzrq.get(com.google.ads.interactivemedia.v3:interactivemedia@@3.33.0:3)
...

But then goes on to process the VAST document.

The version in the head of main (3.31.0), freezes after throwing the Exception.

05-01 15:21:53.674 23159 23365 E IMASDK  : Exception in ADS_LOADER.REQUEST_ADS
05-01 15:21:53.674 23159 23365 E IMASDK  : com.google.ads.interactivemedia.v3.internal.zztg: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.contains(java.lang.CharSequence)' on a null object reference
05-01 15:21:53.674 23159 23365 E IMASDK  : 	at com.google.ads.interactivemedia.v3.internal.zzso.zza(com.google.ads.interactivemedia.v3:interactivemedia@@3.31.0:7)
05-01 15:21:53.674 23159 23365 E IMASDK  : 	at com.google.ads.interactivemedia.v3.internal.zzsj.zzb(com.google.ads.interactivemedia.v3:interactivemedia@@3.31.0:2)
05-01 15:21:53.674 23159 23365 E IMASDK  : 	at com.google.ads.interactivemedia.v3.internal.zzef.run(com.google.ads.interactivemedia.v3:interactivemedia@@3.31.0:1)
05-01 15:21:53.674 23159 23365 E IMASDK  : 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
05-01 15:21:53.674 23159 23365 E IMASDK  : 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
05-01 15:21:53.674 23159 23365 E IMASDK  : 	at java.lang.Thread.run(Thread.java:919)
05-01 15:21:53.674 23159 23365 E IMASDK  : Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.contains(java.lang.CharSequence)' on a null object reference
05-01 15:21:53.674 23159 23365 E IMASDK  : 	at com.google.ads.interactivemedia.v3.internal.zzdw.zza(com.google.ads.interactivemedia.v3:interactivemedia@@3.31.0:1)
05-01 15:21:53.674 23159 23365 E IMASDK  : 	at com.google.ads.interactivemedia.v3.internal.zzea.zza(com.google.ads.interactivemedia.v3:interactivemedia@@3.31.0:14)
05-01 15:21:53.674 23159 23365 E IMASDK  : 	at com.google.ads.interactivemedia.v3.impl.zzn.call(com.google.ads.interactivemedia.v3:interactivemedia@@3.31.0:1)
05-01 15:21:53.674 23159 23365 E IMASDK  : 	at com.google.ads.interactivemedia.v3.internal.zzte.zza(com.google.ads.interactivemedia.v3:interactivemedia@@3.31.0:1)
05-01 15:21:53.674 23159 23365 E IMASDK  : 	at com.google.ads.interactivemedia.v3.internal.zzsv.run(com.google.ads.interactivemedia.v3:interactivemedia@@3.31.0:4)
05-01 15:21:53.674 23159 23365 E IMASDK  : 	at com.google.ads.interactivemedia.v3.internal.zztf.run(com.google.ads.interactivemedia.v3:interactivemedia@@3.31.0:1)
05-01 15:21:53.674 23159 23365 E IMASDK  : 	... 3 more

05-01 15:22:05.114 23159 23159 W edia3.demo.mai: Accessing hidden method Llibcore/io/Memory;->pokeByte(JB)V (greylist, reflection, allowed)
...

My guess is the IMA SDK code is trying to reference the AdTagUri, before it even bothers to look if there is a response.

I can provide a pull request, I also posted this comment link to the IMA SDK Google group as well.

Two "fixes" (workaround basically) possible:

  1. Update to 3.33.0 (throws the exception but it seems to be in a catch that just logs and ignores it)
  2. Set the data URI into the AdTagUrl (the IMA code does not appear to try and fetch this)

For number 2:

  /** Returns an {@link AdsRequest} based on the specified ad tag {@link DataSpec}. */
  public static AdsRequest getAdsRequestForAdTagDataSpec(
      ImaFactory imaFactory, DataSpec adTagDataSpec) throws IOException {
    AdsRequest request = imaFactory.createAdsRequest();
    if (DataSchemeDataSource.SCHEME_DATA.equals(adTagDataSpec.uri.getScheme())) {
      DataSchemeDataSource dataSchemeDataSource = new DataSchemeDataSource();
      try {
        dataSchemeDataSource.open(adTagDataSpec);
        request.setAdTagUrl(adTagDataSpec.uri.toString());
        request.setAdsResponse(Util.fromUtf8Bytes(DataSourceUtil.readToEnd(dataSchemeDataSource)));

@icbaker the one line add, request.setAdTagUrl(adTagDataSpec.uri.toString()); makes the stack trace go away in both 3.33.0 and 3.31.0

copybara-service bot pushed a commit that referenced this issue May 9, 2024
@icbaker
Copy link
Collaborator

icbaker commented May 9, 2024

I've bumped the IMA dependency to 3.33.0 - which it sounds like resolves this issue.

@icbaker icbaker closed this as completed May 9, 2024
@stevemayhew
Copy link
Contributor

@icbaker it "sort of" fixes it, you still see the IMASDK report the error:

05-01 15:11:44.868 22608 22793 E IMASDK  : Error during initialization
05-01 15:11:44.868 22608 22793 E IMASDK  : java.util.concurrent.ExecutionException: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.contains(java.lang.CharSequence)' on a null object reference

I did get a response from the group, so I'll follow up with them. setting the URL and the request both is the only solution that eliminates the error message. You can see the IMA SDK code, so you know best if the error is still ok

@icbaker
Copy link
Collaborator

icbaker commented May 22, 2024

You can see the IMA SDK code

Heh, fair point! I think I've found the only place that String.contains() is invoked on the ad tag URL, and I've submitted a change that avoids the invocation if the URL is null - so hopefully that fixes the logging too. I'm not sure when that change will get released in a new IMA SDK version.

@androidx androidx locked and limited conversation to collaborators Jul 9, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

8 participants