StackOverflowError al serializar un objeto en Java

Estoy escribiendo una aplicación en Java usando Swing. Estoy intentando implementar la funcionalidad para guardar y cargar estados de simulación en la simulación que estoy ejecutando. Toda la simulación se mantiene como un objeto desconectado de Swing. Estoy tratando de serializar mi clase de simulación con este código:

public void saveSimulationState(String simulationFile) { try { Serializable object = this.sm; ObjectOutputStream objstream = new ObjectOutputStream(new FileOutputStream(simulationFile)); objstream.writeObject(object); objstream.close(); } catch (IOException e) { System.out.println(e.getMessage()); } } 

Pero me sale el siguiente error (es enorme).

 Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError at java.io.ObjectStreamClass.processQueue(ObjectStreamClass.java:2234) at java.io.ObjectStreamClass.lookup(ObjectStreamClass.java:266) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1106) at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1509) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1474) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326) at java.util.ArrayList.writeObject(ArrayList.java:570) at sun.reflect.GeneratedMethodAccessor6.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1461) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150) at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1509) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1474) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326) at java.util.ArrayList.writeObject(ArrayList.java:570) at sun.reflect.GeneratedMethodAccessor6.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1461) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150) at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1509) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1474) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326) at java.util.ArrayList.writeObject(ArrayList.java:570) at sun.reflect.GeneratedMethodAccessor6.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1461) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150) at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1509) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1474) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326) at java.util.ArrayList.writeObject(ArrayList.java:570) at sun.reflect.GeneratedMethodAccessor6.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1461) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150) at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1509) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1474) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326) at java.util.ArrayList.writeObject(ArrayList.java:570) at sun.reflect.GeneratedMethodAccessor6.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1461) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150) at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1509) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1474) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326) at java.util.ArrayList.writeObject(ArrayList.java:570) at sun.reflect.GeneratedMethodAccessor6.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1461) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150) at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1509) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1474) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326) at java.util.ArrayList.writeObject(ArrayList.java:570) at sun.reflect.GeneratedMethodAccessor6.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1461) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150) at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1509) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1474) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326) at java.util.ArrayList.writeObject(ArrayList.java:570) at sun.reflect.GeneratedMethodAccessor6.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1461) 

¿Alguien puede decirme qué está causando esta excepción?

Publicación interesante de Chen:

Al depurar un desbordamiento de stack, desea centrarse en la parte repetitiva recursiva

En tu caso:

  at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150) at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1509) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1474) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326) at java.util.ArrayList.writeObject(ArrayList.java:570) at sun.reflect.GeneratedMethodAccessor6.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1461) 

Si busca en la base de datos de seguimiento de defectos para ver si se trata de un problema conocido o no, es poco probable que la búsqueda de las funciones superiores en la stack encuentre algo interesante. Eso es porque los desbordamientos de stack tienden a ocurrir en un punto aleatorio en la recursión; cada desbordamiento de stack se ve superficialmente diferente de todos los demás, incluso si son del mismo desbordamiento de stack.

Una vez que superas la confusión inicial, la traza de la stack se establece en un bonito patrón repetitivo que consta de las mismas funciones x una y otra vez.
Identificar el inicio del patrón de repetición no es importante, porque el punto de partida será diferente para cada choque, de la misma manera que la nota precisa que excede su rango de canto varía de golpe a golpe.

Una vez que haya identificado la parte que se repite, seleccione una función que sea algo inusual y búsquela en su base de datos de defectos .

Por ejemplo , una serialización ArrayList predeterminada.

Aquí su GrahPanel refiere a una Simulation que hace referencia a Graph , con ArrayList de Sensor y Edge potencialmente largos …

La serialización de Java mantiene un registro de cada objeto escrito en una secuencia. Si el mismo objeto se encuentra por segunda vez, solo se escribe una referencia a él en la secuencia, y no una segunda copia del objeto; así que las referencias circulares no son el problema aquí.

Pero la serialización es vulnerable al desbordamiento de la stack para ciertos tipos de estructuras; por ejemplo, una lista enlazada larga sin métodos especiales writeObject () se serializará escribiendo recursivamente cada enlace. Si tiene 100.000 enlaces, intentará utilizar 100.000 marcos de stack, y es muy probable que falle con StackOverflowError .

Es posible definir un método writeObject () para dicha clase de lista que, cuando el primer enlace se serializa, simplemente recorre la lista y serializa cada enlace de forma iterativa; esto evitará que se use el mecanismo recursivo por defecto.

Debería considerar writeObject readObject métodos writeObject / readObject de su clase de Simulación para serializar solo los datos relevantes (y no toda la estructura de objetos contenidos por defecto) o etiquetar transitorios para que no sean objetos serializados. También puede usar la interfaz Externalizable si es necesario.

Por cierto, es posible que desee leer este interesante artículo para comenzar.

Tienes ArrayLists profundamente nesteds.

Creo que tal vez es solo profundizar primero, y eso significa que está yendo para el sensor inferior, que es demasiado profundo.

¿Tal vez podrías crear una estructura personalizada con sensores comenzando con el sensor inferior?

¿O tal vez deberás proporcionar tu propia serialización para manejarlo? http://java.sun.com/developer/technicalArticles/Programming/serialization/

Debe crear una clase de contenedor para los objetos que desea almacenar. No almacenaría el objeto completo con toda la lógica dentro.

Almacene el primer campo por campo para encontrar el elemento que es grande para almacenarlo de esa manera. Luego ponga un punto de inflexión en el método y eche un vistazo al elemento de campo. ¿El elemento contiene enlaces que se vinculan entre sí?

Y después de que haya hecho todo eso solo use XStream en su lugar si solo desea guardar en un archivo.

Ejecuta Java con stacks más grandes

Este código debería servir como modelo, ya que soluciona el problema de stackoverflow en la serialización. Utiliza la memoria en el lugar de la recursión. Aunque no es apto para ser considerado universal como un serializador, serializa y deserializa las clases con las que se probó.

 import java.io.*; import java.util.*; import java.lang.reflect.*; import android.util.*; public class SequentialObjectInputStream extends DataInputStream implements ObjectInput { interface FieldPutAction { void put(Object obj, Field field) throws IllegalAccessException, IOException; } interface ArrayPutAction { void put(Object obj, int index) throws ArrayIndexOutOfBoundsException, IOException; } public HashMap Primatives; public HashMap ArrayPrimatives; public SequentialObjectInputStream(InputStream stream) { super(stream); Primatives = new HashMap(); try { Primatives.put(boolean.class, new FieldPutAction() { public void put(Object obj, Field field) throws IllegalAccessException, IOException { boolean x = readBoolean(); field.setBoolean(obj, x); } }); Primatives.put(byte.class, new FieldPutAction() { public void put(Object obj, Field field) throws IllegalAccessException, IOException { byte x = readByte(); field.setByte(obj, x); } }); Primatives.put(short.class, new FieldPutAction() { public void put(Object obj, Field field) throws IllegalAccessException, IOException { short x = readShort(); field.setShort(obj, x); } }); Primatives.put(int.class, new FieldPutAction() { public void put(Object obj, Field field) throws IllegalAccessException, IOException { int x = readInt(); field.setInt(obj, x); } }); Primatives.put(long.class, new FieldPutAction() { public void put(Object obj, Field field) throws IllegalAccessException, IOException { long x = readLong(); field.setLong(obj, x); } }); Primatives.put(char.class, new FieldPutAction() { public void put(Object obj, Field field) throws IllegalAccessException, IOException { char x = readChar(); field.setChar(obj, x); } }); Primatives.put(float.class, new FieldPutAction() { public void put(Object obj, Field field) throws IllegalAccessException, IOException { float x = readFloat(); field.setFloat(obj, x); } }); Primatives.put(double.class, new FieldPutAction() { public void put(Object obj, Field field) throws IllegalAccessException, IOException { double x = readDouble(); field.setDouble(obj, x); } }); Primatives.put(String.class, new FieldPutAction() { public void put(Object obj, Field field) throws IllegalAccessException, IOException { String x = readUTF(); field.set(obj, x); } }); } catch(Exception e) { Log.e("SOb", Log.getStackTraceString(e)); } ArrayPrimatives = new HashMap(); try { ArrayPrimatives.put(boolean.class, new ArrayPutAction() { public void put(Object obj, int index) throws ArrayIndexOutOfBoundsException, IOException { boolean x = readBoolean(); Array.setBoolean(obj, index, x); } }); ArrayPrimatives.put(byte.class, new ArrayPutAction() { public void put(Object obj, int index) throws ArrayIndexOutOfBoundsException, IOException { byte x = readByte(); Array.setByte(obj, index, x); } }); ArrayPrimatives.put(short.class, new ArrayPutAction() { public void put(Object obj, int index) throws ArrayIndexOutOfBoundsException, IOException { short x = readShort(); Array.setShort(obj, index, x); } }); ArrayPrimatives.put(int.class, new ArrayPutAction() { public void put(Object obj, int index) throws ArrayIndexOutOfBoundsException, IOException { int x = readInt(); Array.setInt(obj, index, x); } }); ArrayPrimatives.put(long.class, new ArrayPutAction() { public void put(Object obj, int index) throws ArrayIndexOutOfBoundsException, IOException { long x = readLong(); Array.setLong(obj, index, x); } }); ArrayPrimatives.put(char.class, new ArrayPutAction() { public void put(Object obj, int index) throws ArrayIndexOutOfBoundsException, IOException { char x = readChar(); Array.setChar(obj, index, x); } }); ArrayPrimatives.put(float.class, new ArrayPutAction() { public void put(Object obj, int index) throws ArrayIndexOutOfBoundsException, IOException { float x = readFloat(); Array.setFloat(obj, index, x); } }); ArrayPrimatives.put(double.class, new ArrayPutAction() { public void put(Object obj, int index) throws ArrayIndexOutOfBoundsException, IOException { double x = readDouble(); Array.setDouble(obj, index, x); } }); ArrayPrimatives.put(String.class, new ArrayPutAction() { public void put(Object obj, int index) throws ArrayIndexOutOfBoundsException, IOException { String x = readUTF(); Array.set(obj, index, x); } }); } catch(Exception e) { Log.e("SOb", Log.getStackTraceString(e)); } } @Override public Object readObject() throws ClassNotFoundException, IOException { long Total = readLong(); Log.i("SOb", "readObject : " + Long.toString(Total) + " objects in graph"); HashMap References = new HashMap(); long currentId = 1; HashMap> refCache = new HashMap>(); final HashMap> arefCache = new HashMap>(); for (int I=0; I < Total; I++) { String Name = readUTF(); Class C = Class.forName(Name); Log.i("SOb", "Object of "+C.getCanonicalName() +" on graph"); int adim = 0; Object O = null; if (C.isArray()) { Class ComponentType = C.getComponentType(); int Size = readInt(); Log.i("SOb", "array of "+ComponentType.getCanonicalName() + ", " + Long.toString(Size) + " elements"); O = Array.newInstance(ComponentType, Size); References.put(currentId, O); currentId++; ArrayPutAction action = null; if (ArrayPrimatives.keySet().contains(ComponentType)) { action = ArrayPrimatives.get(ComponentType); } else { arefCache.put(O, new HashMap()); action = new ArrayPutAction() { public void put(Object O, int Index) throws ArrayIndexOutOfBoundsException , IOException { long Ref = readLong(); arefCache.get(O).put(Index, Ref); } }; } for (int index=0; index< Size; index++) { action.put(O,index); } } else { try { O = C.getConstructor(new Class[0]).newInstance(new Object[0]); } catch(InstantiationException e) { Log.e("SOb", Log.getStackTraceString(e)); } catch(NoSuchMethodException e) { Log.e("SOb", Log.getStackTraceString(e)); } catch(IllegalAccessException e) { Log.e("SOb", Log.getStackTraceString(e)); } catch(InvocationTargetException e) { Log.e("SOb", Log.getStackTraceString(e)); } References.put(currentId, O); currentId++; refCache.put(O, new HashMap()); for (Field F : C.getFields()) { if (F.isAccessible()) { Class T = F.getType(); if (Primatives.containsKey(T)) { try { Primatives.get(T).put(O, F); } catch (IllegalAccessException e) { } } else { refCache.get(O).put(F, readLong()); } } } } } for (long I=0; I < Total; I++) { Object O = References.get(I+1); Class C = O.getClass(); //Log.i("SOb", "get reference "+Long.toString(I)+" "+C.getCanonicalName()); if (C.isArray()) { HashMap aref_table = arefCache.get(O); if (ArrayPrimatives.containsKey(C.getComponentType()) == false) { int len = Array.getLength(O); for (int index=0; index ref_table = refCache.get(O); for (Field F : C.getFields()) { if (F.isAccessible()) { Class T = F.getType(); if (Primatives.containsKey(T) == false) { try { long r = ref_table.get(F); Object ref = r == 0 ? null : References.get(r); F.set(O, ref); } catch (IllegalAccessException e) { Log.e("SOb", Log.getStackTraceString(e)); } } } } } } return References.get((Long) (long) 1); } } import java.io.*; import java.util.*; import java.lang.reflect.*; import android.util.*; public class SequentialObjectOutputStream extends DataOutputStream implements ObjectOutput { interface FieldGetAction { void get(Object obj, Field field) throws IllegalAccessException, IOException; } interface ArrayGetAction { void get(Object array, int Index) throws ArrayIndexOutOfBoundsException, IOException; } public HashMap Primatives; public HashMap ArrayPrimatives; public SequentialObjectOutputStream(OutputStream stream) { super(stream); Primatives = new HashMap(); try { Primatives.put(boolean.class, new FieldGetAction() { public void get(Object obj, Field field) throws IllegalAccessException, IOException { boolean x = field.getBoolean(obj); writeBoolean(x); } }); Primatives.put(byte.class, new FieldGetAction() { public void get(Object obj, Field field) throws IllegalAccessException, IOException { byte x = field.getByte(obj); writeByte(x); } }); Primatives.put(short.class, new FieldGetAction() { public void get(Object obj, Field field) throws IllegalAccessException, IOException { short x = field.getShort(obj); writeShort(x); } }); Primatives.put(int.class, new FieldGetAction() { public void get(Object obj, Field field) throws IllegalAccessException, IOException { int x = field.getInt(obj); writeInt(x); } }); Primatives.put(long.class, new FieldGetAction() { public void get(Object obj, Field field) throws IllegalAccessException, IOException { long x = field.getLong(obj); writeLong(x); } }); Primatives.put(char.class, new FieldGetAction() { public void get(Object obj, Field field) throws IllegalAccessException, IOException { char x = field.getChar(obj); writeChar(x); } }); Primatives.put(float.class, new FieldGetAction() { public void get(Object obj, Field field) throws IllegalAccessException, IOException { float x = field.getFloat(obj); writeFloat(x); } }); Primatives.put(double.class, new FieldGetAction() { public void get(Object obj, Field field) throws IllegalAccessException, IOException { double x = field.getDouble(obj); writeDouble(x); } }); Primatives.put(String.class, new FieldGetAction() { public void get(Object obj, Field field) throws IllegalAccessException, IOException { String x = (String) field.get(obj); writeUTF(x); } }); } catch(Exception e) { Log.e("SOb", Log.getStackTraceString(e)); } ArrayPrimatives = new HashMap(); try { ArrayPrimatives.put(boolean.class, new ArrayGetAction() { public void get(Object obj, int index) throws ArrayIndexOutOfBoundsException, IOException { boolean x = Array.getBoolean(obj, index); writeBoolean(x); } }); ArrayPrimatives.put(byte.class, new ArrayGetAction() { public void get(Object obj, int index) throws ArrayIndexOutOfBoundsException, IOException { byte x = Array.getByte(obj, index); writeByte(x); } }); ArrayPrimatives.put(short.class, new ArrayGetAction() { public void get(Object obj, int index) throws ArrayIndexOutOfBoundsException, IOException { short x = Array.getShort(obj, index); writeShort(x); } }); ArrayPrimatives.put(int.class, new ArrayGetAction() { public void get(Object obj, int index) throws ArrayIndexOutOfBoundsException, IOException { int x = Array.getInt(obj, index); writeInt(x); } }); ArrayPrimatives.put(long.class, new ArrayGetAction() { public void get(Object obj, int index) throws ArrayIndexOutOfBoundsException, IOException { long x = Array.getLong(obj, index); writeLong(x); } }); ArrayPrimatives.put(char.class, new ArrayGetAction() { public void get(Object obj, int index) throws ArrayIndexOutOfBoundsException, IOException { char x = Array.getChar(obj, index); writeChar(x); } }); ArrayPrimatives.put(float.class, new ArrayGetAction() { public void get(Object obj, int index) throws ArrayIndexOutOfBoundsException, IOException { float x = Array.getFloat(obj, index); writeFloat(x); } }); ArrayPrimatives.put(double.class, new ArrayGetAction() { public void get(Object obj, int index) throws ArrayIndexOutOfBoundsException, IOException { double x = Array.getDouble(obj, index); writeDouble(x); } }); ArrayPrimatives.put(String.class, new ArrayGetAction() { public void get(Object obj, int index) throws ArrayIndexOutOfBoundsException, IOException { String x = (String) Array.get(obj, index); writeUTF(x); } }); } catch(Exception e) { Log.e("SOb", Log.getStackTraceString(e)); } } class State { public ArrayList OStack = new ArrayList(); public long currentId = 1; public HashMap References = new HashMap(); } public void writeObject(Object A) throws IOException, NotSerializableException { final State state = new State(); state.OStack.add(0, A); LinkedList ForStack = new LinkedList(); while (!(state.OStack.size() == 0)) { Object Current = state.OStack.get(0); state.OStack.remove(0); if (((Serializable) Current) == null) { throw new NotSerializableException(); } //Type C = Current.getClass(); Class C = Current.getClass(); Log.i("SOb", "placing #"+Long.toString(state.currentId)+" of "+C.getCanonicalName()+" on graph"); state.References.put(Current, state.currentId); state.currentId++; ForStack.add(Current); if (C.isArray()) { //Array array = (Array) Current; Class Ctype = C.getComponentType(); if (ArrayPrimatives.keySet().contains(Ctype) == false) { for (int I=0; I 


Tuve un problema similar. Después de mucha caza, encontré una horquilla de Kryo diseñada para manejar objetos profundamente nesteds. A través de https://github.com/EsotericSoftware/kryo/issues/103 , clone and mvn clean install https://github.com/romix/kryo/tree/kryo-2.23-continuations . Actualmente es com.esotericsoftware.kryo:kryo:2.23-SNAPSHOT .