Glide: RequestManager can not be cast to GlideRequests

Created on 5 Dec 2017  路  8Comments  路  Source: bumptech/glide

We're creating an android library in which we have used Glide for loading images. Glide version is 4.3.1.

Now there is a weird problem with the generated classes. Consider the following piece of code which is generated GlideApp class after being obfuscated with proguard.

package com.example.util;

import android.content.Context;
import com.bumptech.glide.Glide;

public final class GlideApp {
    private GlideApp() {
    }

    public static GlideRequests a(Context var0) {
        return (GlideRequests)Glide.with(var0);
    }
}

And this is the GlideRequests class:

package com.example.util;

import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.support.annotation.CheckResult;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.bumptech.glide.RequestManager;
import com.bumptech.glide.load.resource.gif.GifDrawable;
import com.bumptech.glide.request.RequestOptions;
import java.io.File;

public class GlideRequests extends RequestManager {
    @CheckResult
    public <ResourceType> GlideRequest<ResourceType> a(Class<ResourceType> var1) {
        return new GlideRequest(this.glide, this, var1, this.context);
    }

    public GlideRequests a(RequestOptions var1) {
        return (GlideRequests)super.applyDefaultRequestOptions(var1);
    }

    public GlideRequests b(RequestOptions var1) {
        return (GlideRequests)super.setDefaultRequestOptions(var1);
    }

    @CheckResult
    public GlideRequest<Bitmap> a() {
        return (GlideRequest)super.asBitmap();
    }

    @CheckResult
    public GlideRequest<GifDrawable> b() {
        return (GlideRequest)super.asGif();
    }

    @CheckResult
    public GlideRequest<Drawable> c() {
        return (GlideRequest)super.asDrawable();
    }

    @CheckResult
    public GlideRequest<Drawable> a(@Nullable Object var1) {
        return (GlideRequest)super.load(var1);
    }

    @CheckResult
    public GlideRequest<File> d() {
        return (GlideRequest)super.downloadOnly();
    }

    @CheckResult
    public GlideRequest<File> b(@Nullable Object var1) {
        return (GlideRequest)super.download(var1);
    }

    @CheckResult
    public GlideRequest<File> e() {
        return (GlideRequest)super.asFile();
    }

    protected void setRequestOptions(@NonNull RequestOptions var1) {
        if(var1 instanceof GlideOptions) {
            super.setRequestOptions(var1);
        } else {
            super.setRequestOptions((new GlideOptions()).a(var1));
        }

    }
}

And here is the content of my proguard-rules.pro:

##Glide
-keep class com.bumptech.glide.integration.volley.VolleyGlideModule
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public class * extends com.bumptech.glide.module.AppGlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
  **[] $VALUES;
  public *;
}
-keep class com.bumptech.glide.GeneratedAppGlideModuleImpl

Now the problem here is when I want to actually use Glide to load some images the following exception gets thrown:

java.lang.ClassCastException: com.bumptech.glide.RequestManager cannot be cast to com.example.util.utils.GlideRequests
at com.example.util.utils.GlideApp.a(Unknown Source:4)
at com.example.util.core.banner.a.a.a(Unknown Source:206)
at com.example.util.core.banner.a.a.(Unknown Source:10)
at com.example.util.core.banner.BannerAdView.b(Unknown Source:61)
at com.example.util.core.banner.BannerAdView.a(Unknown Source:3)
at com.example.util.core.banner.BannerAdView.a(Unknown Source:0)
at com.example.util.core.banner.BannerAdView$1.c(Unknown Source:25)
at com.example.util.core.banner.b$1.a(Unknown Source:40)
at com.example.util.core.banner.b$1.onResponse(Unknown Source:2)
at com.android.volley.toolbox.JsonRequest.deliverResponse(JsonRequest.java:65)
at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99)
at android.os.Handler.handleCallback(Handler.java:769)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6540)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

I'm also using Glide and Volley integration.

question repro-needed

Most helpful comment

@sjudd This issue is resolved by tweaking the proguard rules.

-keep class com.bumptech.glide.GeneratedAppGlideModuleImpl {
*;
}

And thanks for pointing out the LibraryGlideModule, I didn't know it could cause a conflict.

All 8 comments

Sounds like GeneratedAppGlideModuleImpl is being stripped by proguard anyway.

If you can reproduce this in a sample app and attach it or a link here, I'm happy to take a look.

Hi @sjudd,
This is a sample project which could be used.
https://github.com/msmoradi/sample-sdk

By upgrading to the latest version of Glide this exception is no longer reachable. Instead another exception is thrown:

java.lang.AbstractMethodError: abstract method "java.util.Set com.bumptech.glide.GeneratedAppGlideModule.getExcludedModuleClasses()"
                                                                      at com.bumptech.glide.Glide.initializeGlide(Glide.java:225)
                                                                      at com.bumptech.glide.Glide.initializeGlide(Glide.java:212)
                                                                      at com.bumptech.glide.Glide.checkAndInitializeGlide(Glide.java:176)
                                                                      at com.bumptech.glide.Glide.get(Glide.java:160)
                                                                      at com.bumptech.glide.Glide.getRetriever(Glide.java:612)
                                                                      at com.bumptech.glide.Glide.with(Glide.java:638)

You can reproduce this exception in this repo: https://github.com/msmoradi/sample-sdk

Ah got it, so the issue is in 'ir.adad.androidsdkv6:AdadSDKv6:6.0.0beta5'.

I'm not sure what the issue is with the module generation in that library, though I can take a look if you can point me to the source.

However, it doesn't make sense for any library package to include an AppGlideModule. Libraries should only include LibraryGlideModules. Including an AppGlideModule prevents applications from defining their own, which in turn prevents them from setting options or managing dependencies appropriately.

@sjudd This issue is resolved by tweaking the proguard rules.

-keep class com.bumptech.glide.GeneratedAppGlideModuleImpl {
*;
}

And thanks for pointing out the LibraryGlideModule, I didn't know it could cause a conflict.

Thanks for the follow up. Could you also try:

-keep public class * extends com.bumptech.glide.module.AppGlideModule {
*;
}

and let me know if that also works? Instead of doing:

-keep class com.bumptech.glide.GeneratedAppGlideModuleImpl {
*;
}

I'd like to update our proguard rules to match what worked for you, but if we can simplify them at all, that would be great.

Hi @sjudd ,
It went back to throwing this:

java.lang.ClassCastException: com.bumptech.glide.RequestManager cannot be cast to ir.adad.adadsdkv6.utils.c
                                                                                 at ir.adad.adadsdkv6.utils.GlideApp.a(Unknown Source:4)
                                                                                 at ir.adad.adadsdkv6.core.banner.a.a.a(Unknown Source:206)
                                                                                 at ir.adad.adadsdkv6.core.banner.a.a.<init馃槧Unknown Source:10)
                                                                                 at ir.adad.adadsdkv6.core.banner.BannerAdView.b(Unknown Source:40)
                                                                                 at ir.adad.adadsdkv6.core.banner.BannerAdView.a(Unknown Source:3)
                                                                                 at ir.adad.adadsdkv6.core.banner.BannerAdView.a(Unknown Source:0)
                                                                                 at ir.adad.adadsdkv6.core.banner.BannerAdView$1.onAdAvailable(Unknown Source:25)
                                                                                 at ir.adad.adadsdkv6.core.banner.a$1.a(Unknown Source:40)
                                                                                 at ir.adad.adadsdkv6.core.banner.a$1.onResponse(Unknown Source:2)
                                                                                 at com.android.volley.toolbox.JsonRequest.deliverResponse(JsonRequest.java:65)
                                                                                 at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99)
                                                                                 at android.os.Handler.handleCallback(Handler.java:790)
                                                                                 at android.os.Handler.dispatchMessage(Handler.java:99)
                                                                                 at android.os.Looper.loop(Looper.java:164)
                                                                                 at android.app.ActivityThread.main(ActivityThread.java:6494)
                                                                                 at java.lang.reflect.Method.invoke(Native Method)
                                                                                 at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
                                                                                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

Any updates on this?

cc @2hamed @sjudd

Was this page helpful?
0 / 5 - 0 ratings