diff options
author | mkuppe | 2010-10-06 18:53:24 +0000 |
---|---|---|
committer | mkuppe | 2010-10-06 18:53:24 +0000 |
commit | 1edaf31728164c2f6fe278355f68f1f94896e6e4 (patch) | |
tree | 864957dd3d966a08363b1fbcdafee9a244c6f6e5 /protocols | |
parent | 19e76a291c770347c11e5a90ffad0d31c78b8eee (diff) | |
download | org.eclipse.ecf-1edaf31728164c2f6fe278355f68f1f94896e6e4.tar.gz org.eclipse.ecf-1edaf31728164c2f6fe278355f68f1f94896e6e4.tar.xz org.eclipse.ecf-1edaf31728164c2f6fe278355f68f1f94896e6e4.zip |
RESOLVED - bug 327147: [r-OSGi][RemoteSrvs] Smart Serialization fails for Object[]s of non-Serializable objects
https://bugs.eclipse.org/bugs/show_bug.cgi?id=327147
Diffstat (limited to 'protocols')
2 files changed, 131 insertions, 70 deletions
diff --git a/protocols/bundles/ch.ethz.iks.r_osgi.remote/src/main/java/ch/ethz/iks/util/SmartObjectInputStream.java b/protocols/bundles/ch.ethz.iks.r_osgi.remote/src/main/java/ch/ethz/iks/util/SmartObjectInputStream.java index f63526213..8a28c1b4d 100644 --- a/protocols/bundles/ch.ethz.iks.r_osgi.remote/src/main/java/ch/ethz/iks/util/SmartObjectInputStream.java +++ b/protocols/bundles/ch.ethz.iks.r_osgi.remote/src/main/java/ch/ethz/iks/util/SmartObjectInputStream.java @@ -80,42 +80,61 @@ public final class SmartObjectInputStream extends ObjectInputStream { // java serialized object return in.readObject(); case 3: - // smart serialized object + return readSmartSerializedObject(); + case 4: + final int length = in.readByte(); final String clazzName = in.readUTF(); + final Class clazz = Class.forName(clazzName); + final Object[] array = (Object[]) java.lang.reflect.Array + .newInstance(clazz, length); + for (int i = 0; i < length; i++) { + final byte b = in.readByte(); + if(b == -1) { + array[i] = null; + } else { + array[i] = readSmartSerializedObject(); + } + } + return array; + default: + throw new IllegalStateException("Unhandled case " + cat); //$NON-NLS-1$ + } + } - // TODO: cache this information... - Class clazz = Class.forName(clazzName); + private Object readSmartSerializedObject() throws IOException, ClassNotFoundException { + // smart serialized object + final String clazzName = in.readUTF(); - try { - final Constructor constr = clazz.getDeclaredConstructor(null); - constr.setAccessible(true); - final Object newInstance = constr.newInstance(null); - - int fieldCount = in.readInt(); - while (fieldCount > -1) { - for (int i = 0; i < fieldCount; i++) { - final String fieldName = in.readUTF(); - final Object value = readObjectOverride(); - final Field field = clazz.getDeclaredField(fieldName); - - final int mod = field.getModifiers(); - if (!Modifier.isPublic(mod)) { - field.setAccessible(true); - } - - field.set(newInstance, value); + // TODO: cache this information... + Class clazz = Class.forName(clazzName); + + try { + final Constructor constr = clazz.getDeclaredConstructor(null); + constr.setAccessible(true); + final Object newInstance = constr.newInstance(null); + + int fieldCount = in.readInt(); + while (fieldCount > -1) { + for (int i = 0; i < fieldCount; i++) { + final String fieldName = in.readUTF(); + final Object value = readObjectOverride(); + final Field field = clazz.getDeclaredField(fieldName); + + final int mod = field.getModifiers(); + if (!Modifier.isPublic(mod)) { + field.setAccessible(true); } - clazz = clazz.getSuperclass(); - fieldCount = in.readInt(); + + field.set(newInstance, value); } - return newInstance; - } catch (final Exception e) { - e.printStackTrace(); - throw new IOException("Error while deserializing " + clazzName //$NON-NLS-1$ - + ": " + e.getMessage()); //$NON-NLS-1$ + clazz = clazz.getSuperclass(); + fieldCount = in.readInt(); } - default: - throw new IllegalStateException("Unhandled case " + cat); //$NON-NLS-1$ + return newInstance; + } catch (final Exception e) { + e.printStackTrace(); + throw new IOException("Error while deserializing " + clazzName //$NON-NLS-1$ + + ": " + e.getMessage()); //$NON-NLS-1$ } } diff --git a/protocols/bundles/ch.ethz.iks.r_osgi.remote/src/main/java/ch/ethz/iks/util/SmartObjectOutputStream.java b/protocols/bundles/ch.ethz.iks.r_osgi.remote/src/main/java/ch/ethz/iks/util/SmartObjectOutputStream.java index be03dd0c8..d352af1d0 100644 --- a/protocols/bundles/ch.ethz.iks.r_osgi.remote/src/main/java/ch/ethz/iks/util/SmartObjectOutputStream.java +++ b/protocols/bundles/ch.ethz.iks.r_osgi.remote/src/main/java/ch/ethz/iks/util/SmartObjectOutputStream.java @@ -75,61 +75,103 @@ public final class SmartObjectOutputStream extends ObjectOutputStream { out.writeUTF(id != null ? id : clazzName); out.writeUTF(obj.toString()); return; + } else if (isNestedSmartSerializedObject(obj)) { + final Object[] objArray = (Object[]) obj; + final String clazzname = objArray.getClass().getName(); + out.write(4); + out.writeByte(objArray.length); + out.writeUTF(clazzname.substring(2, clazzname.length() - 1)); + for (int i = 0; i < objArray.length; i++) { + final Object elem = objArray[i]; + if(elem == null) { + out.writeByte(-1); + } else { + writeSmartSerializedObject(elem); + } + } } else if (obj instanceof Serializable) { // java serializable classes out.writeByte(2); out.writeObject(obj); return; } else { - out.writeByte(3); - - // all other classes: try smart serialization - Class clazz = obj.getClass(); + writeSmartSerializedObject(obj); + } + } - if (SmartConstants.blackList.contains(clazz.getName())) { - throw new NotSerializableException("Class " + clazz.getName() //$NON-NLS-1$ - + " is not serializable"); //$NON-NLS-1$ + private boolean isNestedSmartSerializedObject(final Object obj) { + if(obj != null && obj instanceof Object[]) { + Object[] objArray = (Object[]) obj; + if(objArray.length > 0) { + // iterate to skip null + for(int i = 0; i < objArray.length; i++) { + if(objArray[i] instanceof Serializable) { + return false; + } + } + return true; } + } + return false; + } - out.writeUTF(clazz.getName()); - - // TODO: cache this information... - while (clazz != Object.class) { - // check for native methods - final Method[] methods = clazz.getDeclaredMethods(); - for (int j = 0; j < methods.length; j++) { - final int mod = methods[j].getModifiers(); - if (Modifier.isNative(mod)) { - throw new NotSerializableException( - "Class " //$NON-NLS-1$ - + clazz.getName() - + " contains native methods and is therefore not serializable."); //$NON-NLS-1$ - } + private void writeSmartSerializedObject(final Object obj) throws IOException, + NotSerializableException { + out.writeByte(3); + + // all other classes: try smart serialization + Class clazz = obj.getClass(); + + if (SmartConstants.blackList.contains(clazz.getName())) { + throw new NotSerializableException("Class " + clazz.getName() //$NON-NLS-1$ + + " is not serializable"); //$NON-NLS-1$ + } + + out.writeUTF(clazz.getName()); + + // TODO: cache this information... + while (clazz != Object.class) { + // check for native methods + final Method[] methods = clazz.getDeclaredMethods(); + for (int j = 0; j < methods.length; j++) { + final int mod = methods[j].getModifiers(); + if (Modifier.isNative(mod)) { + throw new NotSerializableException( + "Class " //$NON-NLS-1$ + + clazz.getName() + + " contains native methods and is therefore not serializable."); //$NON-NLS-1$ } + } - try { - final Field[] fields = clazz.getDeclaredFields(); - final int fieldCount = fields.length; - out.writeInt(fieldCount); - for (int i = 0; i < fieldCount; i++) { - final int mod = fields[i].getModifiers(); - if (Modifier.isStatic(mod)) { - continue; - } else if (!Modifier.isPublic(mod)) { - fields[i].setAccessible(true); - } - out.writeUTF(fields[i].getName()); - writeObjectOverride(fields[i].get(obj)); + try { + final Field[] fields = clazz.getDeclaredFields(); + final int fieldCount = fields.length; + int realFieldCount = 0; + for (int i = 0; i < fieldCount; i++) { + final int mod = fields[i].getModifiers(); + if (!(Modifier.isStatic(mod) || Modifier.isTransient(mod))) { + realFieldCount++; + } + } + out.writeInt(realFieldCount); + for (int i = 0; i < fieldCount; i++) { + final int mod = fields[i].getModifiers(); + if (Modifier.isStatic(mod) || Modifier.isTransient(mod)) { + continue; + } else if (!Modifier.isPublic(mod)) { + fields[i].setAccessible(true); } - } catch (final Exception e) { - throw new NotSerializableException( - "Exception while serializing " + obj.toString() //$NON-NLS-1$ - + ":\n" + e.getMessage()); //$NON-NLS-1$ + out.writeUTF(fields[i].getName()); + writeObjectOverride(fields[i].get(obj)); } - clazz = clazz.getSuperclass(); + } catch (final Exception e) { + throw new NotSerializableException( + "Exception while serializing " + obj.toString() //$NON-NLS-1$ + + ":\n" + e.getMessage()); //$NON-NLS-1$ } - out.writeInt(-1); + clazz = clazz.getSuperclass(); } + out.writeInt(-1); } /** |