java - Gson + AutoValue error while trying to implement own deserializer -


i have retrofit interface combine rxjava. retrofit calls return observable. "somepojo" classes, generate them online using schema2pojo sites.

i have problem when making following api call: https://developers.themoviedb.org/3/search/2y9y2lrefzdhfhbfa

as can see, array 2 different types of objects, called "media" , "credit". these 2 classes generated using google's autovalue follows:

@autovalue public abstract class media implements parcelable {  @serializedname(value = "title", alternate = {"name"}) public abstract string title();  @nullable @serializedname("vote_average") public abstract string voteaverage();  @nullable @serializedname("backdrop_path") public abstract string backdroppath();  @nullable public abstract string adult();  public abstract string id();  @nullable public abstract string overview();  @nullable @serializedname("original_language") public abstract string originallanguage();  @nullable @serializedname("genre_ids") public abstract list<string> genreids();  @nullable @serializedname(value = "release_date", alternate = {"first_air_date"}) public abstract string releasedate();  @nullable @serializedname(value = "original_title", alternate = {"original_name"}) public abstract string originaltitle();  @nullable @serializedname("vote_count") public abstract string votecount();  @nullable @serializedname("poster_path") public abstract string posterpath();  @nullable public abstract string video();  @nullable @serializedname("media_type") public abstract string mediatype();  @nullable public abstract string popularity();  @nullable @serializedname("origin_country") public abstract list<string> originalcountry();   public static media create(string title, string voteaverage, string backdroppath,                            string adult, string id, string overview, string originallanguage,                            list<string> genreids, string releasedate, string originaltitle,                            string votecount, string posterpath, string video, string mediatype,                            string popularity, list<string> originalcountry) {      return new autovalue_media(title, voteaverage, backdroppath, adult, id, overview,             originallanguage, genreids, releasedate, originaltitle, votecount, posterpath,             video, mediatype, popularity, originalcountry); }  public static typeadapter<media> typeadapter(gson gson) {     return new autovalue_media.gsontypeadapter(gson); } } 

and:

@autovalue public abstract class credit implements parcelable { public abstract string id();  @serializedname("credit_id") public abstract string creditid();  @nullable public abstract string department();  public abstract string name();  @nullable @serializedname(value = "job", alternate = {"character"}) public abstract string job();  @nullable @serializedname("profile_path") public abstract string profilepath();  @nullable public abstract string order();  @nullable @serializedname("cast_id") public abstract string castid();   public static credit create(string id, string creditid, string department, string name, string job,                             string profilepath, string order, string castid) {      return new autovalue_credit(id, creditid, department, name, job, profilepath, order, castid); }  public static typeadapter<credit> typeadapter(gson gson) {     return new autovalue_credit.gsontypeadapter(gson); }  } 

to resolve problem created array 2 different kind of objects, made pojo return call implement own jsondeserializer:

public class medialistpojo {      @serializedname("results")     private list<media> movies;      private list<credit> credits;      private dates dates;      private string page;      private string total_pages;      private string total_results;      public list<media> getmedia() {         return movies;     }      public void setmovies(list<media> movies) {         this.movies = movies;     }      public list<credit> getcredits() {return credits;}      public void setcredits(list<credit> credits) {this.credits = credits;}      public dates getdates() {         return dates;     }      public void setdates(dates dates) {         this.dates = dates;     }      public string getpage() {         return page;     }      public void setpage(string page) {         this.page = page;     }      public string gettotal_pages() {         return total_pages;     }      public void settotal_pages(string total_pages) {         this.total_pages = total_pages;     }      public string gettotal_results() {         return total_results;     }      public void settotal_results(string total_results) {         this.total_results = total_results;     }      @override     public string tostring() {         return "medialistpojo{" +                 "movies=" + movies +                 ", credits=" + credits +                 ", dates=" + dates +                 ", page='" + page + '\'' +                 ", total_pages='" + total_pages + '\'' +                 ", total_results='" + total_results + '\'' +                 '}';     }      public static class medialistpojodeserializer implements jsondeserializer<medialistpojo> {          @override         public medialistpojo deserialize(jsonelement json, type typeoft,                                          jsondeserializationcontext context) throws jsonparseexception {              medialistpojo medialistpojo = new gson().fromjson(json, medialistpojo.class);             jsonobject  jsonobject = json.getasjsonobject();              if (jsonobject.has("results")) {                 jsonarray jsonarray = jsonobject.getasjsonarray("results");                 list<credit> credits = new arraylist<>();                 credit credit;                 (jsonelement element : jsonarray) {                     jsonobject current = element.getasjsonobject();                      if (current.get("media_type").getasstring().equals("person")) {                         credit = new gson().fromjson(current, credit.class);                         credits.add(credit);                     }                 }                 medialistpojo.setcredits(credits);             }             return medialistpojo;         }     } } 

the main idea behind json deserializer is: "use default type adapter class , set credit objects using jsondeserializer"

however, reason, following error while deserializing:

java.lang.runtimeexception: failed invoke public media() no args ... caused by: java.lang.instantiationexception: can't instantiate abstract class media @ java.lang.reflect.constructor.newinstance(native method)

it shouldn't try instantiate abstract superclass, use autovalue's generated type adapter.

this how built retrofit instance:

class creator {      public static movieservice newmovieservice() {         gson gson = new gsonbuilder()                 .registertypeadapterfactory(new autovaluegson_myadapterfactory())                 .registertypeadapter(medialistpojo.class, new medialistpojo.medialistpojodeserializer())                 .setdateformat("yyyy-mm-dd't'hh:mm:ss.sss'z'")                 .create();         okhttpclient client = new okhttpclient.builder()                 .addinterceptor(networkutil.makequeryinterceptor("api_key", buildconfig.my_api_key))                 .build();         retrofit retrofit = new retrofit.builder()                 .client(client)                 .baseurl(movieservice.endpoint)                 .addconverterfactory(gsonconverterfactory.create(gson))                 .addcalladapterfactory(rxjavacalladapterfactory.create())                 .build();         return retrofit.create(movieservice.class); 

can me understand did wrong?

well, found solution 5 minutes after posting question, since think other people might struggle well. i'll share solution:

basically, inside of jsondeserializer, using new instance of gson object when, in fact, mistake.

the typeadapterfactory registered while creating retrofit instance of other typeadapters live.

therefore, calling

gson gson = new gson(); 

doesn't supply type adapters needed deserialize rest of object.

i hope helps.


Comments

Popular posts from this blog

angular - Is it possible to get native element for formControl? -

unity3d - Rotate an object to face an opposite direction -

javascript - Why jQuery Select box change event is now working? -