Nested list objects with AutoValue / Gson not working with NoSuchMethodError

I am trying to use JSON object to convert to Java object (using AutoValue) using Gson. The JSON object looks like this:

{
    "id": 1,
    "name": "Nutella Pie",
    "ingredients": [
        {
            "quantity": 2,
            "measure": "CUP",
            "ingredient": "Graham Cracker crumbs"
        },
        ...
    ],
    "steps": [
        {
            "id": 5,
            "shortDescription": "Finish filling prep"
        },
        ...
    ]
}

      

So the Java class (built with AutoValue) looks like this:

@AutoValue
public abstract class Recipe {
    @SerializedName("id")
    abstract int id();
    @SerializedName("name")
    abstract String name();
    @SerializedName("ingredients")
    abstract List<Ingredient> ingredients();
    @SerializedName("steps")
    abstract List<Step> steps();

    public static TypeAdapter<Recipe> typeAdapter(Gson gson) {
        return new AutoValue_Recipe.GsonTypeAdapter(gson);
    }
}

      

Method create

in TypeAdapterFactory

:

public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
    Class<? super T> rawType = type.getRawType();

    if (rawType.equals(Ingredient.class)) {
        return (TypeAdapter<T>) Ingredient.typeAdapter(gson);
    }
    if (rawType.equals(Recipe.class)) {
        return (TypeAdapter<T>) Recipe.typeAdapter(gson);
    }
    if (rawType.equals(Step.class)) {
        return (TypeAdapter<T>) Step.typeAdapter(gson);
    }

    return null;
}

      

However, I have an error:

NoSuchMethodError: static method getParameterized

This one getParameterized

is a GsonTypeAdapter

method and apparently not implemented.

If I change the JSON and Java classes to a nested object instead of a list of nested objects, it works fine .

I do not know what's going on. Any ideas?

EDIT: I've made some progress. As per GSON extension AutoValue docs :

To have support for fields with common parameters (eg List), you need to update your Gson dependency to at least 2.8.0, which introduces the TypeToken.getParameterized () helper type, see "List of changes in Gson".

So my code for creating the Type adapter is:

public static <Ingredient,Step> TypeAdapter<Recipe<Ingredient,Step>> typeAdapter(Gson gson,
                  TypeToken<? extends Recipe<Ingredient,Step>> typeToken) {
    return new AutoValue_Recipe.GsonTypeAdapter(gson,typeToken);
}

      

However, I have a problem using TypeAdapterFactory as it should return TypeAdapter<T>

, not TypeAdapter<Recipe<Ingredient,Step>>

. I tried casting, but did not have time.

What should I do? Add a new TypeAdapterFactory?

+3


source to share


1 answer


NoSuchMethodError: No static method getParameterized

I assume you are using com.ryanharter.auto.value:auto-value-gson:0.4.6

, but you have an older version of Gson up to 2.8.0. You're getting an exception because the AutoValue generator uses Gson 2.8.0 under the hood, while Gson 2.8.0 represents TypeToken.getParameterized

(see Commit 9414b9b3b61d59474a274aab21193391e5b97e52 ). And at runtime, the JVM expects your Gson to provide a method TypeToken.getParameterized

. Since you seem to have an older version of Gson, it throws an error.

There is also a note about Gson 2.8.0 in the auto-value-gson documentation:

You also need the usual runtime dependency for gson itself.

compile 'com.google.code.gson:gson:2.8.0'



If you are using Apache Maven, just make sure you have the latest Gson:

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.8.0</version>
</dependency>

      

This should work. If you are unable to update Gson for any reason, try downgrading the AutoValue Gson generator.

+1


source







All Articles