Uploaded image for project: 'JBoss Marshalling'
  1. JBoss Marshalling
  2. JBMAR-108

NPE during the map river deserialization after field addition

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Done
    • Icon: Major Major
    • 1.2.2.GA, 1.3.0.CR3
    • 1.2.0.GA
    • River
    • None
    • Hide

      1) Serializable entity is put to the map
      2) map is serialized into the file
      3) the entity is changed - the field is removed (simulating situation in client/server environment where server is sending updated entity with more fields than on client)
      4) the previously serialized data are deserialized from the file with changed entity (field less entity)

      Show
      1) Serializable entity is put to the map 2) map is serialized into the file 3) the entity is changed - the field is removed (simulating situation in client/server environment where server is sending updated entity with more fields than on client) 4) the previously serialized data are deserialized from the file with changed entity (field less entity)

      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

      { MarshallerFactory f1 = new RiverMarshallerFactory(); MarshallingConfiguration configuration1 = new MarshallingConfiguration(); configuration1.setCreator(new SunReflectiveCreator()); Unmarshaller um1 = f1.createUnmarshaller(configuration1); byte[] byteMessageData = getBytesFromFile(new File("/tmp/xxx")); System.out.println("data size to deserialize: " + byteMessageData.length); ByteArrayInputStream bi = new ByteArrayInputStream(byteMessageData); um1.start(Marshalling.createByteInput(bi)); Object o = um1.readObject(); System.out.println("deserialized: " + o); um1.finish(); }

      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)

      { offset += numRead; }

      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

      {" + "x=" + x + ", y=" + y + '}

      ';
      }

      }
      }

              dlloyd@redhat.com David Lloyd
              seahawk_jira Yan Falken (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

                Created:
                Updated:
                Resolved: