On the server side I format an object into Json using:
String typeJson = new Gson().toJson(typeContainer);
On the client side I unwrap it using:
JSONContainer<CommonNoun> typeContainer = new Gson().fromJson(result,
new TypeToken<JSONContainer<CommonNoun>>(){}.getType());
In execution, the thread never gets past the line above (I have a println right after it).
I've checked that the "result" string received by the client is the same as "typeJson" generated on the server. It looks like this:
{"myObject":{"cid":{"oid":129},"name":"technology","form":1},"children":[]}
The 4 classes comprising the object being sent are:
public class JSONContainer<T> {
private T myObject;
private ArrayList<JSONContainer<T>> children;
public JSONContainer() {
}
public JSONContainer(T anObject) {
myObject = anObject;
children = new ArrayList<JSONContainer<T>>();
}
public void addChildren(ArrayList<JSONContainer<T>> newChildren) {
children.addAll(newChildren);
}
public void addChild(T concept) {
children.add(new JSONContainer<T>(concept));
}
public ArrayList<JSONContainer<T>> getChildren() {
return children;
}
public T getValue() {
return myObject;
}
public boolean hasChildren() {
if (children.size() > 0) return true;
else return false;
}
public String toString() {
return myObject.toString();
}
}
public class CommonNoun extends Concept {
/**
*
*/
private static final long serialVersionUID = 6444629581712454049L;
public CommonNoun() {
super();
}
public CommonNoun(String name, ConceptID cidIn) {
super(name, cidIn);
this.form = ConceptDefs.COMMON_NOUN;
}
}
public class Concept implements Serializable {
/**
*
*/
private static final long serialVersionUID = 2561549161503772431L;
private ConceptID cid = null;
private final String name;
Integer form = 0;
// ArrayList<ProperRelationship> myRelationships = null;
/* @Deprecated
public Concept(String name) {
this.name = name;
}*/
public Concept() {
name = "";
}
public Concept(String name, ConceptID cidIn) {
// this(name);
this.name = name;
cid = cidIn;
}
/*
* This should be over-ridden by any subclasses
*/
public Integer getForm() {
return form;
}
public ConceptID getID() {
return cid;
}
public void setID(ConceptID cidIn) {
cid = cidIn;
}
//this doesn't make any sense. Throw exception?
public String getName() {
return name;
}
public boolean isCommon() {
return true;
}
/**
*
* @return
*/
@Override
public String toString() {
return getName() + "(" + cid.toString() + ")";
}
public boolean equals(Concept other) {
return ((getID().equals(other.getID())));
}
}
public class ConceptID implements Serializable {
long oid;
public ConceptID() {
oid = -1;
}
public ConceptID(long oid) {
this.oid = oid;
}
public long getValue() {
return oid;
}
/**
*
* @return
*/
@Override
public String toString() {
return Long.toString(oid);
}
public Long toLong() {
return Long.valueOf(oid);
}
public boolean equals(ConceptID other) {
return (oid == other.getValue());
}
/**
* Factory model for generating ConceptIDs
*
* This one is here as a convenience as many IDs come in as a String from web POSTs
* @param idAsString
* @return
*/
static public ConceptID parseIntoID(String idAsString) {
ConceptID returnID = null;
try {
returnID = new ConceptID( Long.parseLong(idAsString) );
} catch (Exception e) {
System.err.println("Expected the string, " + idAsString + ", to be Long parsable.");
e.printStackTrace();
}
return returnID;
}
}
In my due-diligence to solve this, I worked to minimize the variables. Now I'm using the same json parser on both sides, and am writing the fromJson() statement in a way that doesn't produce a type warning when referring to the generics. I've studied the api for Gson (there are still combinations of GsonBuilder() left to exhaust), and I've searched StackOverflow and Google with terms such as "Gson" "Json" "parsing" "lock" "not complete." Prior to introducing my new generics class, I was experiencing success with using Gson to format and decompile json.
UPDATE:
After @ParanoidAndroid shared that parsing works in his environment, I tried to parse the json server-side, where it does work. So what's different about my server and client? The server project was generated by selecting one of the project wizard choices in Eclipse, and the client is a libGDX project. Another potential clue here is that libGDX implements its own class for json operations, called Json - was that done to address this situation?
Why aren't I using the native Json class? I started off that way, but could not get the formatting to match up. Json's is apparently non-standard, despite trying all the options available in setOutputType(OutputType).
How do I read this Generics correctly from JSON?
Next I tried to use Json server-side, but couldn't get the configuration to work: got as far as a ClassDefNotFound error.
One more variable I've controlled for is to copy and replace all of the classes being communicated through Json from the server to the client project to make sure everyone is using the same version (I'm sure there's some way to get projects to reference each other's classes, but I don't know it yet).
(final?) UPDATE:
Tried to create a thread dump as requested, but Java Mission Control wasn't having any of it.
Found documentation saying if I wanted to use the native Json class outside of libGDX, I should use jsonbeans: https://github.com/EsotericSoftware/jsonbeans/
Replaced my json serialization server-side with jsonbeans and can now use the native Json class client-side.
This is a poor answer to the question "Why doesn't this Gson parsing complete?":
"Because only the native Json parser works in some cases within libGDX. Furthermore, if you want that class to work with non-libGDX projects you better use it's companion class, jsonbeans."