gson在运行tojson时导致stackoverflow错误

qxsslcnc  于 2021-07-07  发布在  Java
关注(0)|答案(2)|浏览(310)

在我开始这个问题之前,我知道有很多类似的问题,但是我无法控制我转换成json的对象,因此我不能简单地排除引用同一对象的字段。
我发现解释我的应用程序的结构有助于人们更好地理解我的问题,所以我来了!
我有两个应用程序,一个逻辑应用程序(所有繁重的操作都在这里发生)和一个 Jmeter 化的应用程序(一个注入到旧游戏中并且必须保持轻量级的应用程序)。
这两个应用程序通过rmi(远程方法调用)进行通信。
插入指令的应用程序使用反射api将从旧游戏中获取的对象发送到逻辑应用程序(通过rmi,因为这是2的通信方式)。
大多数对象是不可序列化的(不要实现可序列化的,并且不能序列化,除非使用bcl库,我不想这样做,因为强制序列化对象是不好的做法,因为它们可能会导致问题(安全性)序列化)。
正如上面提到的,由于它们是不可序列化的,所以我不能将它们转换成字节数组并发送,所以我使用了gson,它不需要对象来实现可序列化。
当我第一次尝试序列化这些对象时,除了在尝试序列化它们时有几个对象打印出堆栈溢出错误(tojson)外,其他方法都是有效的。
我认为发生错误的原因:对象有一个超类。。对象包含自身的引用(字段)
我不能显示对象本身,因为它在一个游戏和它的模糊,但我可以显示我的 Package ,它显示字段和它们的类型。
对象本身(在其上执行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));
    }
}

上面的对象只包含1个字段,它是“composite”,下面是npccomposite的 Package 器:

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);
    }
}

如果您注意到,对象本身(npc)有一个超类,这是超类的 Package 器:我在具有不明显返回类型的字段getter旁边添加了一个注解。

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库可以序列化这些对象?感谢您的回答!
谢谢您!

0h4hbjxa

0h4hbjxa1#

通过使用xstream并向其中添加对象的类路径,我成功地解决了这个问题。

pengsaosao

pengsaosao2#

我认为除了使用bcel库和将循环字段更改为transient或使类及其内容可序列化之外,没有其他方法可以绕过它。。

相关问题