After the map deserialization the following error occurs in case the deserialized entity has no such field defined but it exist in the stream:
Exception in thread "main" java.lang.NullPointerException
at org.jboss.marshalling.reflect.SerializableField$2.run(SerializableField.java:108)
at org.jboss.marshalling.reflect.SerializableField$2.run(SerializableField.java:106)
at java.security.AccessController.doPrivileged(Native Method)
at org.jboss.marshalling.reflect.SerializableField.getField(SerializableField.java:106)
at org.jboss.marshalling.river.RiverUnmarshaller.readFields(RiverUnmarshaller.java:1565)
at org.jboss.marshalling.river.RiverUnmarshaller.doInitSerializable(RiverUnmarshaller.java:1553)
at org.jboss.marshalling.river.RiverUnmarshaller.doReadNewObject(RiverUnmarshaller.java:1202)
at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:270)
at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:207)
at org.jboss.marshalling.river.RiverUnmarshaller.doReadMapObject(RiverUnmarshaller.java:193)
at org.jboss.marshalling.river.RiverUnmarshaller.readMapData(RiverUnmarshaller.java:741)
at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:666)
at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:207)
at org.jboss.marshalling.AbstractUnmarshaller.readObject(AbstractUnmarshaller.java:85)
at org.y4n.jlibs.jbm12.bugs.addition.FieldAdditionProblem.deserialize(FieldAdditionProblem.java:79)
at org.y4n.jlibs.jbm12.bugs.addition.FieldAdditionProblem.test(FieldAdditionProblem.java:19)
at org.y4n.jlibs.jbm12.bugs.addition.FieldAdditionProblem.main(FieldAdditionProblem.java:14)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:110)
Caused by: an exception which occurred:
in field y
in object of type org.y4n.jlibs.jbm12.bugs.addition.FieldAdditionProblem$Entity
in map value at index [0] of size [3]
Code to reproduce:
package org.y4n.jlibs.jbm12.bugs.addition;
import org.jboss.marshalling.*;
import org.jboss.marshalling.reflect.SunReflectiveCreator;
import org.jboss.marshalling.river.RiverMarshallerFactory;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
public class FieldAdditionProblem {
public static void main(String[] args)
{ FieldAdditionProblem fap = new FieldAdditionProblem(); fap.test(); }public void test()
{ // first serialize / deserialize into / from the file // serializeMap(); // deserialize(); // after that change entity (remove y field) and then just deserialize from the stream: // deserialize(); }private void serializeMap()
{ Entity e1 = new Entity(1); Entity e2 = new Entity(2); Entity e3 = new Entity(3); Map<String,Entity> m = new HashMap<String, Entity>(); m.put("" + 1, e1); m.put("" + 2, e2); m.put("" + 3, e3); serialize(m); } private void serialize(Map m) {
MarshallerFactory f = new RiverMarshallerFactory();
MarshallingConfiguration configuration = new MarshallingConfiguration();
configuration.setCreator(new SunReflectiveCreator());
ByteArrayOutputStream baos = null;
try
{ baos = new ByteArrayOutputStream(); Marshaller marshaller = f.createMarshaller(configuration); marshaller.start(Marshalling.createByteOutput(baos)); marshaller.writeObject(m); marshaller.flush(); marshaller.finish(); marshaller.close(); System.out.println("byte array size = " + baos.size()); FileOutputStream fos = new FileOutputStream("/tmp/xxx"); fos.write(baos.toByteArray()); fos.flush(); fos.close(); }catch (IOException e)
{ e.printStackTrace(); System.exit(-1); } System.out.println("serialized!");
}
private void deserialize() {
try
catch (IOException e)
{ e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); }}
public static byte[] getBytesFromFile(File file) throws IOException {
InputStream is = new FileInputStream(file);
long length = file.length();
byte[] bytes = new byte[(int)length];
int offset = 0;
int numRead = 0;
while (offset < bytes.length
&& (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0)
is.close();
return bytes;
}
public static class Entity implements Serializable {
private static final long serialVersionUID = -8918283944068410792L;
private final int x;
private final long y;
public Entity(int x)
{ this.x = x; this.y = 0; } @Override
public String toString() {
return "Entity
';
}
}
}