java.lang.RuntimeException: Failed to invoke public com.example.syncapp.MessageBase() with no args

user1612863 picture user1612863 · Mar 10, 2013 · Viewed 30.2k times · Source
protected void doPost(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException {

  System.out.println(request.getParameter("msg").toString());
  String data = request.getParameter("msg").toString();
  Gson gson = new Gson();
  MessageBase msggg = gson.fromJson(data, MessageBase.class);
  //System.out.println(msggg.Id + msggg.MessageText);
}

public abstract class MessageBase implements Serializable {
  public int Id;
  public String MessageText;
  public Date ReceiveDate;
}

public class SyncSmsMessage extends MessageBase {
  public String SenderNum;  
}

The code works until MessageBase msggg=gson.fromJson(data, MessageBase.class);. I get this exception:

java.lang.RuntimeException: Failed to invoke public com.example.syncapp.MessageBase() with no args
  at com.google.gson.internal.ConstructorConstructor$2.construct(ConstructorConstructor.java:94)
  at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:162)
  at com.google.gson.Gson.fromJson(Gson.java:795)
  at com.google.gson.Gson.fromJson(Gson.java:761)
  at com.google.gson.Gson.fromJson(Gson.java:710)
  at com.google.gson.Gson.fromJson(Gson.java:682)
  at AndroidServlet.doPost(AndroidServlet.java:75)
  at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
  at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)

What I need to do? I put .jar in lib folder and i think the tomcat load the .jar well.

Answer

MikO picture MikO · Apr 20, 2013

From GSON User Guide:

While deserializing an Object, Gson needs to create a default instance of the class [...] Well-behaved classes that are meant for serialization and deserialization should have a no-argument constructor

Your problem is that GSON's Instance Creator needs a no-argument constructor in the class in which you want to deserialize the JSON response, namely MessageBase.

Otherwise, you need to write your own Instance Creator, like this.