jsonview jsonfilter fields java swing serialization stack-overflow

jsonfilter - StackOverflowError al serializar un objeto en Java



jackson ignore fields (8)

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í?

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?


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.


Ejecuta Java con stacks más grandes


Publicación interesante de Chen:

Al depurar un desbordamiento de pila, 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 pila encuentre algo interesante. Eso es porque los desbordamientos de pila tienden a ocurrir en un punto aleatorio en la recursión; cada desbordamiento de pila se ve superficialmente diferente de todos los demás, incluso si son del mismo desbordamiento de pila.

Una vez que superas la confusión inicial, la traza de la pila 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 pila 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 pila, y es muy probable que falle con Error .

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.


Tienes ArrayLists profundamente anidados.

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/


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


Este código debería servir como modelo, ya que soluciona el problema de 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<Class, FieldPutAction> Primatives; public HashMap<Class, ArrayPutAction> ArrayPrimatives; public SequentialObjectInputStream(InputStream stream) { super(stream); Primatives = new HashMap<Class, FieldPutAction>(); 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<Class, ArrayPutAction>(); 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<Long, Object> References = new HashMap<Long, Object>(); long currentId = 1; HashMap<Object, HashMap<Field, Long>> refCache = new HashMap<Object, HashMap<Field, Long>>(); final HashMap<Object, HashMap<Integer, Long>> arefCache = new HashMap<Object, HashMap<Integer,Long>>(); 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<Integer, Long>()); 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<Field, Long>()); 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<Integer,Long> aref_table = arefCache.get(O); if (ArrayPrimatives.containsKey(C.getComponentType()) == false) { int len = Array.getLength(O); for (int index=0; index<len; index++) { long r = aref_table.get(index); Object ref = r == 0 ? null : References.get(r); Array.set(O, index, ref); } } } else { HashMap<Field, Long> 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<Class, FieldGetAction> Primatives; public HashMap<Class, ArrayGetAction> ArrayPrimatives; public SequentialObjectOutputStream(OutputStream stream) { super(stream); Primatives = new HashMap<Class, FieldGetAction>(); 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<Class, ArrayGetAction>(); 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<Object> OStack = new ArrayList<Object>(); public long currentId = 1; public HashMap<Object, Long> References = new HashMap<Object, Long>(); } public void writeObject(Object A) throws IOException, NotSerializableException { final State state = new State(); state.OStack.add(0, A); LinkedList<Object> ForStack = new LinkedList<Object>(); 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<Array.getLength(Current); I++) { Object o = Array.get(Current, I); if ((o != null) && (state.References.keySet().contains(o) == false)) { if (state.OStack.contains(o) == false) state.OStack.add(state.OStack.size(), o); } } } } else { for (Class Cur = C; Cur != null; Cur = Cur.getSuperclass()) { Field[] fields = Cur.getDeclaredFields(); for (Field f : fields) { if (Modifier.isStatic(f.getModifiers())) { continue; } f.setAccessible(true); if (f.isAccessible() == false) { // Log.i("SOb", " isAccessible = false"); continue; } Class type = f.getType(); //Log.i("SOb", " field /""+f.getName()+"/" of "+type.getCanonicalName()); if (Primatives.keySet().contains(type) == false) { try { Object o = f.get(Current); if ((o != null) && (state.References.keySet().contains(o) == false)) { if (state.OStack.contains(o) == false) state.OStack.add(state.OStack.size(), o); } } catch (IllegalAccessException e) { Log.e("SOb", Log.getStackTraceString(e)); } } } } } } writeLong(state.References.size()); for (Object O : ForStack ) { Serializable s = (Serializable) O; // if (s != null) { Class cl = O.getClass(); String name = cl.getName(); writeUTF(name); if (cl.isArray()) { Class components = cl.getComponentType(); ArrayGetAction action; //Array array = (Array) O; if (ArrayPrimatives.keySet().contains(components)) { action = ArrayPrimatives.get(components); } else { action = new ArrayGetAction() { public void get(Object array, int index) throws ArrayIndexOutOfBoundsException, IOException { Object O = Array.get(array, index); if (O==null) writeLong(0); else writeLong(state.References.get(O)); } }; } int length = Array.getLength(O); writeInt(length); for (int I=0; I<length; I++) { action.get(O, I); } } else { for (Class Cur = cl; Cur != null; Cur = Cur.getSuperclass()) { Field[] fields = Cur.getDeclaredFields(); for (Field F : fields) { Class FieldType = F.getType(); F.setAccessible(true); if (F.isAccessible() && (Modifier.isStatic(FieldType.getModifiers()))) { FieldGetAction action; //Array array = (Array) O; if (Primatives.keySet().contains(FieldType)) { action = Primatives.get(FieldType); } else { action = new FieldGetAction() { public void get(Object obj, Field index) throws IllegalAccessException, IOException { Object O = index.get(obj); if (O==null) writeLong(0); else writeLong(state.References.get(O)); } }; } try { action.get(O, F); } catch (IllegalAccessException e) { Log.e("SOb", Log.getStackTraceString(e)); } } } } } } } } }