[英]GSON causing StackOverFlow Error when running toJSON
在我開始提問之前,我知道有很多類似的問題,但我無法控制我變成 JSON 的對象,因此我不能簡單地排除引用相同 object 的字段。
我發現解釋我的應用程序的結構可以幫助人們更多地理解我的問題,所以我開始了!
我有 2 個應用程序,一個 Logic 應用程序(所有繁重的操作都發生在這里)和一個 Instrumented 應用程序(一個注入舊游戲並且必須保持輕量級的應用程序)。
這兩個應用程序通過 RMI(遠程方法調用)進行通信。
檢測應用程序將使用反射 API 從舊游戲中獲取的對象發送到邏輯應用程序(通過 RMI,因為這就是 2 通信的方式)。
大多數對象都是不可序列化的(不要實現可序列化,並且不能序列化,除非使用我不想這樣做的 BCL 庫,因為強制序列化對象是不好的做法,因為它們可能會導致問題(安全)序列化)。
如上段所述,由於它們是不可序列化的,我不能只將它們轉換為字節 arrays 並發送,所以我已經完成並使用了 GSON,它不需要對象實現可序列化。
當我第一次嘗試序列化對象時,它可以工作,除了幾個對象在嘗試序列化它們時打印出堆棧溢出錯誤(toJSON)。
為什么我認為發生錯誤:object 有一個超類.. object 包含自身的引用(字段)
我無法顯示 object 本身,因為它在游戲中並且被混淆了,但我可以向它展示我的包裝器,它顯示了字段及其類型。
Object 本身(在其上執行 toJSON 時會導致堆棧溢出錯誤):
public class NPC extends Model {
//The Class itself contains 1 field which is "Composite"
public NPC(Object object) {
super(object);
}
public NPCComposite getComposite() {
return new NPCComposite(getFieldValue("Npc.composite", object));
}
}
上面的 Object 僅包含 1 個字段,它是“復合”,這是 NPCComposite 的包裝器:
public class NPCComposite extends Wrapper {
//Contains 3 Fields: String[], String, int (Nothing out of the ordinary)
public NPCComposite(Object object) {
super(object);
}
public String[] getActions() {
return (String[]) getFieldValue("NpcComposite.actions", object);
}
public int getID() {
return (int) getFieldValue("NpcComposite.id", object);
}
public String getName() {
return (String) getFieldValue("NpcComposite.name", object);
}
}
如果您注意到,Object 本身(NPC)有一個超類,這是超類的包裝器:我在具有不明顯返回類型的字段獲取器旁邊添加了一條注釋。
public class Model extends Render {
public Model(Object object) {
super(object);
}
public int getFineX() {
return (int) getFieldValue("Model.localX", object);
}
public int getFineY() {
return (int) getFieldValue("localY", object);
}
public int getAnimation() {
return (int) getFieldValue("animation", object);
}
public int getAnimationDelay() {
return (int) getFieldValue("animationDelay", object);
}
public int getCombatTime() {
return (int) getFieldValue("combatTime", object);
}
public int getStandAnimation() {
return (int) getFieldValue("standAnimation", object);
}
public int getFrameOne() {
return (int) getFieldValue("frameOne", object);
}
public int getFrameTwo() {
return (int) getFieldValue("Model.frameTwo", object);
}
public Object getHealthBars() { //Returns a Health Bar Object
return getFieldValue("Model.healthBars", object);
}
public Object getHitCycles() { //Returns an Integer 1D Array
return getFieldValue("Model.hitCycles", object);
}
public Object getHitDamages() { //Returns an Integer 1D Array
return getFieldValue("Model.hitDamages", object);
}
public Object getHitTypes() { //Returns an Integer 1D Array
return getFieldValue("Model.hitTypes", object);
}
public int getInteracting() {
return (int) getFieldValue("Model.interacting", object);
}
public Object getMessage() { //Returns a String
return getFieldValue("Model.message", object);
}
public int getOrientation() {
return (int) getFieldValue("Model.orientation", object);
}
public int getQueueSize() {
return (int) getFieldValue("Model.queueSize", object);
}
public Object getQueueTraversed() { //Returns a byte 1D array
return getFieldValue("Model.queueTraversed", object);
}
public Object getQueueX() { //Returns a 1D int array
return getFieldValue("Model.queueX", object);
}
public Object getQueueY() { //Returns a 1D int array
return getFieldValue("Model.queueY", object);
}
public int getRuntimeAnimation() {
return (int) getFieldValue("Model.runtimeAnimation", object);
}
}
主要方法:
Gson g = new Gson();
String res = g.toJson(NPCObject);
錯誤:
java.rmi.ServerError: Error occurred in server thread; nested exception is:
java.lang.StackOverflowError
at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:303)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:279)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:163)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:235)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:180)
at com.sun.proxy.$Proxy0.getGSONValue(Unknown Source)
at main.Instance.test(Instance.java:29)
Caused by: java.lang.StackOverflowError
at java.lang.AbstractStringBuilder.append(Unknown Source)
at java.lang.StringBuffer.append(Unknown Source)
at java.io.StringWriter.write(Unknown Source)
at com.google.gson.stream.JsonWriter.string(JsonWriter.java:590)
at com.google.gson.stream.JsonWriter.writeDeferredName(JsonWriter.java:401)
at com.google.gson.stream.JsonWriter.value(JsonWriter.java:526)
at com.google.gson.internal.bind.TypeAdapters$11.write(TypeAdapters.java:311)
at com.google.gson.internal.bind.TypeAdapters$11.write(TypeAdapters.java:296)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:69)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:127)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:245)
at com.google.gson.Gson$FutureTypeAdapter.write(Gson.java:1027)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:69)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:127)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:245)
我的問題是:有沒有辦法解決這個錯誤? 還是有任何其他可以序列化此類對象的 JSON 庫? 任何答案表示贊賞!
謝謝!
我已經通過使用 XStream 並將對象的 class 路徑添加到它成功地解決了這個問題。
我認為除了使用 BCEL 庫並將循環字段更改為瞬態或使 class 可序列化及其內容之外,沒有其他辦法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.