misaochan
misaochan

Reputation: 890

'No args constructor for class does not exist', but it does

I am receiving the error No-args constructor for class MwVolleyApi$Page does not exist. Register an InstanceCreator with Gson for this type to fix this problem. I've read up on this and have found two types of solutions, neither of which seems to work for me:

  1. https://github.com/google/gson/issues/135 - use a static nested class (I did)
  2. No-args constructor for class XXX does not exist - create a no args constructor for the class (I did)

What am I missing?

Full error message:

10-08 17:07:53.790: E/Volley(31902): [4551] NetworkDispatcher.run: Unhandled exception java.lang.RuntimeException: No-args constructor for class fr.free.nrw.commons.upload.MwVolleyApi$Page does not exist. Register an InstanceCreator with Gson for this type to fix this problem.
10-08 17:07:53.790: E/Volley(31902): java.lang.RuntimeException: No-args constructor for class fr.free.nrw.commons.upload.MwVolleyApi$Page does not exist. Register an InstanceCreator with Gson for this type to fix this problem.
10-08 17:07:53.790: E/Volley(31902):    at com.google.gson.MappedObjectConstructor.constructWithNoArgConstructor(MappedObjectConstructor.java:64)
10-08 17:07:53.790: E/Volley(31902):    at com.google.gson.MappedObjectConstructor.construct(MappedObjectConstructor.java:53)
10-08 17:07:53.790: E/Volley(31902):    at com.google.gson.JsonObjectDeserializationVisitor.constructTarget(JsonObjectDeserializationVisitor.java:41)
10-08 17:07:53.790: E/Volley(31902):    at com.google.gson.JsonDeserializationVisitor.getTarget(JsonDeserializationVisitor.java:56)
10-08 17:07:53.790: E/Volley(31902):    at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:101)
10-08 17:07:53.790: E/Volley(31902):    at com.google.gson.JsonDeserializationVisitor.visitChild(JsonDeserializationVisitor.java:107)
10-08 17:07:53.790: E/Volley(31902):    at com.google.gson.JsonDeserializationVisitor.visitChildAsObject(JsonDeserializationVisitor.java:95)
10-08 17:07:53.790: E/Volley(31902):    at com.google.gson.JsonArrayDeserializationVisitor.visitArray(JsonArrayDeserializationVisitor.java:73)
10-08 17:07:53.790: E/Volley(31902):    at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:109)
10-08 17:07:53.790: E/Volley(31902):    at com.google.gson.JsonDeserializationVisitor.visitChild(JsonDeserializationVisitor.java:107)
10-08 17:07:53.790: E/Volley(31902):    at com.google.gson.JsonDeserializationVisitor.visitChildAsArray(JsonDeserializationVisitor.java:102)
10-08 17:07:53.790: E/Volley(31902):    at com.google.gson.JsonObjectDeserializationVisitor.visitArrayField(JsonObjectDeserializationVisitor.java:81)
10-08 17:07:53.790: E/Volley(31902):    at com.google.gson.ObjectNavigator.navigateClassFields(ObjectNavigator.java:154)
10-08 17:07:53.790: E/Volley(31902):    at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:123)
10-08 17:07:53.790: E/Volley(31902):    at com.google.gson.JsonDeserializationVisitor.visitChild(JsonDeserializationVisitor.java:107)
10-08 17:07:53.790: E/Volley(31902):    at com.google.gson.JsonDeserializationVisitor.visitChildAsObject(JsonDeserializationVisitor.java:95)
10-08 17:07:53.790: E/Volley(31902):    at com.google.gson.JsonObjectDeserializationVisitor.visitObjectField(JsonObjectDeserializationVisitor.java:62)
10-08 17:07:53.790: E/Volley(31902):    at com.google.gson.ObjectNavigator.navigateClassFields(ObjectNavigator.java:156)
10-08 17:07:53.790: E/Volley(31902):    at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:123)
10-08 17:07:53.790: E/Volley(31902):    at com.google.gson.JsonDeserializationContextDefault.fromJsonObject(JsonDeserializationContextDefault.java:73)
10-08 17:07:53.790: E/Volley(31902):    at com.google.gson.JsonDeserializationContextDefault.deserialize(JsonDeserializationContextDefault.java:51)
10-08 17:07:53.790: E/Volley(31902):    at com.google.gson.Gson.fromJson(Gson.java:495)
10-08 17:07:53.790: E/Volley(31902):    at com.google.gson.Gson.fromJson(Gson.java:444)
10-08 17:07:53.790: E/Volley(31902):    at com.google.gson.Gson.fromJson(Gson.java:396)
10-08 17:07:53.790: E/Volley(31902):    at com.google.gson.Gson.fromJson(Gson.java:372)
10-08 17:07:53.790: E/Volley(31902):    at fr.free.nrw.commons.upload.MwVolleyApi$QueryRequest.parseNetworkResponse(MwVolleyApi.java:140)
10-08 17:07:53.790: E/Volley(31902):    at com.android.volley.NetworkDispatcher.run(NetworkDispatcher.java:123)
10-08 17:07:53.790: E/fr.free.nrw.commons.upload.MwVolleyApi$LogResponseErrorListener(31902): com.android.volley.VolleyError: java.lang.RuntimeException: No-args constructor for class fr.free.nrw.commons.upload.MwVolleyApi$Page does not exist. Register an InstanceCreator with Gson for this type to fix this problem.

Relevant code:

private static class QueryRequest extends JsonRequest<QueryResponse> {
    private static final String TAG = QueryRequest.class.getName();

    public QueryRequest(String url,
                        Response.Listener<QueryResponse> listener,
                        Response.ErrorListener errorListener) {
        super(Request.Method.GET, url, null, listener, errorListener);
    }

    @Override
    protected Response<QueryResponse> parseNetworkResponse(NetworkResponse response) {
        String json = parseString(response);
        QueryResponse queryResponse = GSON.fromJson(json, QueryResponse.class);
        return Response.success(queryResponse, cacheEntry(response));
    }

    private Cache.Entry cacheEntry(NetworkResponse response) {
        return HttpHeaderParser.parseCacheHeaders(response);
    }

    private String parseString(NetworkResponse response) {
        try {
            return new String(response.data, HttpHeaderParser.parseCharset(response.headers));
        } catch (UnsupportedEncodingException e) {
            return new String(response.data);
        }
    }
}


private static class QueryResponse {
    private Query query = new Query();

    private String printSet() {
        if (categorySet == null || categorySet.isEmpty()) {
            GpsCatExists.setGpsCatExists(false);
            Log.d(TAG, "gpsCatExists=" + GpsCatExists.getGpsCatExists());
            return "No collection of categories";
        } else {
            GpsCatExists.setGpsCatExists(true);
            Log.d(TAG, "gpsCatExists=" + GpsCatExists.getGpsCatExists());
            return "CATEGORIES FOUND" + categorySet.toString();
        }

    }

    @Override
    public String toString() {
        if (query != null) {
            return "query=" + query.toString() + "\n" + printSet();
        } else {
            return "No pages found";
        }
    }
}

private static class Query {
    private Page [] pages;

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder("pages=" + "\n");
        if (pages != null) {
            for (Page page : pages) {
                builder.append(page.toString());
                builder.append("\n");
            }
            builder.replace(builder.length() - 1, builder.length(), "");
            return builder.toString();
        } else {
            return "No pages found";
        }
    }
}

private static class Page {
    private int pageid;
    private int ns;
    private String title;
    private Category[] categories;
    private Category category;

    public Page() {
    }

    @Override
    public String toString() {

        StringBuilder builder = new StringBuilder("PAGEID=" + pageid + " ns=" + ns + " title=" + title + "\n" + " CATEGORIES= ");

        if (categories == null || categories.length == 0) {
            builder.append("no categories exist\n");
        } else {
            for (Category category : categories) {
                builder.append(category.toString());
                builder.append("\n");
                if (category != null) {
                    String categoryString = category.toString().replace("Category:", "");
                    categorySet.add(categoryString);
                }
            }
        }

        categoryList = new ArrayList<String>(categorySet);
        builder.replace(builder.length() - 1, builder.length(), "");
        return builder.toString();
    }
}

private static class Category {
    private String title;

    @Override
    public String toString() {
        return title;
    }
}

Upvotes: 2

Views: 944

Answers (1)

Mousa
Mousa

Reputation: 2290

Gson cannot instantiate private nested classes. Make your Page class public:

public static class Page {...}

Upvotes: 3

Related Questions