Repository: ignite
Updated Branches:
  refs/heads/ignite-2.0 6bdff2c31 -> f52ba0f5d


IGNITE-4538: Improved messages for BinaryMarshaller field read errors. This 
closes #1470.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/f52ba0f5
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/f52ba0f5
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/f52ba0f5

Branch: refs/heads/ignite-2.0
Commit: f52ba0f5d6efe9abc5d6c29352872df08007858c
Parents: 6bdff2c
Author: Alexandr Kuramshin <akurams...@gridgain.com>
Authored: Thu Feb 16 12:09:22 2017 +0300
Committer: devozerov <voze...@gridgain.com>
Committed: Thu Feb 16 12:09:22 2017 +0300

----------------------------------------------------------------------
 .../internal/binary/BinaryClassDescriptor.java  |  81 +++---
 .../internal/binary/BinaryFieldAccessor.java    |  56 ++--
 .../internal/binary/BinaryReaderExImpl.java     | 284 ++++++++++++++++---
 .../ignite/internal/binary/BinaryUtils.java     |  11 +-
 .../binary/BinaryObjectExceptionSelfTest.java   | 209 ++++++++++++++
 .../IgniteBinaryObjectsTestSuite.java           |   2 +
 6 files changed, 544 insertions(+), 99 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/f52ba0f5/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java
index b63e674..9b3a377 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java
@@ -45,6 +45,7 @@ import 
org.apache.ignite.internal.processors.query.GridQueryProcessor;
 import org.apache.ignite.internal.util.GridUnsafe;
 import org.apache.ignite.internal.util.IgniteUtils;
 import org.apache.ignite.internal.util.tostring.GridToStringExclude;
+import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.marshaller.MarshallerExclusions;
@@ -819,58 +820,66 @@ public class BinaryClassDescriptor {
      * @throws BinaryObjectException If failed.
      */
     Object read(BinaryReaderExImpl reader) throws BinaryObjectException {
-        assert reader != null;
-        assert mode != BinaryWriteMode.OPTIMIZED : "OptimizedMarshaller should 
not be used here: " + cls.getName();
+        try {
+            assert reader != null;
+            assert mode != BinaryWriteMode.OPTIMIZED : "OptimizedMarshaller 
should not be used here: " + cls.getName();
 
-        Object res;
+            Object res;
 
-        switch (mode) {
-            case BINARY:
-                res = newInstance();
+            switch (mode) {
+                case BINARY:
+                    res = newInstance();
 
-                reader.setHandle(res);
+                    reader.setHandle(res);
 
-                if (serializer != null)
-                    serializer.readBinary(res, reader);
-                else
-                    ((Binarylizable)res).readBinary(reader);
+                    if (serializer != null)
+                        serializer.readBinary(res, reader);
+                    else
+                        ((Binarylizable)res).readBinary(reader);
 
-                break;
+                    break;
 
-            case OBJECT:
-                res = newInstance();
+                case OBJECT:
+                    res = newInstance();
 
-                reader.setHandle(res);
+                    reader.setHandle(res);
 
-                for (BinaryFieldAccessor info : fields)
-                    info.read(res, reader);
+                    for (BinaryFieldAccessor info : fields)
+                        info.read(res, reader);
 
-                break;
+                    break;
 
-            default:
-                assert false : "Invalid mode: " + mode;
+                default:
+                    assert false : "Invalid mode: " + mode;
 
-                return null;
-        }
+                    return null;
+            }
 
-        if (readResolveMtd != null) {
-            try {
-                res = readResolveMtd.invoke(res);
+            if (readResolveMtd != null) {
+                try {
+                    res = readResolveMtd.invoke(res);
 
-                reader.setHandle(res);
-            }
-            catch (IllegalAccessException e) {
-                throw new RuntimeException(e);
-            }
-            catch (InvocationTargetException e) {
-                if (e.getTargetException() instanceof BinaryObjectException)
-                    throw (BinaryObjectException)e.getTargetException();
+                    reader.setHandle(res);
+                }
+                catch (IllegalAccessException e) {
+                    throw new RuntimeException(e);
+                }
+                catch (InvocationTargetException e) {
+                    if (e.getTargetException() instanceof 
BinaryObjectException)
+                        throw (BinaryObjectException)e.getTargetException();
 
-                throw new BinaryObjectException("Failed to execute 
readResolve() method on " + res, e);
+                    throw new BinaryObjectException("Failed to execute 
readResolve() method on " + res, e);
+                }
             }
-        }
 
-        return res;
+            return res;
+        }
+        catch (Exception e) {
+            if (S.INCLUDE_SENSITIVE && !F.isEmpty(typeName))
+                throw new BinaryObjectException("Failed to deserialize object 
[typeName=" + typeName + ']', e);
+            else
+                throw new BinaryObjectException("Failed to deserialize object 
[typeId=" + typeId + ']', e);
+        }
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/f52ba0f5/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryFieldAccessor.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryFieldAccessor.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryFieldAccessor.java
index aabb772..f7d35f0 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryFieldAccessor.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryFieldAccessor.java
@@ -27,6 +27,8 @@ import java.util.Map;
 import java.util.UUID;
 import org.apache.ignite.binary.BinaryObjectException;
 import org.apache.ignite.internal.util.GridUnsafe;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.internal.util.typedef.internal.U;
 
 /**
@@ -36,6 +38,9 @@ public abstract class BinaryFieldAccessor {
     /** Field ID. */
     protected final int id;
 
+    /** Field name */
+    protected final String name;
+
     /** Mode. */
     protected final BinaryWriteMode mode;
 
@@ -119,10 +124,12 @@ public abstract class BinaryFieldAccessor {
      * @param id Field ID.
      * @param mode Mode;
      */
-    protected BinaryFieldAccessor(int id, BinaryWriteMode mode) {
+    protected BinaryFieldAccessor(Field field, int id, BinaryWriteMode mode) {
+        assert field != null;
         assert id != 0;
         assert mode != null;
 
+        this.name = field.getName();
         this.id = id;
         this.mode = mode;
     }
@@ -152,7 +159,26 @@ public abstract class BinaryFieldAccessor {
      * @param reader Reader.
      * @throws BinaryObjectException If failed.
      */
-    public abstract void read(Object obj, BinaryReaderExImpl reader) throws 
BinaryObjectException;
+    public void read(Object obj, BinaryReaderExImpl reader) throws 
BinaryObjectException {
+        try {
+            read0(obj, reader);
+        }
+        catch (Exception ex) {
+            if (S.INCLUDE_SENSITIVE && !F.isEmpty(name))
+                throw new BinaryObjectException("Failed to read field [name=" 
+ name + ']', ex);
+            else
+                throw new BinaryObjectException("Failed to read field [id=" + 
id + ']', ex);
+        }
+    }
+
+    /**
+     * Read field.
+     *
+     * @param obj Object.
+     * @param reader Reader.
+     * @throws BinaryObjectException If failed.
+     */
+    protected abstract void read0(Object obj, BinaryReaderExImpl reader) 
throws BinaryObjectException;
 
     /**
      * Base primitive field accessor.
@@ -169,9 +195,7 @@ public abstract class BinaryFieldAccessor {
          * @param mode Mode.
          */
         protected AbstractPrimitiveAccessor(Field field, int id, 
BinaryWriteMode mode) {
-            super(id, mode);
-
-            assert field != null;
+            super(field, id, mode);
 
             offset = GridUnsafe.objectFieldOffset(field);
         }
@@ -200,7 +224,7 @@ public abstract class BinaryFieldAccessor {
         }
 
         /** {@inheritDoc} */
-        @Override public void read(Object obj, BinaryReaderExImpl reader) 
throws BinaryObjectException {
+        @Override public void read0(Object obj, BinaryReaderExImpl reader) 
throws BinaryObjectException {
             byte val = reader.readByte(id);
 
             GridUnsafe.putByteField(obj, offset, val);
@@ -230,7 +254,7 @@ public abstract class BinaryFieldAccessor {
         }
 
         /** {@inheritDoc} */
-        @Override public void read(Object obj, BinaryReaderExImpl reader) 
throws BinaryObjectException {
+        @Override public void read0(Object obj, BinaryReaderExImpl reader) 
throws BinaryObjectException {
             boolean val = reader.readBoolean(id);
 
             GridUnsafe.putBooleanField(obj, offset, val);
@@ -260,7 +284,7 @@ public abstract class BinaryFieldAccessor {
         }
 
         /** {@inheritDoc} */
-        @Override public void read(Object obj, BinaryReaderExImpl reader) 
throws BinaryObjectException {
+        @Override public void read0(Object obj, BinaryReaderExImpl reader) 
throws BinaryObjectException {
             short val = reader.readShort(id);
 
             GridUnsafe.putShortField(obj, offset, val);
@@ -290,7 +314,7 @@ public abstract class BinaryFieldAccessor {
         }
 
         /** {@inheritDoc} */
-        @Override public void read(Object obj, BinaryReaderExImpl reader) 
throws BinaryObjectException {
+        @Override public void read0(Object obj, BinaryReaderExImpl reader) 
throws BinaryObjectException {
             char val = reader.readChar(id);
 
             GridUnsafe.putCharField(obj, offset, val);
@@ -320,7 +344,7 @@ public abstract class BinaryFieldAccessor {
         }
 
         /** {@inheritDoc} */
-        @Override public void read(Object obj, BinaryReaderExImpl reader) 
throws BinaryObjectException {
+        @Override public void read0(Object obj, BinaryReaderExImpl reader) 
throws BinaryObjectException {
             int val = reader.readInt(id);
 
             GridUnsafe.putIntField(obj, offset, val);
@@ -350,7 +374,7 @@ public abstract class BinaryFieldAccessor {
         }
 
         /** {@inheritDoc} */
-        @Override public void read(Object obj, BinaryReaderExImpl reader) 
throws BinaryObjectException {
+        @Override public void read0(Object obj, BinaryReaderExImpl reader) 
throws BinaryObjectException {
             long val = reader.readLong(id);
 
             GridUnsafe.putLongField(obj, offset, val);
@@ -380,7 +404,7 @@ public abstract class BinaryFieldAccessor {
         }
 
         /** {@inheritDoc} */
-        @Override public void read(Object obj, BinaryReaderExImpl reader) 
throws BinaryObjectException {
+        @Override public void read0(Object obj, BinaryReaderExImpl reader) 
throws BinaryObjectException {
             float val = reader.readFloat(id);
 
             GridUnsafe.putFloatField(obj, offset, val);
@@ -410,7 +434,7 @@ public abstract class BinaryFieldAccessor {
         }
 
         /** {@inheritDoc} */
-        @Override public void read(Object obj, BinaryReaderExImpl reader) 
throws BinaryObjectException {
+        @Override public void read0(Object obj, BinaryReaderExImpl reader) 
throws BinaryObjectException {
             double val = reader.readDouble(id);
 
             GridUnsafe.putDoubleField(obj, offset, val);
@@ -435,9 +459,7 @@ public abstract class BinaryFieldAccessor {
          * @param mode Mode.
          */
         DefaultFinalClassAccessor(Field field, int id, BinaryWriteMode mode, 
boolean dynamic) {
-            super(id, mode);
-
-            assert field != null;
+            super(field, id, mode);
 
             this.field = field;
             this.dynamic = dynamic;
@@ -648,7 +670,7 @@ public abstract class BinaryFieldAccessor {
         }
 
         /** {@inheritDoc} */
-        @Override public void read(Object obj, BinaryReaderExImpl reader) 
throws BinaryObjectException {
+        @Override public void read0(Object obj, BinaryReaderExImpl reader) 
throws BinaryObjectException {
             Object val = dynamic ? reader.readField(id) : 
readFixedType(reader);
 
             try {

http://git-wip-us.apache.org/repos/asf/ignite/blob/f52ba0f5/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java
index 246cf57..b38d0ff 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java
@@ -36,6 +36,7 @@ import org.apache.ignite.binary.BinaryRawReader;
 import org.apache.ignite.binary.BinaryReader;
 import org.apache.ignite.internal.binary.streams.BinaryInputStream;
 import org.apache.ignite.internal.util.IgniteUtils;
+import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.internal.util.typedef.internal.SB;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -332,7 +333,12 @@ public class BinaryReaderExImpl implements BinaryReader, 
BinaryRawReaderEx, Bina
      * @throws BinaryObjectException In case of error.
      */
     @Nullable Object unmarshalField(String fieldName) throws 
BinaryObjectException {
-        return findFieldByName(fieldName) ? BinaryUtils.unmarshal(in, ctx, 
ldr, this) : null;
+        try {
+            return findFieldByName(fieldName) ? BinaryUtils.unmarshal(in, ctx, 
ldr, this) : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -424,9 +430,29 @@ public class BinaryReaderExImpl implements BinaryReader, 
BinaryRawReaderEx, Bina
 
         return (T)obj;
     }
+
+    /**
+     * Wraps an exception by adding the fieldName
+     *
+     * @param fieldName the name of the field, causes failure
+     * @param e the cause of the deserialization failure
+     * @return wrapping exception
+     */
+    private BinaryObjectException wrapFieldException(String fieldName, 
Exception e) {
+        if (S.INCLUDE_SENSITIVE)
+            return new BinaryObjectException("Failed to read field: " + 
fieldName, e);
+        else
+            return new BinaryObjectException("Failed to read field.", e);
+    }
+
     /** {@inheritDoc} */
     @Override public byte readByte(String fieldName) throws 
BinaryObjectException {
-        return findFieldByName(fieldName) && checkFlagNoHandles(BYTE) == 
Flag.NORMAL ? in.readByte() : 0;
+        try {
+            return findFieldByName(fieldName) && checkFlagNoHandles(BYTE) == 
Flag.NORMAL ? in.readByte() : 0;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -454,7 +480,12 @@ public class BinaryReaderExImpl implements BinaryReader, 
BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Nullable @Override public byte[] readByteArray(String fieldName) throws 
BinaryObjectException {
-        return findFieldByName(fieldName) ? this.readByteArray() : null;
+        try {
+            return findFieldByName(fieldName) ? this.readByteArray() : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -482,7 +513,12 @@ public class BinaryReaderExImpl implements BinaryReader, 
BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Override public boolean readBoolean(String fieldName) throws 
BinaryObjectException {
-        return findFieldByName(fieldName) && checkFlagNoHandles(BOOLEAN) == 
Flag.NORMAL && in.readBoolean();
+        try {
+            return findFieldByName(fieldName) && checkFlagNoHandles(BOOLEAN) 
== Flag.NORMAL && in.readBoolean();
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -510,7 +546,12 @@ public class BinaryReaderExImpl implements BinaryReader, 
BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Nullable @Override public boolean[] readBooleanArray(String fieldName) 
throws BinaryObjectException {
-        return findFieldByName(fieldName) ? this.readBooleanArray() : null;
+        try {
+            return findFieldByName(fieldName) ? this.readBooleanArray() : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -538,7 +579,12 @@ public class BinaryReaderExImpl implements BinaryReader, 
BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Override public short readShort(String fieldName) throws 
BinaryObjectException {
-        return findFieldByName(fieldName) && checkFlagNoHandles(SHORT) == 
Flag.NORMAL ? in.readShort() : 0;
+        try {
+            return findFieldByName(fieldName) && checkFlagNoHandles(SHORT) == 
Flag.NORMAL ? in.readShort() : 0;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -566,7 +612,12 @@ public class BinaryReaderExImpl implements BinaryReader, 
BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Nullable @Override public short[] readShortArray(String fieldName) throws 
BinaryObjectException {
-        return findFieldByName(fieldName) ? this.readShortArray() : null;
+        try {
+            return findFieldByName(fieldName) ? this.readShortArray() : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -594,7 +645,12 @@ public class BinaryReaderExImpl implements BinaryReader, 
BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Override public char readChar(String fieldName) throws 
BinaryObjectException {
-        return findFieldByName(fieldName) && checkFlagNoHandles(CHAR) == 
Flag.NORMAL ? in.readChar() : 0;
+        try {
+            return findFieldByName(fieldName) && checkFlagNoHandles(CHAR) == 
Flag.NORMAL ? in.readChar() : 0;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -622,7 +678,12 @@ public class BinaryReaderExImpl implements BinaryReader, 
BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Nullable @Override public char[] readCharArray(String fieldName) throws 
BinaryObjectException {
-        return findFieldByName(fieldName) ? this.readCharArray() : null;
+        try {
+            return findFieldByName(fieldName) ? this.readCharArray() : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -650,7 +711,12 @@ public class BinaryReaderExImpl implements BinaryReader, 
BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Override public int readInt(String fieldName) throws 
BinaryObjectException {
-        return findFieldByName(fieldName) && checkFlagNoHandles(INT) == 
Flag.NORMAL ? in.readInt() : 0;
+        try {
+            return findFieldByName(fieldName) && checkFlagNoHandles(INT) == 
Flag.NORMAL ? in.readInt() : 0;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -678,7 +744,12 @@ public class BinaryReaderExImpl implements BinaryReader, 
BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Nullable @Override public int[] readIntArray(String fieldName) throws 
BinaryObjectException {
-        return findFieldByName(fieldName) ? this.readIntArray() : null;
+        try {
+            return findFieldByName(fieldName) ? this.readIntArray() : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -706,7 +777,12 @@ public class BinaryReaderExImpl implements BinaryReader, 
BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Override public long readLong(String fieldName) throws 
BinaryObjectException {
-        return findFieldByName(fieldName) && checkFlagNoHandles(LONG) == 
Flag.NORMAL ? in.readLong() : 0;
+        try {
+            return findFieldByName(fieldName) && checkFlagNoHandles(LONG) == 
Flag.NORMAL ? in.readLong() : 0;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -734,7 +810,12 @@ public class BinaryReaderExImpl implements BinaryReader, 
BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Nullable @Override public long[] readLongArray(String fieldName) throws 
BinaryObjectException {
-        return findFieldByName(fieldName) ? this.readLongArray() : null;
+        try {
+            return findFieldByName(fieldName) ? this.readLongArray() : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -762,7 +843,12 @@ public class BinaryReaderExImpl implements BinaryReader, 
BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Override public float readFloat(String fieldName) throws 
BinaryObjectException {
-        return findFieldByName(fieldName) && checkFlagNoHandles(FLOAT) == 
Flag.NORMAL ? in.readFloat() : 0;
+        try {
+            return findFieldByName(fieldName) && checkFlagNoHandles(FLOAT) == 
Flag.NORMAL ? in.readFloat() : 0;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -790,7 +876,12 @@ public class BinaryReaderExImpl implements BinaryReader, 
BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Nullable @Override public float[] readFloatArray(String fieldName) throws 
BinaryObjectException {
-        return findFieldByName(fieldName) ? this.readFloatArray() : null;
+        try {
+            return findFieldByName(fieldName) ? this.readFloatArray() : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -818,7 +909,12 @@ public class BinaryReaderExImpl implements BinaryReader, 
BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Override public double readDouble(String fieldName) throws 
BinaryObjectException {
-        return findFieldByName(fieldName) && checkFlagNoHandles(DOUBLE) == 
Flag.NORMAL ? in.readDouble() : 0;
+        try {
+            return findFieldByName(fieldName) && checkFlagNoHandles(DOUBLE) == 
Flag.NORMAL ? in.readDouble() : 0;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -846,7 +942,12 @@ public class BinaryReaderExImpl implements BinaryReader, 
BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Nullable @Override public double[] readDoubleArray(String fieldName) 
throws BinaryObjectException {
-        return findFieldByName(fieldName) ? this.readDoubleArray() : null;
+        try {
+            return findFieldByName(fieldName) ? this.readDoubleArray() : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -874,7 +975,12 @@ public class BinaryReaderExImpl implements BinaryReader, 
BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Override @Nullable public BigDecimal readDecimal(String fieldName) throws 
BinaryObjectException {
-        return findFieldByName(fieldName) ? this.readDecimal() : null;
+        try {
+            return findFieldByName(fieldName) ? this.readDecimal() : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -893,7 +999,12 @@ public class BinaryReaderExImpl implements BinaryReader, 
BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Override @Nullable public BigDecimal[] readDecimalArray(String fieldName) 
throws BinaryObjectException {
-        return findFieldByName(fieldName) ? this.readDecimalArray() : null;
+        try {
+            return findFieldByName(fieldName) ? this.readDecimalArray() : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -921,7 +1032,12 @@ public class BinaryReaderExImpl implements BinaryReader, 
BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Override @Nullable public String readString(String fieldName) throws 
BinaryObjectException {
-        return findFieldByName(fieldName) ? this.readString() : null;
+        try {
+            return findFieldByName(fieldName) ? this.readString() : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -940,7 +1056,12 @@ public class BinaryReaderExImpl implements BinaryReader, 
BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Override @Nullable public String[] readStringArray(String fieldName) 
throws BinaryObjectException {
-        return findFieldByName(fieldName) ? this.readStringArray() : null;
+        try {
+            return findFieldByName(fieldName) ? this.readStringArray() : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -968,7 +1089,12 @@ public class BinaryReaderExImpl implements BinaryReader, 
BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Override @Nullable public UUID readUuid(String fieldName) throws 
BinaryObjectException {
-        return findFieldByName(fieldName) ? this.readUuid() : null;
+        try {
+            return findFieldByName(fieldName) ? this.readUuid() : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -987,7 +1113,12 @@ public class BinaryReaderExImpl implements BinaryReader, 
BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Override @Nullable public UUID[] readUuidArray(String fieldName) throws 
BinaryObjectException {
-        return findFieldByName(fieldName) ? this.readUuidArray() : null;
+        try {
+            return findFieldByName(fieldName) ? this.readUuidArray() : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -1015,7 +1146,12 @@ public class BinaryReaderExImpl implements BinaryReader, 
BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Override @Nullable public Date readDate(String fieldName) throws 
BinaryObjectException {
-        return findFieldByName(fieldName) ? this.readDate() : null;
+        try {
+            return findFieldByName(fieldName) ? this.readDate() : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -1034,7 +1170,12 @@ public class BinaryReaderExImpl implements BinaryReader, 
BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Override @Nullable public Date[] readDateArray(String fieldName) throws 
BinaryObjectException {
-        return findFieldByName(fieldName) ? this.readDateArray() : null;
+        try {
+            return findFieldByName(fieldName) ? this.readDateArray() : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -1062,7 +1203,12 @@ public class BinaryReaderExImpl implements BinaryReader, 
BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Override @Nullable public Timestamp readTimestamp(String fieldName) 
throws BinaryObjectException {
-        return findFieldByName(fieldName) ? this.readTimestamp() : null;
+        try {
+            return findFieldByName(fieldName) ? this.readTimestamp() : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -1081,7 +1227,12 @@ public class BinaryReaderExImpl implements BinaryReader, 
BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Override @Nullable public Timestamp[] readTimestampArray(String 
fieldName) throws BinaryObjectException {
-        return findFieldByName(fieldName) ? this.readTimestampArray() : null;
+        try {
+            return findFieldByName(fieldName) ? this.readTimestampArray() : 
null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -1155,7 +1306,12 @@ public class BinaryReaderExImpl implements BinaryReader, 
BinaryRawReaderEx, Bina
     /** {@inheritDoc} */
     @SuppressWarnings("unchecked")
     @Nullable @Override public <T> T readObject(String fieldName) throws 
BinaryObjectException {
-        return findFieldByName(fieldName) ? (T)BinaryUtils.doReadObject(in, 
ctx, ldr, this) : null;
+        try {
+            return findFieldByName(fieldName) ? 
(T)BinaryUtils.doReadObject(in, ctx, ldr, this) : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -1179,7 +1335,12 @@ public class BinaryReaderExImpl implements BinaryReader, 
BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Nullable @Override public Object[] readObjectArray(String fieldName) 
throws BinaryObjectException {
-        return findFieldByName(fieldName) ? this.readObjectArray() : null;
+        try {
+            return findFieldByName(fieldName) ? this.readObjectArray() : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -1207,7 +1368,12 @@ public class BinaryReaderExImpl implements BinaryReader, 
BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Nullable @Override public <T extends Enum<?>> T readEnum(String 
fieldName) throws BinaryObjectException {
-        return findFieldByName(fieldName) ? (T)readEnum0(null) : null;
+        try {
+            return findFieldByName(fieldName) ? (T)readEnum0(null) : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -1249,7 +1415,13 @@ public class BinaryReaderExImpl implements BinaryReader, 
BinaryRawReaderEx, Bina
     /** {@inheritDoc} */
     @Nullable @Override public <T extends Enum<?>> T[] readEnumArray(String 
fieldName)
         throws BinaryObjectException {
-        return findFieldByName(fieldName) ? (T[])readEnumArray0(null) : null;
+
+        try {
+            return findFieldByName(fieldName) ? (T[])readEnumArray0(null) : 
null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -1295,13 +1467,24 @@ public class BinaryReaderExImpl implements 
BinaryReader, BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Nullable @Override public <T> Collection<T> readCollection(String 
fieldName) throws BinaryObjectException {
-        return findFieldByName(fieldName) ? 
(Collection<T>)readCollection0(null) : null;
+        try {
+            return findFieldByName(fieldName) ? 
(Collection<T>)readCollection0(null) : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /** {@inheritDoc} */
     @Nullable @Override public <T> Collection<T> readCollection(String 
fieldName, BinaryCollectionFactory<T> factory)
         throws BinaryObjectException {
-        return findFieldByName(fieldName) ? readCollection0(factory) : null;
+
+        try {
+            return findFieldByName(fieldName) ? readCollection0(factory) : 
null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -1364,13 +1547,24 @@ public class BinaryReaderExImpl implements 
BinaryReader, BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Nullable @Override public <K, V> Map<K, V> readMap(String fieldName) 
throws BinaryObjectException {
-        return findFieldByName(fieldName) ? (Map<K, V>)readMap0(null) : null;
+        try {
+            return findFieldByName(fieldName) ? (Map<K, V>)readMap0(null) : 
null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /** {@inheritDoc} */
     @Nullable @Override public <K, V> Map<K, V> readMap(String fieldName, 
BinaryMapFactory<K, V> factory)
         throws BinaryObjectException {
-        return findFieldByName(fieldName) ? readMap0(factory) : null;
+
+        try {
+            return findFieldByName(fieldName) ? readMap0(factory) : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -1448,8 +1642,8 @@ public class BinaryReaderExImpl implements BinaryReader, 
BinaryRawReaderEx, Bina
 
         int pos = BinaryUtils.positionForHandle(in);
 
-        throw new BinaryObjectException("Unexpected flag value [pos=" + pos + 
", expected=" + expFlag +
-            ", actual=" + flag + ']');
+        throw new BinaryObjectException("Unexpected field type [pos=" + pos + 
", expected=" + fieldFlagName(expFlag) +
+            ", actual=" + fieldFlagName(flag) + ']');
     }
 
     /**
@@ -1469,8 +1663,20 @@ public class BinaryReaderExImpl implements BinaryReader, 
BinaryRawReaderEx, Bina
 
         int pos = BinaryUtils.positionForHandle(in);
 
-        throw new BinaryObjectException("Unexpected flag value [pos=" + pos + 
", expected=" + expFlag +
-            ", actual=" + flag + ']');
+        throw new BinaryObjectException("Unexpected field type [pos=" + pos + 
", expected=" + fieldFlagName(expFlag) +
+            ", actual=" + fieldFlagName(flag) + ']');
+    }
+
+    /**
+     * Gets a flag name
+     *
+     * @param flag a flag value
+     * @return string representation of the flag (type name, handle, else 
number)
+     */
+    private String fieldFlagName(byte flag) {
+        String typeName = BinaryUtils.fieldTypeName(flag);
+
+        return typeName == null ? String.valueOf(flag) : typeName;
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/f52ba0f5/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java 
b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java
index 24c2f72..28659ab 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java
@@ -354,16 +354,13 @@ public class BinaryUtils {
 
     /**
      * @param typeId Field type ID.
-     * @return Field type name.
+     * @return Field type name or {@code null} if unknown.
      */
     public static String fieldTypeName(int typeId) {
-        assert typeId >= 0 && typeId < FIELD_TYPE_NAMES.length : typeId;
-
-        String typeName = FIELD_TYPE_NAMES[typeId];
-
-        assert typeName != null : typeId;
+        if(typeId < 0 || typeId >= FIELD_TYPE_NAMES.length)
+            return null;
 
-        return typeName;
+        return FIELD_TYPE_NAMES[typeId];
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/f52ba0f5/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryObjectExceptionSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryObjectExceptionSelfTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryObjectExceptionSelfTest.java
new file mode 100644
index 0000000..e4be824
--- /dev/null
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryObjectExceptionSelfTest.java
@@ -0,0 +1,209 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ignite.internal.binary;
+
+import java.lang.reflect.Field;
+import java.math.BigDecimal;
+import java.sql.Timestamp;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.UUID;
+import javax.cache.Cache;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.binary.BinaryBasicNameMapper;
+import org.apache.ignite.binary.BinaryObjectException;
+import org.apache.ignite.configuration.BinaryConfiguration;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+
+/**
+ * BinaryObjectExceptionSelfTest
+ */
+public class BinaryObjectExceptionSelfTest extends GridCommonAbstractTest {
+    /** */
+    private static final String TEST_KEY = "test_key";
+
+    /** */
+    private static final TcpDiscoveryIpFinder IP_FINDER = new 
TcpDiscoveryVmIpFinder(true);
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String gridName) 
throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+        cfg.setMarshaller(new BinaryMarshaller());
+        cfg.setDiscoverySpi(new TcpDiscoverySpi().setIpFinder(IP_FINDER));
+
+        cfg.setCacheConfiguration(new 
CacheConfiguration().setCopyOnRead(true));
+
+        BinaryConfiguration bcfg = new BinaryConfiguration();
+
+        bcfg.setNameMapper(new BinaryBasicNameMapper(false));
+
+        cfg.setBinaryConfiguration(bcfg);
+
+        return cfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTest() throws Exception {
+        startGrids(2);
+
+        awaitPartitionMapExchange();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        stopAllGrids();
+    }
+
+    /**
+     * Test unexpected field type.
+     *
+     * @throws Exception If failed.
+     */
+    @SuppressWarnings("WhileLoopReplaceableByForEach")
+    public void testUnexpectedFieldType() throws Exception {
+        IgniteEx grid = grid(0);
+
+        IgniteCache<String, Value> cache = grid.cache(null);
+
+        cache.put(TEST_KEY, new Value());
+
+        BinaryObjectImpl b = 
(BinaryObjectImpl)cache.withKeepBinary().get(TEST_KEY);
+
+        b.deserialize(); // deserialize working
+
+        byte[] a = b.array();
+
+        int unexpectedCnt = 0;
+
+        Field[] fields = Value.class.getDeclaredFields();
+
+        StringBuilder sb = new StringBuilder(4 << 10);
+
+        for (int i = b.dataStartOffset(), j = b.footerStartOffset(); i < j; 
++i) {
+            byte old = a[i];
+
+            a[i] = -1;
+
+            try {
+                Iterator<Cache.Entry<String, Value>> it = cache.iterator();
+
+                while (it.hasNext())
+                    it.next();
+            }
+            catch (Exception ex) {
+                Throwable root = ex;
+
+                sb.setLength(0);
+
+                sb.append(root.getMessage());
+
+                while (root.getCause() != null) {
+                    root = root.getCause();
+
+                    sb.append(". ").append(root.getMessage());
+                }
+                if (root instanceof BinaryObjectException && 
root.getMessage().startsWith("Unexpected field type")) {
+                    log().info(sb.toString());
+
+                    Field f = fields[unexpectedCnt];
+
+                    Throwable t = ex;
+
+                    assertTrue(t.getMessage(), t.getMessage().contains(
+                        "object 
[typeName=org.apache.ignite.internal.binary.BinaryObjectExceptionSelfTest$Value"));
+
+                    t = t.getCause();
+
+                    assertTrue(t.getMessage(), t.getMessage().contains("field 
[name=" + f.getName()));
+
+                    ++unexpectedCnt;
+                }
+                else
+                    log().info("Ignored exception: " + sb);
+            }
+
+            a[i] = old;
+        }
+
+        assertEquals("Fields count must match \"Unexpected field type\" 
exception count", fields.length, unexpectedCnt);
+    }
+
+    /** */
+    private enum EnumValues {
+        /** */
+        val1,
+
+        /** */
+        val2,
+
+        /** */
+        val3;
+    }
+
+    /** */
+    @SuppressWarnings("unused")
+    private static class Value {
+        /** */
+        public byte byteVal = 1;
+
+        /** */
+        public boolean booleanVal = true;
+
+        /** */
+        public short shortVal = 2;
+
+        /** */
+        public char charVal = 'Q';
+
+        /** */
+        public int intVal = 3;
+
+        /** */
+        public long longVal = 4;
+
+        /** */
+        public float floatVal = 5;
+
+        /** */
+        public double doubleVal = 6;
+
+        /** */
+        public BigDecimal bigDecimal = new BigDecimal(7);
+
+        /** */
+        public String string = "QWERTY";
+
+        /** */
+        public UUID uuid = UUID.randomUUID();
+
+        /** */
+        public Date date = new Date();
+
+        /** */
+        public Timestamp timestamp = new Timestamp(date.getTime() + 1000L);
+
+        /** */
+        public EnumValues enumVal = EnumValues.val2;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f52ba0f5/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBinaryObjectsTestSuite.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBinaryObjectsTestSuite.java
 
b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBinaryObjectsTestSuite.java
index 3496dbf..1a348e0 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBinaryObjectsTestSuite.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBinaryObjectsTestSuite.java
@@ -33,6 +33,7 @@ import 
org.apache.ignite.internal.binary.BinaryMarshallerSelfTest;
 import org.apache.ignite.internal.binary.BinaryObjectBuilderAdditionalSelfTest;
 import 
org.apache.ignite.internal.binary.BinaryObjectBuilderDefaultMappersSelfTest;
 import 
org.apache.ignite.internal.binary.BinaryObjectBuilderSimpleNameLowerCaseMappersSelfTest;
+import org.apache.ignite.internal.binary.BinaryObjectExceptionSelfTest;
 import org.apache.ignite.internal.binary.BinaryObjectToStringSelfTest;
 import 
org.apache.ignite.internal.binary.BinarySerialiedFieldComparatorSelfTest;
 import org.apache.ignite.internal.binary.BinarySimpleNameTestPropertySelfTest;
@@ -93,6 +94,7 @@ public class IgniteBinaryObjectsTestSuite extends TestSuite {
 
         suite.addTestSuite(BinaryTreeSelfTest.class);
         suite.addTestSuite(BinaryMarshallerSelfTest.class);
+        suite.addTestSuite(BinaryObjectExceptionSelfTest.class);
 
         suite.addTestSuite(BinarySerialiedFieldComparatorSelfTest.class);
         suite.addTestSuite(BinaryArrayIdentityResolverSelfTest.class);

Reply via email to