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

java.lang.AssertionError: illegal type variable reference #1343

Open
kkmike999 opened this issue Jul 5, 2018 · 6 comments
Open

java.lang.AssertionError: illegal type variable reference #1343

kkmike999 opened this issue Jul 5, 2018 · 6 comments
Labels
android Issues which are exclusive to Android, and don't occur with a JDK (even if ProGuard / R8 is used) needs-info

Comments

@kkmike999
Copy link

kkmike999 commented Jul 5, 2018

i use gson 2.8.5 in android project,run app with proguard on real Android Phone. when execute code Type listType = new TypeToken<List<T>>() {}.getType(),then crash:

 java.lang.AssertionError: illegal type variable reference
        at libcore.reflect.TypeVariableImpl.resolve(TypeVariableImpl.java:111)
        at libcore.reflect.TypeVariableImpl.getGenericDeclaration(TypeVariableImpl.java:125)
        at libcore.reflect.TypeVariableImpl.hashCode(TypeVariableImpl.java:47)
        at java.util.Arrays.hashCode(Arrays.java:4153)
        at com.google.gson.internal.$Gson$Types$ParameterizedTypeImpl.hashCode($Gson$Types.java:502)
        at com.google.gson.reflect.TypeToken.<init>(TypeToken.java:64)
......

i have add these code in proguard.pro:

-keepattributes Exceptions
-keepattributes InnerClasses
-keepattributes Signature
-keepattributes Deprecated
-keepattributes SourceFile
-keepattributes LineNumberTable
-keepattributes *Annotation*
-keepattributes EnclosingMethod

# Gson specific classes
-keep class sun.** { *; }
#-keep class com.google.gson.stream.** { *; }

# Prevent proguard from stripping interface information from TypeAdapterFactory,
# JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
@lyubomyr-shaydariv
Copy link
Contributor

lyubomyr-shaydariv commented Jul 5, 2018

It doesn't look like a bug.listType cannot be declared with T (it looks like it's declared within your generic class capturing the class type variable only) at the declaration site, but it should be declared at the call site with a real type, and then passed to your generic class. The same goes to generic methods. Simple googling before posting would save you some time and give some hints: Gson illegal type variable reference - Stack Overflow.

@kkmike999
Copy link
Author

kkmike999 commented Jul 5, 2018

@lyubomyr-shaydariv maybe some other config cause this error. i config build.gradle

android {
 buildTypes{
    alpha {
            minifyEnabled true
            zipAlignEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro', 'proguard-rules-2.0.pro'
            signingConfig signingConfigs.releaseConfig
            multiDexKeepProguard file('keep_in_main_dex.pro')
            debuggable = false

            // matchingFallbacks属性来设置回退策略(必填,http://codezjx.com/2017/11/23/gradle-plugin-3-0-0-migration/)
            matchingFallbacks = ['release']
        }
    }
}

the problem solve. But when config debuggable = ture, the error occur T_T.

@YuanKJ-
Copy link

YuanKJ- commented Aug 19, 2019

I had the same problem

@rosuH
Copy link

rosuH commented Mar 2, 2020

@kkmike999 Toggled debuggable not help us.
We convert a JSON string to List in our conditions. And then we got this error.
But same code in other computers works fine.

public static <T> List<T> jsonToList(@NonNull String jsonStr) {
       try {
           List<T> objList = null;
           if (gson != null) {
               Type type = new TypeToken<List<T>>() {}.getType();
               objList = gson.fromJson(jsonStr, type);
           }
           return objList;
       }catch (Exception e){
           Log.i("json",e.getMessage());
           return null;
       }
 }

We tried below code to fix it by specified a type.

public static <T> List<T> jsonToList(@NonNull String json, Class<T> cls) {
        try {
            Gson gson = new Gson();
            List<T> list = new ArrayList<T>();
            JsonArray array = new JsonParser().parse(json).getAsJsonArray();
            for(final JsonElement elem : array){
                list.add(gson.fromJson(elem, cls));
            }
            return list;
        }catch (Exception e){
            Log.i("json",e.getMessage());
            return null;
        }
    }

Maybe it was compiled issue, hope it help.


Just using Gson in Retrofit converter:

api 'com.squareup.retrofit2:converter-gson:2.4.0'

Android Studio 3.6.1
Build #AI-192.7142.36.36.6241897, built on February 27, 2020
Runtime version: 1.8.0_212-release-1586-b04 amd64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
Windows 10 10.0
GC: ParNew, ConcurrentMarkSweep
Memory: 1979M
Cores: 12
Registry: ide.new.welcome.screen.force=true
Non-Bundled Plugins: String Manipulation, com.dengzii.plugin.adb, com.genymotion.idea, com.mfwebstudio.atomonedark.plugin.id, com.vermouthx.idea, net.seesharpsoft.intellij.plugins.file-preview, net.vektah.codeglance, cn.yiiguxing.plugin.translate, izhangzhihao.rainbow.brackets, BashSupport, com.developerphil.adbidea, some.awesome

@lyubomyr-shaydariv
Copy link
Contributor

@rosuH
No need to have it such complex. You can simply create a method like this:

public static <T> List<T> fromJsonToList(final String json, final Class<T> elementClass) {
	return gson.fromJson(json, TypeToken.getParameterized(List.class, elementClass).getType());
}

that will do the job. I'd only recommend this method if you provide the element types dynamically, not statically (also note that gson can be re-used, no need to new it). However, I believe you only need something like this:

private static final TypeToken<List<Short>> listOfShorts = new TypeToken<List<Short>>() {};
private static final TypeToken<List<Float>> listOfFloats = new TypeToken<List<Float>>() {};

public static void main(final String... args) {
	final String json = "[1,2,3,4,5,6]";
	System.out.println(gson.<List<Short>>fromJson(json, listOfShorts.getType()));
	System.out.println(gson.<List<Float>>fromJson(json, listOfFloats.getType()));
}

that would produce [1, 2, 3, 4, 5, 6] and [1.0, 2.0, 3.0, 4.0, 5.0, 6.0] respectively. It is a little more verbose, but you don't need to implement custom methods, and you can reuse type tokens too.

@Marcono1234
Copy link
Collaborator

Could you please test if you still experience this AssertionError with the latest Gson version?
And if that is the case, does that only occur on a real Android device (if so, which Android version and which device) or does it also occur for an Android emulator, in unit tests or even with a JDK?

@eamonnmcmanus eamonnmcmanus added the android Issues which are exclusive to Android, and don't occur with a JDK (even if ProGuard / R8 is used) label Jul 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
android Issues which are exclusive to Android, and don't occur with a JDK (even if ProGuard / R8 is used) needs-info
Projects
None yet
Development

No branches or pull requests

6 participants