You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ak...@apache.org on 2015/11/30 13:10:24 UTC

[41/50] [abbrv] ignite git commit: Fixing metadata update under changing topology. This closes #280

Fixing metadata update under changing topology. This closes #280


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

Branch: refs/heads/ignite-843-rc1
Commit: 59ee87e17d4cb4cc1232dd883e2f708552139c13
Parents: ba28eaf
Author: Alexey Goncharuk <al...@gmail.com>
Authored: Sat Nov 28 18:42:26 2015 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Sat Nov 28 18:42:26 2015 +0300

----------------------------------------------------------------------
 .../internal/portable/BinaryEnumObjectImpl.java |   2 +-
 .../internal/portable/BinaryObjectImpl.java     |  10 +-
 .../internal/portable/BinaryReaderExImpl.java   |   6 +-
 .../internal/portable/BinaryWriterExImpl.java   |  10 +-
 .../internal/portable/PortableContext.java      |  31 ++-
 .../ignite/internal/portable/PortableUtils.java |  10 +-
 .../builder/BinaryObjectBuilderImpl.java        |   2 +-
 .../portable/builder/PortableBuilderEnum.java   |   2 +-
 .../builder/PortableEnumArrayLazyValue.java     |   2 +-
 .../builder/PortableObjectArrayLazyValue.java   |   2 +-
 .../CacheDefaultBinaryAffinityKeyMapper.java    |  51 ++++
 .../distributed/dht/GridDhtTxFinishFuture.java  |  12 +-
 .../distributed/dht/GridDhtTxLocalAdapter.java  |   2 +-
 .../distributed/dht/GridDhtTxPrepareFuture.java |  37 ++-
 .../dht/atomic/GridDhtAtomicCache.java          |   5 +-
 .../colocated/GridDhtColocatedLockFuture.java   |  17 +-
 .../distributed/near/GridNearLockFuture.java    |  24 +-
 ...arOptimisticSerializableTxPrepareFuture.java |  12 +-
 .../near/GridNearOptimisticTxPrepareFuture.java | 134 +++++-----
 .../portable/CacheObjectPortableContext.java    |   3 +-
 .../cache/transactions/IgniteTxHandler.java     |   6 +-
 .../cache/transactions/IgniteTxManager.java     |  22 +-
 .../portable/BinaryMarshallerSelfTest.java      |   2 +-
 .../CachePutEventListenerErrorSelfTest.java     | 180 ++++++++++++++
 .../GridCacheOnCopyFlagAbstractSelfTest.java    |  14 +-
 ...yMetadataUpdateChangingTopologySelfTest.java | 245 +++++++++++++++++++
 .../replicated/GridReplicatedTxPreloadTest.java |   6 +
 ...CacheReplicatedPreloadLifecycleSelfTest.java | 100 +++++---
 .../ignite/testsuites/IgniteCacheTestSuite.java |   3 +
 .../IgnitePortableObjectsTestSuite.java         |   2 +
 30 files changed, 791 insertions(+), 163 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/59ee87e1/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryEnumObjectImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryEnumObjectImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryEnumObjectImpl.java
index e13c076..467d767 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryEnumObjectImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryEnumObjectImpl.java
@@ -110,7 +110,7 @@ public class BinaryEnumObjectImpl implements BinaryObjectEx, Externalizable, Cac
     /** {@inheritDoc} */
     @SuppressWarnings("unchecked")
     @Override public <T> T deserialize() throws BinaryObjectException {
-        Class cls = PortableUtils.resolveClass(ctx, typeId, clsName, null);
+        Class cls = PortableUtils.resolveClass(ctx, typeId, clsName, null, true);
 
         return BinaryEnumCache.get(cls, ord);
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/59ee87e1/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryObjectImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryObjectImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryObjectImpl.java
index 87a03dc..cf5a659 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryObjectImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryObjectImpl.java
@@ -127,7 +127,7 @@ public final class BinaryObjectImpl extends BinaryObjectExImpl implements Extern
     @Nullable @Override public <T> T value(CacheObjectContext ctx, boolean cpy) {
         Object obj0 = obj;
 
-        if (obj0 == null || cpy)
+        if (obj0 == null || (cpy && needCopy(ctx)))
             obj0 = deserializeValue(ctx);
 
         return (T)obj0;
@@ -561,6 +561,14 @@ public final class BinaryObjectImpl extends BinaryObjectExImpl implements Extern
     }
 
     /**
+     * @param ctx Context.
+     * @return {@code True} need to copy value returned to user.
+     */
+    private boolean needCopy(CacheObjectContext ctx) {
+        return ctx.copyOnGet() && obj != null && !ctx.processor().immutable(obj);
+    }
+
+    /**
      * Create new reader for this object.
      *
      * @param rCtx Reader context.

http://git-wip-us.apache.org/repos/asf/ignite/blob/59ee87e1/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryReaderExImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryReaderExImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryReaderExImpl.java
index 3cc2fbe..b9f851c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryReaderExImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryReaderExImpl.java
@@ -234,7 +234,7 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
                 int off = in.position();
 
                 // Registers class by type ID, at least locally if the cache is not ready yet.
-                typeId = ctx.descriptorForClass(PortableUtils.doReadClass(in, ctx, ldr, typeId0)).typeId();
+                typeId = ctx.descriptorForClass(PortableUtils.doReadClass(in, ctx, ldr, typeId0), false).typeId();
 
                 int clsNameLen = in.position() - off;
 
@@ -277,7 +277,7 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
      * @return Descriptor.
      */
     PortableClassDescriptor descriptor() {
-        return ctx.descriptorForTypeId(userType, typeId, ldr);
+        return ctx.descriptorForTypeId(userType, typeId, ldr, true);
     }
 
     /**
@@ -1427,7 +1427,7 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
                 break;
 
             case OBJ:
-                PortableClassDescriptor desc = ctx.descriptorForTypeId(userType, typeId, ldr);
+                PortableClassDescriptor desc = ctx.descriptorForTypeId(userType, typeId, ldr, true);
 
                 streamPosition(dataStart);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/59ee87e1/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryWriterExImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryWriterExImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryWriterExImpl.java
index 9d1d037..95807ea 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryWriterExImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryWriterExImpl.java
@@ -182,7 +182,7 @@ public class BinaryWriterExImpl implements BinaryWriter, BinaryRawWriterEx, Obje
 
         Class<?> cls = obj.getClass();
 
-        PortableClassDescriptor desc = ctx.descriptorForClass(cls);
+        PortableClassDescriptor desc = ctx.descriptorForClass(cls, false);
 
         if (desc == null)
             throw new BinaryObjectException("Object is not portable: [class=" + cls + ']');
@@ -697,7 +697,7 @@ public class BinaryWriterExImpl implements BinaryWriter, BinaryRawWriterEx, Obje
             if (tryWriteAsHandle(val))
                 return;
 
-            PortableClassDescriptor desc = ctx.descriptorForClass(val.getClass().getComponentType());
+            PortableClassDescriptor desc = ctx.descriptorForClass(val.getClass().getComponentType(), false);
 
             out.unsafeEnsure(1 + 4);
             out.unsafeWriteByte(OBJ_ARR);
@@ -785,7 +785,7 @@ public class BinaryWriterExImpl implements BinaryWriter, BinaryRawWriterEx, Obje
         if (val == null)
             out.writeByte(NULL);
         else {
-            PortableClassDescriptor desc = ctx.descriptorForClass(val.getClass());
+            PortableClassDescriptor desc = ctx.descriptorForClass(val.getClass(), false);
 
             out.unsafeEnsure(1 + 4);
 
@@ -830,7 +830,7 @@ public class BinaryWriterExImpl implements BinaryWriter, BinaryRawWriterEx, Obje
         if (val == null)
             out.writeByte(NULL);
         else {
-            PortableClassDescriptor desc = ctx.descriptorForClass(val.getClass().getComponentType());
+            PortableClassDescriptor desc = ctx.descriptorForClass(val.getClass().getComponentType(), false);
 
             out.unsafeEnsure(1 + 4);
 
@@ -859,7 +859,7 @@ public class BinaryWriterExImpl implements BinaryWriter, BinaryRawWriterEx, Obje
         if (val == null)
             out.writeByte(NULL);
         else {
-            PortableClassDescriptor desc = ctx.descriptorForClass(val);
+            PortableClassDescriptor desc = ctx.descriptorForClass(val, false);
 
             out.unsafeEnsure(1 + 4);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/59ee87e1/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java
index ae0d940..1482df9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java
@@ -402,14 +402,14 @@ public class PortableContext implements Externalizable {
      * @return Class descriptor.
      * @throws org.apache.ignite.binary.BinaryObjectException In case of error.
      */
-    public PortableClassDescriptor descriptorForClass(Class<?> cls)
+    public PortableClassDescriptor descriptorForClass(Class<?> cls, boolean deserialize)
         throws BinaryObjectException {
         assert cls != null;
 
         PortableClassDescriptor desc = descByCls.get(cls);
 
         if (desc == null || !desc.registered())
-            desc = registerClassDescriptor(cls);
+            desc = registerClassDescriptor(cls, deserialize);
 
         return desc;
     }
@@ -420,7 +420,12 @@ public class PortableContext implements Externalizable {
      * @param ldr Class loader.
      * @return Class descriptor.
      */
-    public PortableClassDescriptor descriptorForTypeId(boolean userType, int typeId, ClassLoader ldr) {
+    public PortableClassDescriptor descriptorForTypeId(
+        boolean userType,
+        int typeId,
+        ClassLoader ldr,
+        boolean deserialize
+    ) {
         assert typeId != GridPortableMarshaller.UNREGISTERED_TYPE_ID;
 
         //TODO: As a workaround for IGNITE-1358 we always check the predefined map before without checking 'userType'
@@ -450,21 +455,21 @@ public class PortableContext implements Externalizable {
         }
         catch (ClassNotFoundException e) {
             // Class might have been loaded by default class loader.
-            if (userType && !ldr.equals(dfltLdr) && (desc = descriptorForTypeId(true, typeId, dfltLdr)) != null)
+            if (userType && !ldr.equals(dfltLdr) && (desc = descriptorForTypeId(true, typeId, dfltLdr, deserialize)) != null)
                 return desc;
 
             throw new BinaryInvalidTypeException(e);
         }
         catch (IgniteCheckedException e) {
             // Class might have been loaded by default class loader.
-            if (userType && !ldr.equals(dfltLdr) && (desc = descriptorForTypeId(true, typeId, dfltLdr)) != null)
+            if (userType && !ldr.equals(dfltLdr) && (desc = descriptorForTypeId(true, typeId, dfltLdr, deserialize)) != null)
                 return desc;
 
             throw new BinaryObjectException("Failed resolve class for ID: " + typeId, e);
         }
 
         if (desc == null) {
-            desc = registerClassDescriptor(cls);
+            desc = registerClassDescriptor(cls, deserialize);
 
             assert desc.typeId() == typeId;
         }
@@ -478,7 +483,7 @@ public class PortableContext implements Externalizable {
      * @param cls Class.
      * @return Class descriptor.
      */
-    private PortableClassDescriptor registerClassDescriptor(Class<?> cls) {
+    private PortableClassDescriptor registerClassDescriptor(Class<?> cls, boolean deserialize) {
         PortableClassDescriptor desc;
 
         String clsName = cls.getName();
@@ -503,7 +508,7 @@ public class PortableContext implements Externalizable {
                 desc = old;
         }
         else
-            desc = registerUserClassDescriptor(cls);
+            desc = registerUserClassDescriptor(cls, deserialize);
 
         return desc;
     }
@@ -514,7 +519,7 @@ public class PortableContext implements Externalizable {
      * @param cls Class.
      * @return Class descriptor.
      */
-    private PortableClassDescriptor registerUserClassDescriptor(Class<?> cls) {
+    private PortableClassDescriptor registerUserClassDescriptor(Class<?> cls, boolean deserialize) {
         boolean registered;
 
         String typeName = typeName(cls.getName());
@@ -545,10 +550,12 @@ public class PortableContext implements Externalizable {
             false /* predefined */
         );
 
-        Collection<PortableSchema> schemas = desc.schema() != null ? Collections.singleton(desc.schema()) : null;
+        if (!deserialize) {
+            Collection<PortableSchema> schemas = desc.schema() != null ? Collections.singleton(desc.schema()) : null;
 
-        metaHnd.addMeta(typeId, 
-            new BinaryMetadata(typeId, typeName, desc.fieldsMeta(), affFieldName, schemas, desc.isEnum()).wrap(this));
+            metaHnd.addMeta(typeId,
+                new BinaryMetadata(typeId, typeName, desc.fieldsMeta(), affFieldName, schemas, desc.isEnum()).wrap(this));
+        }
 
         // perform put() instead of putIfAbsent() because "registered" flag might have been changed or class loader
         // might have reloaded described class.

http://git-wip-us.apache.org/repos/asf/ignite/blob/59ee87e1/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableUtils.java
index 1a8f156..5d794ca 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableUtils.java
@@ -1366,7 +1366,7 @@ public class PortableUtils {
             return Object.class;
 
         if (typeId != UNREGISTERED_TYPE_ID)
-            cls = ctx.descriptorForTypeId(true, typeId, ldr).describedClass();
+            cls = ctx.descriptorForTypeId(true, typeId, ldr, false).describedClass();
         else {
             String clsName = doReadClassName(in);
 
@@ -1378,7 +1378,7 @@ public class PortableUtils {
             }
 
             // forces registering of class by type id, at least locally
-            ctx.descriptorForClass(cls);
+            ctx.descriptorForClass(cls, true);
         }
 
         return cls;
@@ -1394,14 +1394,14 @@ public class PortableUtils {
      * @return Resovled class.
      */
     public static Class resolveClass(PortableContext ctx, int typeId, @Nullable String clsName,
-        @Nullable ClassLoader ldr) {
+        @Nullable ClassLoader ldr, boolean deserialize) {
         Class cls;
 
         if (typeId == OBJECT_TYPE_ID)
             return Object.class;
 
         if (typeId != UNREGISTERED_TYPE_ID)
-            cls = ctx.descriptorForTypeId(true, typeId, ldr).describedClass();
+            cls = ctx.descriptorForTypeId(true, typeId, ldr, deserialize).describedClass();
         else {
             try {
                 cls = U.forName(clsName, ldr);
@@ -1411,7 +1411,7 @@ public class PortableUtils {
             }
 
             // forces registering of class by type id, at least locally
-            ctx.descriptorForClass(cls);
+            ctx.descriptorForClass(cls, true);
         }
 
         return cls;

http://git-wip-us.apache.org/repos/asf/ignite/blob/59ee87e1/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/BinaryObjectBuilderImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/BinaryObjectBuilderImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/BinaryObjectBuilderImpl.java
index cadc781..c4ce9e6 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/BinaryObjectBuilderImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/BinaryObjectBuilderImpl.java
@@ -161,7 +161,7 @@ public class BinaryObjectBuilderImpl implements BinaryObjectBuilder {
                 throw new BinaryInvalidTypeException("Failed to load the class: " + clsNameToWrite, e);
             }
 
-            this.typeId = ctx.descriptorForClass(cls).typeId();
+            this.typeId = ctx.descriptorForClass(cls, false).typeId();
 
             registeredType = false;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/59ee87e1/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderEnum.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderEnum.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderEnum.java
index 9eb77b4..6f79e73 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderEnum.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderEnum.java
@@ -64,7 +64,7 @@ public class PortableBuilderEnum implements PortableBuilderSerializationAware {
                 throw new BinaryInvalidTypeException("Failed to load the class: " + clsName, e);
             }
 
-            this.typeId = reader.portableContext().descriptorForClass(cls).typeId();
+            this.typeId = reader.portableContext().descriptorForClass(cls, false).typeId();
         }
         else {
             this.typeId = typeId;

http://git-wip-us.apache.org/repos/asf/ignite/blob/59ee87e1/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableEnumArrayLazyValue.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableEnumArrayLazyValue.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableEnumArrayLazyValue.java
index 1e2ebc9..91c1c87 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableEnumArrayLazyValue.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableEnumArrayLazyValue.java
@@ -57,7 +57,7 @@ class PortableEnumArrayLazyValue extends PortableAbstractLazyValue {
                 throw new BinaryInvalidTypeException("Failed to load the class: " + clsName, e);
             }
 
-            compTypeId = reader.portableContext().descriptorForClass(cls).typeId();
+            compTypeId = reader.portableContext().descriptorForClass(cls, true).typeId();
         }
         else {
             compTypeId = typeId;

http://git-wip-us.apache.org/repos/asf/ignite/blob/59ee87e1/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableObjectArrayLazyValue.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableObjectArrayLazyValue.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableObjectArrayLazyValue.java
index 6634eea..8c8022b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableObjectArrayLazyValue.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableObjectArrayLazyValue.java
@@ -56,7 +56,7 @@ class PortableObjectArrayLazyValue extends PortableAbstractLazyValue {
                 throw new BinaryInvalidTypeException("Failed to load the class: " + clsName, e);
             }
 
-            compTypeId = reader.portableContext().descriptorForClass(cls).typeId();
+            compTypeId = reader.portableContext().descriptorForClass(cls, true).typeId();
         }
         else {
             compTypeId = typeId;

http://git-wip-us.apache.org/repos/asf/ignite/blob/59ee87e1/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheDefaultBinaryAffinityKeyMapper.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheDefaultBinaryAffinityKeyMapper.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheDefaultBinaryAffinityKeyMapper.java
new file mode 100644
index 0000000..efd38f7
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheDefaultBinaryAffinityKeyMapper.java
@@ -0,0 +1,51 @@
+/*
+ * 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.processors.cache;
+
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.internal.IgniteKernal;
+import org.apache.ignite.internal.processors.cache.portable.CacheObjectBinaryProcessorImpl;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.binary.BinaryObject;
+
+/**
+ *
+ */
+public class CacheDefaultBinaryAffinityKeyMapper extends GridCacheDefaultAffinityKeyMapper {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** {@inheritDoc} */
+    @Override public Object affinityKey(Object key) {
+        IgniteKernal kernal = (IgniteKernal)ignite;
+
+        CacheObjectBinaryProcessorImpl proc = (CacheObjectBinaryProcessorImpl)kernal.context().cacheObjects();
+
+        try {
+            key = proc.toPortable(key);
+        }
+        catch (IgniteException e) {
+            U.error(log, "Failed to marshal key to portable: " + key, e);
+        }
+
+        if (key instanceof BinaryObject)
+            return proc.affinityKey((BinaryObject)key);
+        else
+            return super.affinityKey(key);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/59ee87e1/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishFuture.java
index c4a90b1..9a0d778 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxFinishFuture.java
@@ -201,9 +201,17 @@ public final class GridDhtTxFinishFuture<K, V> extends GridCompoundIdentityFutur
 
             Throwable e = this.err.get();
 
-            if (super.onDone(tx, e != null ? e : err)) {
+            if (e == null && commit)
+                e = this.tx.commitError();
+
+            Throwable finishErr = e != null ? e : err;
+
+            if (super.onDone(tx, finishErr)) {
+                if (finishErr == null)
+                    finishErr = this.tx.commitError();
+
                 // Always send finish reply.
-                this.tx.sendFinishReply(commit, error());
+                this.tx.sendFinishReply(commit, finishErr);
 
                 // Don't forget to clean up.
                 cctx.mvcc().removeFuture(futId);

http://git-wip-us.apache.org/repos/asf/ignite/blob/59ee87e1/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocalAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocalAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocalAdapter.java
index 2330a95..534a560 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocalAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocalAdapter.java
@@ -822,7 +822,7 @@ public abstract class GridDhtTxLocalAdapter extends IgniteTxLocalAdapter {
     /**
      * @return {@code True} if transaction is finished on prepare step.
      */
-    protected final boolean commitOnPrepare() {
+    public final boolean commitOnPrepare() {
         return onePhaseCommit() && !near() && !nearOnOriginatingNode;
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/59ee87e1/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java
index 1d418ea..34addfa 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java
@@ -58,6 +58,7 @@ import org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry;
 import org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey;
 import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
 import org.apache.ignite.internal.processors.dr.GridDrType;
+import org.apache.ignite.internal.transactions.IgniteTxHeuristicCheckedException;
 import org.apache.ignite.internal.transactions.IgniteTxOptimisticCheckedException;
 import org.apache.ignite.internal.util.F0;
 import org.apache.ignite.internal.util.GridLeanSet;
@@ -602,13 +603,8 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
                 if (tx.markFinalizing(IgniteInternalTx.FinalizationStatus.USER_FINISH)) {
                     IgniteInternalFuture<IgniteInternalTx> fut = null;
 
-                    if (prepErr == null)
-                        fut = tx.commitAsync();
-                    else if (!cctx.kernalContext().isStopping())
-                        fut = tx.rollbackAsync();
-
-                    if (fut != null) {
-                        fut.listen(new CIX1<IgniteInternalFuture<IgniteInternalTx>>() {
+                    CIX1<IgniteInternalFuture<IgniteInternalTx>> responseClo =
+                        new CIX1<IgniteInternalFuture<IgniteInternalTx>>() {
                             @Override public void applyx(IgniteInternalFuture<IgniteInternalTx> fut) {
                                 try {
                                     if (replied.compareAndSet(false, true))
@@ -618,8 +614,33 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
                                     U.error(log, "Failed to send prepare response for transaction: " + tx, e);
                                 }
                             }
-                        });
+                        };
+
+                    if (prepErr == null) {
+                        try {
+                            fut = tx.commitAsync();
+                        }
+                        catch (RuntimeException | Error e) {
+                            Exception hEx = new IgniteTxHeuristicCheckedException("Commit produced a runtime " +
+                                "exception: " + CU.txString(tx), e);
+
+                            res.error(hEx);
+
+                            tx.systemInvalidate(true);
+
+                            fut = tx.rollbackAsync();
+
+                            fut.listen(responseClo);
+
+                            throw e;
+                        }
+
                     }
+                    else if (!cctx.kernalContext().isStopping())
+                        fut = tx.rollbackAsync();
+
+                    if (fut != null)
+                        fut.listen(responseClo);
                 }
             }
             else {

http://git-wip-us.apache.org/repos/asf/ignite/blob/59ee87e1/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java
index 8fe1b3a..a49341b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java
@@ -1393,7 +1393,7 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
 
             remap = true;
         }
-        catch (Exception e) {
+        catch (Throwable e) {
             // At least RuntimeException can be thrown by the code above when GridCacheContext is cleaned and there is
             // an attempt to use cleaned resources.
             U.error(log, "Unexpected exception during cache update", e);
@@ -1402,6 +1402,9 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
 
             completionCb.apply(req, res);
 
+            if (e instanceof Error)
+                throw e;
+
             return;
         }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/59ee87e1/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedLockFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedLockFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedLockFuture.java
index ecdf641..d3028ca 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedLockFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedLockFuture.java
@@ -977,12 +977,27 @@ public final class GridDhtColocatedLockFuture extends GridCompoundIdentityFuture
     }
 
     /**
+     * @throws IgniteCheckedException If failed.
+     */
+    private void proceedMapping() throws IgniteCheckedException {
+        boolean set = tx != null && cctx.shared().tm().setTxTopologyHint(tx);
+
+        try {
+            proceedMapping0();
+        }
+        finally {
+            if (set)
+                cctx.tm().setTxTopologyHint(null);
+        }
+    }
+
+    /**
      * Gets next near lock mapping and either acquires dht locks locally or sends near lock request to
      * remote primary node.
      *
      * @throws IgniteCheckedException If mapping can not be completed.
      */
-    private void proceedMapping()
+    private void proceedMapping0()
         throws IgniteCheckedException {
         GridNearLockMapping map;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/59ee87e1/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockFuture.java
index f1f9990..4cb7248 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockFuture.java
@@ -263,13 +263,6 @@ public final class GridNearLockFuture extends GridCompoundIdentityFuture<Boolean
     }
 
     /**
-     * @return {@code True} if commit is synchronous.
-     */
-    private boolean syncCommit() {
-        return tx != null && tx.syncCommit();
-    }
-
-    /**
      * @return {@code True} if rollback is synchronous.
      */
     private boolean syncRollback() {
@@ -1082,13 +1075,28 @@ public final class GridNearLockFuture extends GridCompoundIdentityFuture<Boolean
     }
 
     /**
+     * @throws IgniteCheckedException If failed.
+     */
+    private void proceedMapping() throws IgniteCheckedException {
+        boolean set = tx != null && cctx.shared().tm().setTxTopologyHint(tx);
+
+        try {
+            proceedMapping0();
+        }
+        finally {
+            if (set)
+                cctx.tm().setTxTopologyHint(null);
+        }
+    }
+
+    /**
      * Gets next near lock mapping and either acquires dht locks locally or sends near lock request to
      * remote primary node.
      *
      * @throws IgniteCheckedException If mapping can not be completed.
      */
     @SuppressWarnings("unchecked")
-    private void proceedMapping()
+    private void proceedMapping0()
         throws IgniteCheckedException {
         GridNearLockMapping map;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/59ee87e1/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticSerializableTxPrepareFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticSerializableTxPrepareFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticSerializableTxPrepareFuture.java
index 916c7ab..f52b3fc 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticSerializableTxPrepareFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticSerializableTxPrepareFuture.java
@@ -304,9 +304,17 @@ public class GridNearOptimisticSerializableTxPrepareFuture extends GridNearOptim
             return;
         }
 
-        prepare(tx.readEntries(), tx.writeEntries(), remap, topLocked);
+        boolean set = cctx.tm().setTxTopologyHint(tx);
 
-        markInitialized();
+        try {
+            prepare(tx.readEntries(), tx.writeEntries(), remap, topLocked);
+
+            markInitialized();
+        }
+        finally {
+            if (set)
+                cctx.tm().setTxTopologyHint(null);
+        }
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/59ee87e1/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
index ca1d36c..2ce14af 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
@@ -405,82 +405,90 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearOptimisticTxPrepa
         if (isDone())
             return;
 
-        assert !m.empty();
-
-        final ClusterNode n = m.node();
-
-        GridNearTxPrepareRequest req = new GridNearTxPrepareRequest(
-            futId,
-            tx.topologyVersion(),
-            tx,
-            null,
-            m.writes(),
-            m.near(),
-            txMapping.transactionNodes(),
-            m.last(),
-            tx.onePhaseCommit(),
-            tx.needReturnValue() && tx.implicit(),
-            tx.implicitSingle(),
-            m.explicitLock(),
-            tx.subjectId(),
-            tx.taskNameHash(),
-            m.clientFirst(),
-            tx.activeCachesDeploymentEnabled());
-
-        for (IgniteTxEntry txEntry : m.writes()) {
-            if (txEntry.op() == TRANSFORM)
-                req.addDhtVersion(txEntry.txKey(), null);
-        }
-
-        // Must lock near entries separately.
-        if (m.near()) {
-            try {
-                tx.optimisticLockEntries(req.writes());
+        boolean set = cctx.tm().setTxTopologyHint(tx);
 
-                tx.userPrepare();
+        try {
+            assert !m.empty();
+
+            final ClusterNode n = m.node();
+
+            GridNearTxPrepareRequest req = new GridNearTxPrepareRequest(
+                futId,
+                tx.topologyVersion(),
+                tx,
+                null,
+                m.writes(),
+                m.near(),
+                txMapping.transactionNodes(),
+                m.last(),
+                tx.onePhaseCommit(),
+                tx.needReturnValue() && tx.implicit(),
+                tx.implicitSingle(),
+                m.explicitLock(),
+                tx.subjectId(),
+                tx.taskNameHash(),
+                m.clientFirst(),
+                tx.activeCachesDeploymentEnabled());
+
+            for (IgniteTxEntry txEntry : m.writes()) {
+                if (txEntry.op() == TRANSFORM)
+                    req.addDhtVersion(txEntry.txKey(), null);
             }
-            catch (IgniteCheckedException e) {
-                onError(e);
+
+            // Must lock near entries separately.
+            if (m.near()) {
+                try {
+                    tx.optimisticLockEntries(req.writes());
+
+                    tx.userPrepare();
+                }
+                catch (IgniteCheckedException e) {
+                    onError(e);
+                }
             }
-        }
 
-        final MiniFuture fut = new MiniFuture(m, mappings);
+            final MiniFuture fut = new MiniFuture(m, mappings);
 
-        req.miniId(fut.futureId());
+            req.miniId(fut.futureId());
 
-        add(fut); // Append new future.
+            add(fut); // Append new future.
 
-        // If this is the primary node for the keys.
-        if (n.isLocal()) {
-            // At this point, if any new node joined, then it is
-            // waiting for this transaction to complete, so
-            // partition reassignments are not possible here.
-            IgniteInternalFuture<GridNearTxPrepareResponse> prepFut = cctx.tm().txHandler().prepareTx(n.id(), tx, req);
+            // If this is the primary node for the keys.
+            if (n.isLocal()) {
+                // At this point, if any new node joined, then it is
+                // waiting for this transaction to complete, so
+                // partition reassignments are not possible here.
+                IgniteInternalFuture<GridNearTxPrepareResponse> prepFut = cctx.tm().txHandler().prepareTx(n.id(), tx, req);
 
-            prepFut.listen(new CI1<IgniteInternalFuture<GridNearTxPrepareResponse>>() {
-                @Override public void apply(IgniteInternalFuture<GridNearTxPrepareResponse> prepFut) {
-                    try {
-                        fut.onResult(n.id(), prepFut.get());
-                    }
-                    catch (IgniteCheckedException e) {
-                        fut.onResult(e);
+                prepFut.listen(new CI1<IgniteInternalFuture<GridNearTxPrepareResponse>>() {
+                    @Override public void apply(IgniteInternalFuture<GridNearTxPrepareResponse> prepFut) {
+                        try {
+                            fut.onResult(n.id(), prepFut.get());
+                        }
+                        catch (IgniteCheckedException e) {
+                            fut.onResult(e);
+                        }
                     }
-                }
-            });
-        }
-        else {
-            try {
-                cctx.io().send(n, req, tx.ioPolicy());
+                });
             }
-            catch (ClusterTopologyCheckedException e) {
-                e.retryReadyFuture(cctx.nextAffinityReadyFuture(tx.topologyVersion()));
+            else {
+                try {
+                    cctx.io().send(n, req, tx.ioPolicy());
+                }
+                catch (ClusterTopologyCheckedException e) {
+                    e.retryReadyFuture(cctx.nextAffinityReadyFuture(tx.topologyVersion()));
 
-                fut.onResult(e);
-            }
-            catch (IgniteCheckedException e) {
-                fut.onResult(e);
+                    fut.onResult(e);
+                }
+                catch (IgniteCheckedException e) {
+                    fut.onResult(e);
+                }
             }
         }
+        finally {
+            if (set)
+                cctx.tm().setTxTopologyHint(null);
+        }
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/59ee87e1/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/CacheObjectPortableContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/CacheObjectPortableContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/CacheObjectPortableContext.java
index c83c9af..719d0a9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/CacheObjectPortableContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/CacheObjectPortableContext.java
@@ -18,6 +18,7 @@
 package org.apache.ignite.internal.processors.cache.portable;
 
 import org.apache.ignite.internal.GridKernalContext;
+import org.apache.ignite.internal.processors.cache.CacheDefaultBinaryAffinityKeyMapper;
 import org.apache.ignite.internal.processors.cache.CacheObjectContext;
 import org.apache.ignite.internal.processors.cache.GridCacheDefaultAffinityKeyMapper;
 
@@ -40,7 +41,7 @@ public class CacheObjectPortableContext extends CacheObjectContext {
         boolean storeVal,
         boolean portableEnabled,
         boolean depEnabled) {
-        super(kernalCtx, portableEnabled ? new CacheDefaultPortableAffinityKeyMapper() :
+        super(kernalCtx, portableEnabled ? new CacheDefaultBinaryAffinityKeyMapper() :
             new GridCacheDefaultAffinityKeyMapper(), cpyOnGet, storeVal, depEnabled);
 
         this.portableEnabled = portableEnabled;

http://git-wip-us.apache.org/repos/asf/ignite/blob/59ee87e1/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java
index 63a4cbe..61a9bed 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java
@@ -413,7 +413,7 @@ public class IgniteTxHandler {
                 req.transactionNodes(),
                 req.last());
 
-            if (tx.isRollbackOnly()) {
+            if (tx.isRollbackOnly() && !tx.commitOnPrepare()) {
                 try {
                     if (tx.state() != TransactionState.ROLLED_BACK && tx.state() != TransactionState.ROLLING_BACK)
                         tx.rollback();
@@ -713,6 +713,10 @@ public class IgniteTxHandler {
             }
         }
         catch (Throwable e) {
+            tx.commitError(e);
+
+            tx.systemInvalidate(true);
+
             U.error(log, "Failed completing transaction [commit=" + req.commit() + ", tx=" + tx + ']', e);
 
             IgniteInternalFuture<IgniteInternalTx> res = null;

http://git-wip-us.apache.org/repos/asf/ignite/blob/59ee87e1/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
index 421b0e6..243c4cb 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
@@ -114,6 +114,9 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
     /** Committing transactions. */
     private final ThreadLocal<IgniteInternalTx> threadCtx = new ThreadLocal<>();
 
+    /** Transaction which topology version should be used when mapping internal tx. */
+    private final ThreadLocal<IgniteInternalTx> txTopology = new ThreadLocal<>();
+
     /** Per-thread transaction map. */
     private final ConcurrentMap<Long, IgniteInternalTx> threadMap = newMap();
 
@@ -622,7 +625,24 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
                 return tx;
         }
 
-        return null;
+        return txTopology.get();
+    }
+
+    /**
+     * @param tx Transaction.
+     */
+    public boolean setTxTopologyHint(IgniteInternalTx tx) {
+        if (tx == null)
+            txTopology.remove();
+        else {
+            if (txTopology.get() == null) {
+                txTopology.set(tx);
+
+                return true;
+            }
+        }
+
+        return false;
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/59ee87e1/modules/core/src/test/java/org/apache/ignite/internal/portable/BinaryMarshallerSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/portable/BinaryMarshallerSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/portable/BinaryMarshallerSelfTest.java
index ad0dcf2..cc035f6 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/portable/BinaryMarshallerSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/portable/BinaryMarshallerSelfTest.java
@@ -2105,7 +2105,7 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest {
             if (id == GridPortableMarshaller.UNREGISTERED_TYPE_ID)
                 continue;
 
-            PortableClassDescriptor desc = pCtx.descriptorForTypeId(false, entry.getValue(), null);
+            PortableClassDescriptor desc = pCtx.descriptorForTypeId(false, entry.getValue(), null, false);
 
             assertEquals(desc.typeId(), pCtx.typeId(desc.describedClass().getName()));
             assertEquals(desc.typeId(), pCtx.typeId(pCtx.typeName(desc.describedClass().getName())));

http://git-wip-us.apache.org/repos/asf/ignite/blob/59ee87e1/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CachePutEventListenerErrorSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CachePutEventListenerErrorSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CachePutEventListenerErrorSelfTest.java
new file mode 100644
index 0000000..0e0e521
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CachePutEventListenerErrorSelfTest.java
@@ -0,0 +1,180 @@
+/*
+ * 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.processors.cache;
+
+import java.util.UUID;
+import javax.cache.CacheException;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.Ignition;
+import org.apache.ignite.cache.CacheAtomicityMode;
+import org.apache.ignite.cache.CacheMemoryMode;
+import org.apache.ignite.cache.CacheMode;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.events.Event;
+import org.apache.ignite.events.EventType;
+import org.apache.ignite.lang.IgniteBiPredicate;
+import org.apache.ignite.lang.IgnitePredicate;
+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;
+
+/**
+ * Test for cache put with error in event listener.
+ */
+public class CachePutEventListenerErrorSelfTest extends GridCommonAbstractTest {
+    /** */
+    private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+        TcpDiscoverySpi disco = new TcpDiscoverySpi();
+
+        disco.setIpFinder(IP_FINDER);
+
+        cfg.setDiscoverySpi(disco);
+
+        cfg.setIncludeEventTypes(EventType.EVT_CACHE_OBJECT_PUT);
+
+        return cfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTestsStarted() throws Exception {
+        startGridsMultiThreaded(3);
+
+        Ignition.setClientMode(true);
+
+        Ignite ignite = startGrid("client");
+
+        ignite.events().remoteListen(
+            new IgniteBiPredicate<UUID, Event>() {
+                @Override public boolean apply(UUID uuid, Event evt) {
+                    return true;
+                }
+            },
+            new IgnitePredicate<Event>() {
+                @Override public boolean apply(Event evt) {
+                    throw new NoClassDefFoundError("XXX");
+                }
+            },
+            EventType.EVT_CACHE_OBJECT_PUT
+        );
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTestsStopped() throws Exception {
+        stopAllGrids();
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testPartitionedAtomicOnHeap() throws Exception {
+        doTest(CacheMode.PARTITIONED, CacheAtomicityMode.ATOMIC, CacheMemoryMode.ONHEAP_TIERED);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testPartitionedAtomicOffHeap() throws Exception {
+        doTest(CacheMode.PARTITIONED, CacheAtomicityMode.ATOMIC, CacheMemoryMode.OFFHEAP_TIERED);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testPartitionedTransactionalOnHeap() throws Exception {
+        doTest(CacheMode.PARTITIONED, CacheAtomicityMode.TRANSACTIONAL, CacheMemoryMode.ONHEAP_TIERED);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testPartitionedTransactionalOffHeap() throws Exception {
+        doTest(CacheMode.PARTITIONED, CacheAtomicityMode.TRANSACTIONAL, CacheMemoryMode.OFFHEAP_TIERED);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testReplicatedAtomicOnHeap() throws Exception {
+        doTest(CacheMode.REPLICATED, CacheAtomicityMode.ATOMIC, CacheMemoryMode.ONHEAP_TIERED);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testReplicatedAtomicOffHeap() throws Exception {
+        doTest(CacheMode.REPLICATED, CacheAtomicityMode.ATOMIC, CacheMemoryMode.OFFHEAP_TIERED);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testReplicatedTransactionalOnHeap() throws Exception {
+        doTest(CacheMode.REPLICATED, CacheAtomicityMode.TRANSACTIONAL, CacheMemoryMode.ONHEAP_TIERED);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testReplicatedTransactionalOffHeap() throws Exception {
+        doTest(CacheMode.REPLICATED, CacheAtomicityMode.TRANSACTIONAL, CacheMemoryMode.OFFHEAP_TIERED);
+    }
+
+    /**
+     * @param cacheMode Cache mode.
+     * @param atomicityMode Atomicity mode.
+     * @param memMode Memory mode.
+     * @throws Exception If failed.
+     */
+    private void doTest(CacheMode cacheMode, CacheAtomicityMode atomicityMode, CacheMemoryMode memMode)
+        throws Exception {
+        Ignite ignite = grid("client");
+
+        try {
+            CacheConfiguration<Integer, Integer> cfg = defaultCacheConfiguration();
+
+            cfg.setName("cache");
+            cfg.setCacheMode(cacheMode);
+            cfg.setAtomicityMode(atomicityMode);
+            cfg.setMemoryMode(memMode);
+
+            IgniteCache<Integer, Integer> cache = ignite.createCache(cfg).withAsync();
+
+            cache.put(0, 0);
+
+            try {
+                cache.future().get(2000);
+
+                assert false : "Exception was not thrown";
+            }
+            catch (CacheException e) {
+                info("Caught expected exception: " + e);
+            }
+        }
+        finally {
+            ignite.destroyCache("cache");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/59ee87e1/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheOnCopyFlagAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheOnCopyFlagAbstractSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheOnCopyFlagAbstractSelfTest.java
index 10fb661..b9c1449 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheOnCopyFlagAbstractSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheOnCopyFlagAbstractSelfTest.java
@@ -284,6 +284,8 @@ public abstract class GridCacheOnCopyFlagAbstractSelfTest extends GridCacheAbstr
 
         GridCacheContext cctx = cache0.context();
 
+        boolean binary = cctx.cacheObjects().isPortableEnabled(null);
+
         for (Map.Entry<TestKey, TestValue> e : map.entrySet()) {
             GridCacheEntryEx entry = cache0.peekEx(e.getKey());
 
@@ -295,7 +297,10 @@ public abstract class GridCacheOnCopyFlagAbstractSelfTest extends GridCacheAbstr
 
             TestKey key1 = entry.key().value(cctx.cacheObjectContext(), true);
 
-            assertSame(key0, key1);
+            if (!binary)
+                assertSame(key0, key1);
+            else
+                assertNotSame(key0, key1);
 
             TestValue val0 = entry.rawGet().value(cctx.cacheObjectContext(), false);
 
@@ -330,6 +335,8 @@ public abstract class GridCacheOnCopyFlagAbstractSelfTest extends GridCacheAbstr
 
         GridCacheContext cctx = cache0.context();
 
+        boolean binary = cctx.cacheObjects().isPortableEnabled(null);
+
         for (Map.Entry<TestKey, byte[]> e : map.entrySet()) {
             GridCacheEntryEx entry = cache0.peekEx(e.getKey());
 
@@ -341,7 +348,10 @@ public abstract class GridCacheOnCopyFlagAbstractSelfTest extends GridCacheAbstr
 
             TestKey key1 = entry.key().value(cctx.cacheObjectContext(), true);
 
-            assertSame(key0, key1);
+            if (!binary)
+                assertSame(key0, key1);
+            else
+                assertNotSame(key0, key1);
 
             byte[] val0 = entry.rawGet().value(cctx.cacheObjectContext(), false);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/59ee87e1/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteBinaryMetadataUpdateChangingTopologySelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteBinaryMetadataUpdateChangingTopologySelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteBinaryMetadataUpdateChangingTopologySelfTest.java
new file mode 100644
index 0000000..e53650c
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteBinaryMetadataUpdateChangingTopologySelfTest.java
@@ -0,0 +1,245 @@
+/*
+ * 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.processors.cache.distributed;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.Callable;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.IgniteLogger;
+import org.apache.ignite.cache.CacheAtomicityMode;
+import org.apache.ignite.cluster.ClusterNode;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.IgniteInternalFuture;
+import org.apache.ignite.internal.IgniteNodeAttributes;
+import org.apache.ignite.internal.managers.communication.GridIoMessage;
+import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxPrepareResponse;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.T2;
+import org.apache.ignite.lang.IgniteInClosure;
+import org.apache.ignite.plugin.extensions.communication.Message;
+import org.apache.ignite.resources.LoggerResource;
+import org.apache.ignite.spi.IgniteSpiException;
+import org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi;
+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.GridTestUtils;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Tests specific scenario when binary metadata should be updated from a system thread
+ * and topology has been already changed since the original transaction start.
+ */
+public class IgniteBinaryMetadataUpdateChangingTopologySelfTest extends GridCommonAbstractTest {
+    /** */
+    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(null);
+
+        CacheConfiguration ccfg = new CacheConfiguration("cache");
+
+        ccfg.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);
+        ccfg.setBackups(1);
+
+        cfg.setCacheConfiguration(ccfg);
+
+        TcpDiscoverySpi discoSpi = new TcpDiscoverySpi();
+
+        discoSpi.setIpFinder(IP_FINDER);
+
+        cfg.setDiscoverySpi(discoSpi);
+
+        cfg.setCommunicationSpi(new TestCommunicationSpi());
+
+        return cfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTestsStarted() throws Exception {
+        startGrids(4);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTestsStopped() throws Exception {
+        stopAllGrids();
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testNoDeadlockOptimistic() throws Exception {
+        int key1 = primaryKey(ignite(1).cache("cache"));
+        int key2 = primaryKey(ignite(2).cache("cache"));
+
+        TestCommunicationSpi spi = (TestCommunicationSpi)ignite(1).configuration().getCommunicationSpi();
+
+        spi.blockMessages(GridNearTxPrepareResponse.class, ignite(0).cluster().localNode().id());
+
+        IgniteCache<Object, Object> cache = ignite(0).cache("cache").withAsync();
+
+        cache.putAll(F.asMap(key1, "val1", key2, new TestValue()));
+
+        try {
+            Thread.sleep(500);
+
+            IgniteInternalFuture<Void> fut = GridTestUtils.runAsync(new Callable<Void>() {
+                @Override public Void call() throws Exception {
+                    startGrid(4);
+
+                    return null;
+                }
+            });
+
+            Thread.sleep(500);
+
+            spi.stopBlock();
+
+            cache.future().get();
+
+            fut.get();
+        }
+        finally {
+            stopGrid(4);
+        }
+    }
+
+    /**
+     *
+     */
+    private static class TestCommunicationSpi extends TcpCommunicationSpi {
+        /** */
+        @LoggerResource
+        private IgniteLogger log;
+
+        /** */
+        private List<T2<ClusterNode, GridIoMessage>> blockedMsgs = new ArrayList<>();
+
+        /** */
+        private Map<Class<?>, Set<UUID>> blockCls = new HashMap<>();
+
+        /** */
+        private Class<?> recordCls;
+
+        /** */
+        private List<Object> recordedMsgs = new ArrayList<>();
+
+        /** {@inheritDoc} */
+        @Override public void sendMessage(ClusterNode node, Message msg, IgniteInClosure<IgniteException> ackClosure)
+            throws IgniteSpiException {
+            if (msg instanceof GridIoMessage) {
+                Object msg0 = ((GridIoMessage)msg).message();
+
+                synchronized (this) {
+                    if (recordCls != null && msg0.getClass().equals(recordCls))
+                        recordedMsgs.add(msg0);
+
+                    Set<UUID> blockNodes = blockCls.get(msg0.getClass());
+
+                    if (F.contains(blockNodes, node.id())) {
+                        log.info("Block message [node=" + node.attribute(IgniteNodeAttributes.ATTR_GRID_NAME) +
+                            ", msg=" + msg0 + ']');
+
+                        blockedMsgs.add(new T2<>(node, (GridIoMessage)msg));
+
+                        return;
+                    }
+                }
+            }
+
+            super.sendMessage(node, msg, ackClosure);
+        }
+
+        /**
+         * @param recordCls Message class to record.
+         */
+        void record(@Nullable Class<?> recordCls) {
+            synchronized (this) {
+                this.recordCls = recordCls;
+            }
+        }
+
+        /**
+         * @return Recorded messages.
+         */
+        List<Object> recordedMessages() {
+            synchronized (this) {
+                List<Object> msgs = recordedMsgs;
+
+                recordedMsgs = new ArrayList<>();
+
+                return msgs;
+            }
+        }
+
+        /**
+         * @param cls Message class.
+         * @param nodeId Node ID.
+         */
+        void blockMessages(Class<?> cls, UUID nodeId) {
+            synchronized (this) {
+                Set<UUID> set = blockCls.get(cls);
+
+                if (set == null) {
+                    set = new HashSet<>();
+
+                    blockCls.put(cls, set);
+                }
+
+                set.add(nodeId);
+            }
+        }
+
+        /**
+         *
+         */
+        void stopBlock() {
+            synchronized (this) {
+                blockCls.clear();
+
+                for (T2<ClusterNode, GridIoMessage> msg : blockedMsgs) {
+                    ClusterNode node = msg.get1();
+
+                    log.info("Send blocked message: [node=" + node.attribute(IgniteNodeAttributes.ATTR_GRID_NAME) +
+                        ", msg=" + msg.get2().message() + ']');
+
+                    sendMessage(msg.get1(), msg.get2());
+                }
+
+                blockedMsgs.clear();
+            }
+        }
+    }
+
+    private static class TestValue {
+        /** Field1. */
+        private String field1;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/59ee87e1/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/GridReplicatedTxPreloadTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/GridReplicatedTxPreloadTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/GridReplicatedTxPreloadTest.java
index e7560c7..126ce61 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/GridReplicatedTxPreloadTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/GridReplicatedTxPreloadTest.java
@@ -18,6 +18,7 @@
 package org.apache.ignite.internal.processors.cache.distributed.replicated;
 
 import org.apache.ignite.cache.CacheMode;
+import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.internal.processors.cache.distributed.IgniteTxPreloadAbstractTest;
 
 import static org.apache.ignite.cache.CacheMode.REPLICATED;
@@ -32,6 +33,11 @@ public class GridReplicatedTxPreloadTest extends IgniteTxPreloadAbstractTest {
     }
 
     /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+        return super.getConfiguration(gridName).setMarshaller(null);
+    }
+
+    /** {@inheritDoc} */
     @Override public void testLocalTxPreloadingOptimistic() throws Exception {
         fail("https://issues.apache.org/jira/browse/IGNITE-1755");
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/59ee87e1/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/preloader/GridCacheReplicatedPreloadLifecycleSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/preloader/GridCacheReplicatedPreloadLifecycleSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/preloader/GridCacheReplicatedPreloadLifecycleSelfTest.java
index fcaafd7..6a7a68b 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/preloader/GridCacheReplicatedPreloadLifecycleSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/preloader/GridCacheReplicatedPreloadLifecycleSelfTest.java
@@ -192,46 +192,7 @@ public class GridCacheReplicatedPreloadLifecycleSelfTest extends GridCachePreloa
 
                 qry = qry.projection(grid(j).cluster());
 
-                int totalCnt = F.sumInt(qry.execute(new IgniteReducer<Map.Entry<Object, MyValue>, Integer>() {
-                    @IgniteInstanceResource
-                    private Ignite grid;
-
-                    @LoggerResource
-                    private IgniteLogger log0;
-
-                    private int cnt;
-
-                    @Override public boolean collect(Map.Entry<Object, MyValue> e) {
-                        if (!quiet && log0.isInfoEnabled())
-                            log0.info("Collecting entry: " + e);
-
-                        Object key = e.getKey();
-
-                        assertNotNull(e.getValue());
-
-                        try {
-                            Object v1 = e.getValue();
-                            Object v2 = ((IgniteKernal)grid).getCache("one").get(key);
-
-                            assertNotNull("Cache c1 misses value for key [i=" + j0 + ", j=" + i0 + ", missedKey=" +
-                                key + ", cache=" + ((IgniteKernal)grid).getCache("one").values() + ']', v2);
-                            assertEquals(v1, v2);
-                        }
-                        catch (IgniteCheckedException e1) {
-                            e1.printStackTrace();
-
-                            assert false;
-                        }
-
-                        cnt++;
-
-                        return true;
-                    }
-
-                    @Override public Integer reduce() {
-                        return cnt;
-                    }
-                }).get());
+                int totalCnt = F.sumInt(qry.execute(new EntryReducer(j0, i0)).get());
 
                 info("Total entry count [grid=" + j + ", totalCnt=" + totalCnt + ']');
 
@@ -295,4 +256,63 @@ public class GridCacheReplicatedPreloadLifecycleSelfTest extends GridCachePreloa
     public void testScanQuery4() throws Exception {
         checkScanQuery(keys(false, 500));
     }
+
+    private static class EntryReducer implements IgniteReducer<Map.Entry<Object, MyValue>, Integer> {
+        /** */
+        private final int j0;
+
+        /** */
+        private final int i0;
+
+        /** */
+        @IgniteInstanceResource
+        private Ignite grid;
+
+        /** */
+        @LoggerResource
+        private IgniteLogger log0;
+
+        /** */
+        private int cnt;
+
+        /**
+         */
+        public EntryReducer(int j0, int i0) {
+            this.j0 = j0;
+            this.i0 = i0;
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean collect(Map.Entry<Object, MyValue> e) {
+            if (!quiet && log0.isInfoEnabled())
+                log0.info("Collecting entry: " + e);
+
+            Object key = e.getKey();
+
+            assertNotNull(e.getValue());
+
+            try {
+                Object v1 = e.getValue();
+                Object v2 = ((IgniteKernal)grid).getCache("one").get(key);
+
+                assertNotNull("Cache c1 misses value for key [i=" + j0 + ", j=" + i0 + ", missedKey=" +
+                    key + ", cache=" + ((IgniteKernal)grid).getCache("one").values() + ']', v2);
+                assertEquals(v1, v2);
+            }
+            catch (IgniteCheckedException e1) {
+                e1.printStackTrace();
+
+                assert false;
+            }
+
+            cnt++;
+
+            return true;
+        }
+
+        /** {@inheritDoc} */
+        @Override public Integer reduce() {
+            return cnt;
+        }
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/59ee87e1/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite.java
index 4797ff1..ca31c28 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite.java
@@ -38,6 +38,7 @@ import org.apache.ignite.cache.store.jdbc.GridCacheJdbcBlobStoreSelfTest;
 import org.apache.ignite.internal.processors.cache.CacheAffinityCallSelfTest;
 import org.apache.ignite.internal.processors.cache.CacheDeferredDeleteSanitySelfTest;
 import org.apache.ignite.internal.processors.cache.CacheFutureExceptionSelfTest;
+import org.apache.ignite.internal.processors.cache.CachePutEventListenerErrorSelfTest;
 import org.apache.ignite.internal.processors.cache.CacheNamesSelfTest;
 import org.apache.ignite.internal.processors.cache.GridCacheAffinityApiSelfTest;
 import org.apache.ignite.internal.processors.cache.GridCacheAffinityMapperSelfTest;
@@ -276,6 +277,8 @@ public class IgniteCacheTestSuite extends TestSuite {
 
         suite.addTestSuite(IgniteCacheNearLockValueSelfTest.class);
 
+        suite.addTestSuite(CachePutEventListenerErrorSelfTest.class);
+
         return suite;
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/59ee87e1/modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePortableObjectsTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePortableObjectsTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePortableObjectsTestSuite.java
index 629835b..62952b5 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePortableObjectsTestSuite.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePortableObjectsTestSuite.java
@@ -37,6 +37,7 @@ import org.apache.ignite.internal.portable.noncompact.BinaryFooterOffsetsOffheap
 import org.apache.ignite.internal.portable.noncompact.BinaryMarshallerNonCompactSelfTest;
 import org.apache.ignite.internal.portable.noncompact.BinaryObjectBuilderAdditionalNonCompactSelfTest;
 import org.apache.ignite.internal.portable.noncompact.BinaryObjectBuilderNonCompactSelfTest;
+import org.apache.ignite.internal.processors.cache.distributed.IgniteBinaryMetadataUpdateChangingTopologySelfTest;
 import org.apache.ignite.internal.processors.cache.portable.GridCacheClientNodeBinaryObjectMetadataMultinodeTest;
 import org.apache.ignite.internal.processors.cache.portable.GridCacheClientNodeBinaryObjectMetadataTest;
 import org.apache.ignite.internal.processors.cache.portable.GridCachePortableStoreObjectsSelfTest;
@@ -106,6 +107,7 @@ public class IgnitePortableObjectsTestSuite extends TestSuite {
 
         suite.addTestSuite(GridCacheClientNodeBinaryObjectMetadataTest.class);
         suite.addTestSuite(GridCacheClientNodeBinaryObjectMetadataMultinodeTest.class);
+        suite.addTestSuite(IgniteBinaryMetadataUpdateChangingTopologySelfTest.class);
 
         return suite;
     }