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-4565-ddl Commit: f52ba0f5d6efe9abc5d6c29352872df08007858c Parents: 6bdff2c Author: Alexandr Kuramshin <[email protected]> Authored: Thu Feb 16 12:09:22 2017 +0300 Committer: devozerov <[email protected]> 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);
