http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/f586cfc2/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/GridOptimizedMarshallerUtils.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/GridOptimizedMarshallerUtils.java
 
b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/GridOptimizedMarshallerUtils.java
index 8cfaca8..de90035 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/GridOptimizedMarshallerUtils.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/GridOptimizedMarshallerUtils.java
@@ -22,10 +22,10 @@ import java.security.*;
 import java.util.*;
 import java.util.concurrent.*;
 
-import static 
org.apache.ignite.marshaller.optimized.GridOptimizedMarshallable.*;
+import static 
org.apache.ignite.marshaller.optimized.IgniteOptimizedMarshallable.*;
 
 /**
- * Miscellaneous utility methods to facilitate {@link GridOptimizedMarshaller}.
+ * Miscellaneous utility methods to facilitate {@link 
IgniteOptimizedMarshaller}.
  */
 class GridOptimizedMarshallerUtils {
     /** Unsafe. */
@@ -44,7 +44,7 @@ class GridOptimizedMarshallerUtils {
     static final Charset UTF_8 = Charset.forName("UTF-8");
 
     /** Class descriptors cache. */
-    private static final ConcurrentMap<Class<?>, GridOptimizedClassDescriptor> 
CLS_DESC_CACHE =
+    private static final ConcurrentMap<Class<?>, 
IgniteOptimizedClassDescriptor> CLS_DESC_CACHE =
         new ConcurrentHashMap8<>(256);
 
     /** Classes cache by name. */
@@ -105,21 +105,21 @@ class GridOptimizedMarshallerUtils {
      * @return Descriptor.
      * @throws IOException In case of error.
      */
-    static GridOptimizedClassDescriptor classDescriptor(Class<?> cls, 
@Nullable Object obj) throws IOException {
+    static IgniteOptimizedClassDescriptor classDescriptor(Class<?> cls, 
@Nullable Object obj) throws IOException {
         if (obj != null) {
-            if (obj instanceof GridOptimizedMarshallable) {
-                GridOptimizedMarshallable m = (GridOptimizedMarshallable)obj;
+            if (obj instanceof IgniteOptimizedMarshallable) {
+                IgniteOptimizedMarshallable m = 
(IgniteOptimizedMarshallable)obj;
 
                 Object clsId = m.ggClassId();
 
-                if (clsId != null && !(clsId instanceof 
GridOptimizedClassDescriptor))
+                if (clsId != null && !(clsId instanceof 
IgniteOptimizedClassDescriptor))
                     throw new IOException("Method '" + 
obj.getClass().getName() + ".ggClassId() must return " +
                         "the value of the field '" + CLS_ID_FIELD_NAME + "'.");
 
-                GridOptimizedClassDescriptor desc = 
(GridOptimizedClassDescriptor)clsId;
+                IgniteOptimizedClassDescriptor desc = 
(IgniteOptimizedClassDescriptor)clsId;
 
                 if (desc == null) {
-                    desc = new GridOptimizedClassDescriptor(cls);
+                    desc = new IgniteOptimizedClassDescriptor(cls);
 
                     try {
                         Field field = 
obj.getClass().getDeclaredField(CLS_ID_FIELD_NAME);
@@ -140,7 +140,7 @@ class GridOptimizedMarshallerUtils {
                                     "return the value of the field '" + 
CLS_ID_FIELD_NAME + "': "
                                     + obj.getClass().getName());
                         }
-                        else if (!(o instanceof GridOptimizedClassDescriptor))
+                        else if (!(o instanceof 
IgniteOptimizedClassDescriptor))
                             throw new IOException("Field '" + 
CLS_ID_FIELD_NAME + "' must be declared with " +
                                 "null value: " + obj.getClass().getName());
                     }
@@ -158,11 +158,11 @@ class GridOptimizedMarshallerUtils {
             }
         }
 
-        GridOptimizedClassDescriptor desc = CLS_DESC_CACHE.get(cls);
+        IgniteOptimizedClassDescriptor desc = CLS_DESC_CACHE.get(cls);
 
         if (desc == null) {
-            GridOptimizedClassDescriptor existing = 
CLS_DESC_CACHE.putIfAbsent(cls,
-                desc = new GridOptimizedClassDescriptor(cls));
+            IgniteOptimizedClassDescriptor existing = 
CLS_DESC_CACHE.putIfAbsent(cls,
+                desc = new IgniteOptimizedClassDescriptor(cls));
 
             if (existing != null)
                 desc = existing;
@@ -201,7 +201,7 @@ class GridOptimizedMarshallerUtils {
         X.println(">>> GridOptimizedMarshallerUtils memory stats:");
         X.println(" Cache size: " + CLS_DESC_CACHE.size());
 
-        for (Map.Entry<Class<?>, GridOptimizedClassDescriptor> e : 
CLS_DESC_CACHE.entrySet())
+        for (Map.Entry<Class<?>, IgniteOptimizedClassDescriptor> e : 
CLS_DESC_CACHE.entrySet())
             X.println(" " + e.getKey() + " : " + e.getValue());
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/f586cfc2/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/GridOptimizedObjectInputStream.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/GridOptimizedObjectInputStream.java
 
b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/GridOptimizedObjectInputStream.java
index 384b643..9aae0ab 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/GridOptimizedObjectInputStream.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/GridOptimizedObjectInputStream.java
@@ -45,13 +45,13 @@ class GridOptimizedObjectInputStream extends 
ObjectInputStream {
     private Object curObj;
 
     /** */
-    private List<T2<GridOptimizedFieldType, Long>> curFields;
+    private List<T2<IgniteOptimizedFieldType, Long>> curFields;
 
     /** */
-    private List<IgniteBiTuple<Integer, GridOptimizedFieldType>> 
curFieldInfoList;
+    private List<IgniteBiTuple<Integer, IgniteOptimizedFieldType>> 
curFieldInfoList;
 
     /** */
-    private Map<String, IgniteBiTuple<Integer, GridOptimizedFieldType>> 
curFieldInfoMap;
+    private Map<String, IgniteBiTuple<Integer, IgniteOptimizedFieldType>> 
curFieldInfoMap;
 
     /** */
     private Class<?> curCls;
@@ -133,7 +133,7 @@ class GridOptimizedObjectInputStream extends 
ObjectInputStream {
                 return handles.lookup(readInt());
 
             case OBJECT:
-                GridOptimizedClassDescriptor desc = 
GridOptimizedClassResolver.readClass(this, clsLdr);
+                IgniteOptimizedClassDescriptor desc = 
IgniteOptimizedClassResolver.readClass(this, clsLdr);
 
                 curCls = desc.describedClass();
 
@@ -220,10 +220,10 @@ class GridOptimizedObjectInputStream extends 
ObjectInputStream {
      * @throws IOException In case of error.
      */
     @SuppressWarnings("ForLoopReplaceableByForEach")
-    void readFields(Object obj, List<T2<GridOptimizedFieldType, Long>> 
fieldOffs) throws ClassNotFoundException,
+    void readFields(Object obj, List<T2<IgniteOptimizedFieldType, Long>> 
fieldOffs) throws ClassNotFoundException,
         IOException {
         for (int i = 0; i < fieldOffs.size(); i++) {
-            T2<GridOptimizedFieldType, Long> t = fieldOffs.get(i);
+            T2<IgniteOptimizedFieldType, Long> t = fieldOffs.get(i);
 
             switch ((t.get1())) {
                 case BYTE:
@@ -325,7 +325,7 @@ class GridOptimizedObjectInputStream extends 
ObjectInputStream {
      */
     @SuppressWarnings("ForLoopReplaceableByForEach")
     Object readSerializable(Class<?> cls, List<Method> mtds, Method 
readResolveMtd,
-        GridOptimizedClassDescriptor.Fields fields) throws 
ClassNotFoundException, IOException {
+        IgniteOptimizedClassDescriptor.Fields fields) throws 
ClassNotFoundException, IOException {
         Object obj;
 
         try {
@@ -869,7 +869,7 @@ class GridOptimizedObjectInputStream extends 
ObjectInputStream {
      */
     private static class GetFieldImpl extends GetField {
         /** Field info map. */
-        private final Map<String, IgniteBiTuple<Integer, 
GridOptimizedFieldType>> fieldInfoMap;
+        private final Map<String, IgniteBiTuple<Integer, 
IgniteOptimizedFieldType>> fieldInfoMap;
 
         /** Values. */
         private final Object[] objs;
@@ -883,12 +883,12 @@ class GridOptimizedObjectInputStream extends 
ObjectInputStream {
         private GetFieldImpl(GridOptimizedObjectInputStream in) throws 
IOException, ClassNotFoundException {
             fieldInfoMap = in.curFieldInfoMap;
 
-            List<IgniteBiTuple<Integer, GridOptimizedFieldType>> infos = 
in.curFieldInfoList;
+            List<IgniteBiTuple<Integer, IgniteOptimizedFieldType>> infos = 
in.curFieldInfoList;
 
             objs = new Object[infos.size()];
 
             for (int i = 0; i < infos.size(); i++) {
-                IgniteBiTuple<Integer, GridOptimizedFieldType> t = 
infos.get(i);
+                IgniteBiTuple<Integer, IgniteOptimizedFieldType> t = 
infos.get(i);
 
                 Object obj = null;
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/f586cfc2/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/GridOptimizedObjectOutputStream.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/GridOptimizedObjectOutputStream.java
 
b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/GridOptimizedObjectOutputStream.java
index 55125e3..bd78c36 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/GridOptimizedObjectOutputStream.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/GridOptimizedObjectOutputStream.java
@@ -44,10 +44,10 @@ class GridOptimizedObjectOutputStream extends 
ObjectOutputStream {
     private Object curObj;
 
     /** */
-    private List<T2<GridOptimizedFieldType, Long>> curFields;
+    private List<T2<IgniteOptimizedFieldType, Long>> curFields;
 
     /** */
-    private Map<String, IgniteBiTuple<Integer, GridOptimizedFieldType>> 
curFieldInfoMap;
+    private Map<String, IgniteBiTuple<Integer, IgniteOptimizedFieldType>> 
curFieldInfoMap;
 
     /** */
     private PutFieldImpl curPut;
@@ -148,7 +148,7 @@ class GridOptimizedObjectOutputStream extends 
ObjectOutputStream {
         else {
             Class<?> cls = obj.getClass();
 
-            GridOptimizedClassDescriptor desc = classDescriptor(cls, obj);
+            IgniteOptimizedClassDescriptor desc = classDescriptor(cls, obj);
 
             if (desc.excluded()) {
                 writeByte(NULL);
@@ -182,7 +182,7 @@ class GridOptimizedObjectOutputStream extends 
ObjectOutputStream {
             else {
                 writeByte(OBJECT);
 
-                GridOptimizedClassResolver.writeClass(this, desc);
+                IgniteOptimizedClassResolver.writeClass(this, desc);
 
                 desc.write(this, obj);
             }
@@ -268,7 +268,7 @@ class GridOptimizedObjectOutputStream extends 
ObjectOutputStream {
      * @throws IOException In case of error.
      */
     @SuppressWarnings("ForLoopReplaceableByForEach")
-    void writeSerializable(Object obj, List<Method> mtds, 
GridOptimizedClassDescriptor.Fields fields)
+    void writeSerializable(Object obj, List<Method> mtds, 
IgniteOptimizedClassDescriptor.Fields fields)
         throws IOException {
         for (int i = 0; i < mtds.size(); i++) {
             Method mtd = mtds.get(i);
@@ -422,9 +422,9 @@ class GridOptimizedObjectOutputStream extends 
ObjectOutputStream {
      * @throws IOException In case of error.
      */
     @SuppressWarnings("ForLoopReplaceableByForEach")
-    private void writeFields(Object obj, List<T2<GridOptimizedFieldType, 
Long>> fieldOffs) throws IOException {
+    private void writeFields(Object obj, List<T2<IgniteOptimizedFieldType, 
Long>> fieldOffs) throws IOException {
         for (int i = 0; i < fieldOffs.size(); i++) {
-            T2<GridOptimizedFieldType, Long> t = fieldOffs.get(i);
+            T2<IgniteOptimizedFieldType, Long> t = fieldOffs.get(i);
 
             switch (t.get1()) {
                 case BYTE:
@@ -660,7 +660,7 @@ class GridOptimizedObjectOutputStream extends 
ObjectOutputStream {
         if (curPut == null)
             throw new NotActiveException("putFields() was not called.");
 
-        for (IgniteBiTuple<GridOptimizedFieldType, Object> t : curPut.objs) {
+        for (IgniteBiTuple<IgniteOptimizedFieldType, Object> t : curPut.objs) {
             switch (t.get1()) {
                 case BYTE:
                     writeByte((Byte)t.get2());
@@ -747,10 +747,10 @@ class GridOptimizedObjectOutputStream extends 
ObjectOutputStream {
         private final GridOptimizedObjectOutputStream out;
 
         /** Field info map. */
-        private final Map<String, IgniteBiTuple<Integer, 
GridOptimizedFieldType>> fieldInfoMap;
+        private final Map<String, IgniteBiTuple<Integer, 
IgniteOptimizedFieldType>> fieldInfoMap;
 
         /** Values. */
-        private final IgniteBiTuple<GridOptimizedFieldType, Object>[] objs;
+        private final IgniteBiTuple<IgniteOptimizedFieldType, Object>[] objs;
 
         /**
          * @param out Output stream.
@@ -823,7 +823,7 @@ class GridOptimizedObjectOutputStream extends 
ObjectOutputStream {
          * @param val Value.
          */
         private void value(String name, Object val) {
-            IgniteBiTuple<Integer, GridOptimizedFieldType> info = 
fieldInfoMap.get(name);
+            IgniteBiTuple<Integer, IgniteOptimizedFieldType> info = 
fieldInfoMap.get(name);
 
             objs[info.get1()] = F.t(info.get2(), val);
         }

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/f586cfc2/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/IgniteOptimizedClassDescriptor.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/IgniteOptimizedClassDescriptor.java
 
b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/IgniteOptimizedClassDescriptor.java
new file mode 100644
index 0000000..eafa113
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/IgniteOptimizedClassDescriptor.java
@@ -0,0 +1,1032 @@
+/* @java.file.header */
+
+/*  _________        _____ __________________        _____
+ *  __  ____/___________(_)______  /__  ____/______ ____(_)_______
+ *  _  / __  __  ___/__  / _  __  / _  / __  _  __ `/__  / __  __ \
+ *  / /_/ /  _  /    _  /  / /_/ /  / /_/ /  / /_/ / _  /  _  / / /
+ *  \____/   /_/     /_/   \_,__/   \____/   \__,_/  /_/   /_/ /_/
+ */
+
+package org.apache.ignite.marshaller.optimized;
+
+import org.apache.ignite.lang.*;
+import org.apache.ignite.marshaller.*;
+import org.gridgain.grid.util.*;
+import org.gridgain.grid.util.typedef.*;
+import sun.misc.*;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import static java.lang.reflect.Modifier.*;
+
+/**
+ * Class descriptor.
+ */
+class IgniteOptimizedClassDescriptor {
+    /** Unsafe. */
+    private static final Unsafe UNSAFE = GridUnsafe.unsafe();
+
+    /** */
+    private static final int TYPE_BYTE = 1;
+
+    /** */
+    private static final int TYPE_SHORT = 2;
+
+    /** */
+    private static final int TYPE_INT = 3;
+
+    /** */
+    private static final int TYPE_LONG = 4;
+
+    /** */
+    private static final int TYPE_FLOAT = 5;
+
+    /** */
+    private static final int TYPE_DOUBLE = 6;
+
+    /** */
+    private static final int TYPE_CHAR = 7;
+
+    /** */
+    private static final int TYPE_BOOLEAN = 8;
+
+    /** */
+    private static final int TYPE_BYTE_ARR = 9;
+
+    /** */
+    private static final int TYPE_SHORT_ARR = 10;
+
+    /** */
+    private static final int TYPE_INT_ARR = 11;
+
+    /** */
+    private static final int TYPE_LONG_ARR = 12;
+
+    /** */
+    private static final int TYPE_FLOAT_ARR = 13;
+
+    /** */
+    private static final int TYPE_DOUBLE_ARR = 14;
+
+    /** */
+    private static final int TYPE_CHAR_ARR = 15;
+
+    /** */
+    private static final int TYPE_BOOLEAN_ARR = 16;
+
+    /** */
+    private static final int TYPE_OBJ_ARR = 17;
+
+    /** */
+    private static final int TYPE_STR = 18;
+
+    /** */
+    private static final int TYPE_ENUM = 19;
+
+    /** */
+    private static final int TYPE_UUID = 20;
+
+    /** */
+    private static final int TYPE_PROPS = 21;
+
+    /** */
+    private static final int TYPE_ARRAY_LIST = 22;
+
+    /** */
+    private static final int TYPE_HASH_MAP = 23;
+
+    /** */
+    private static final int TYPE_HASH_SET = 24;
+
+    /** */
+    private static final int TYPE_LINKED_LIST = 25;
+
+    /** */
+    private static final int TYPE_LINKED_HASH_MAP = 26;
+
+    /** */
+    private static final int TYPE_LINKED_HASH_SET = 27;
+
+    /** */
+    private static final int TYPE_DATE = 28;
+
+    /** */
+    private static final int TYPE_CLS = 29;
+
+    /** */
+    private static final int TYPE_EXTERNALIZABLE = 50;
+
+    /** */
+    private static final int TYPE_SERIALIZABLE = 51;
+
+    /** Class. */
+    private Class<?> cls;
+
+    /** Header. */
+    private Integer hdr;
+
+    /** ID. */
+    private Integer id;
+
+    /** Short ID. */
+    private Short shortId;
+
+    /** Class name. */
+    private String name;
+
+    /** Class type. */
+    private int type;
+
+    /** Primitive flag. */
+    private boolean isPrimitive;
+
+    /** Enum flag. */
+    private boolean isEnum;
+
+    /** Serializable flag. */
+    private boolean isSerial;
+
+    /** Excluded flag. */
+    private final boolean excluded;
+
+    /** {@code True} if descriptor is for {@link Class}. */
+    private boolean isCls;
+
+    /** Array component type. */
+    private Class<?> arrCompType;
+
+    /** Enumeration values. */
+    private Object[] enumVals;
+
+    /** Constructor. */
+    private Constructor<?> constructor;
+
+    /** Fields. */
+    private Fields fields;
+
+    /** {@code writeObject} methods. */
+    private List<Method> writeObjMtds;
+
+    /** {@code writeReplace} method. */
+    private Method writeReplaceMtd;
+
+    /** {@code readObject} methods. */
+    private List<Method> readObjMtds;
+
+    /** {@code readResolve} method. */
+    private Method readResolveMtd;
+
+    /** Defaults field offset. */
+    private long dfltsFieldOff;
+
+    /** Load factor field offset. */
+    private long loadFactorFieldOff;
+
+    /** Map field offset. */
+    private long mapFieldOff;
+
+    /** Access order field offset. */
+    private long accessOrderFieldOff;
+
+    /**
+     * Creates descriptor for class.
+     *
+     * @param cls Class.
+     * @throws IOException In case of error.
+     */
+    @SuppressWarnings({"ForLoopReplaceableByForEach", 
"MapReplaceableByEnumMap"})
+    IgniteOptimizedClassDescriptor(Class<?> cls) throws IOException {
+        this.cls = cls;
+
+        excluded = GridMarshallerExclusions.isExcluded(cls);
+
+        T2<Integer, Integer> t = 
IgniteOptimizedClassResolver.writeClassData(cls);
+
+        hdr = t.get1();
+        id = t.get2();
+        name = cls.getName();
+
+        if (!excluded) {
+            Class<?> parent;
+
+            if (cls == byte.class || cls == Byte.class) {
+                type = TYPE_BYTE;
+
+                isPrimitive = true;
+            }
+            else if (cls == short.class || cls == Short.class) {
+                type = TYPE_SHORT;
+
+                isPrimitive = true;
+            }
+            else if (cls == int.class || cls == Integer.class) {
+                type = TYPE_INT;
+
+                isPrimitive = true;
+            }
+            else if (cls == long.class || cls == Long.class) {
+                type = TYPE_LONG;
+
+                isPrimitive = true;
+            }
+            else if (cls == float.class || cls == Float.class) {
+                type = TYPE_FLOAT;
+
+                isPrimitive = true;
+            }
+            else if (cls == double.class || cls == Double.class) {
+                type = TYPE_DOUBLE;
+
+                isPrimitive = true;
+            }
+            else if (cls == char.class || cls == Character.class) {
+                type = TYPE_CHAR;
+
+                isPrimitive = true;
+            }
+            else if (cls == boolean.class || cls == Boolean.class) {
+                type = TYPE_BOOLEAN;
+
+                isPrimitive = true;
+            }
+            else if (cls == byte[].class)
+                type = TYPE_BYTE_ARR;
+            else if (cls == short[].class)
+                type = TYPE_SHORT_ARR;
+            else if (cls == int[].class)
+                type = TYPE_INT_ARR;
+            else if (cls == long[].class)
+                type = TYPE_LONG_ARR;
+            else if (cls == float[].class)
+                type = TYPE_FLOAT_ARR;
+            else if (cls == double[].class)
+                type = TYPE_DOUBLE_ARR;
+            else if (cls == char[].class)
+                type = TYPE_CHAR_ARR;
+            else if (cls == boolean[].class)
+                type = TYPE_BOOLEAN_ARR;
+            else if (cls.isArray()) {
+                type = TYPE_OBJ_ARR;
+
+                arrCompType = cls.getComponentType();
+            }
+            else if (cls == String.class)
+                type = TYPE_STR;
+            else if (cls.isEnum()) {
+                type = TYPE_ENUM;
+
+                isEnum = true;
+                enumVals = cls.getEnumConstants();
+            }
+            // Support for enum constants, based on anonymous children classes.
+            else if ((parent = cls.getSuperclass()) != null && 
parent.isEnum()) {
+                type = TYPE_ENUM;
+
+                isEnum = true;
+                enumVals = parent.getEnumConstants();
+            }
+            else if (cls == UUID.class)
+                type = TYPE_UUID;
+            else if (cls == Properties.class) {
+                type = TYPE_PROPS;
+
+                try {
+                    dfltsFieldOff = 
UNSAFE.objectFieldOffset(Properties.class.getDeclaredField("defaults"));
+                }
+                catch (NoSuchFieldException e) {
+                    throw new IOException(e);
+                }
+            }
+            else if (cls == ArrayList.class)
+                type = TYPE_ARRAY_LIST;
+            else if (cls == HashMap.class) {
+                type = TYPE_HASH_MAP;
+
+                try {
+                    loadFactorFieldOff = 
UNSAFE.objectFieldOffset(HashMap.class.getDeclaredField("loadFactor"));
+                }
+                catch (NoSuchFieldException e) {
+                    throw new IOException(e);
+                }
+            }
+            else if (cls == HashSet.class) {
+                type = TYPE_HASH_SET;
+
+                try {
+                    loadFactorFieldOff = 
UNSAFE.objectFieldOffset(HashMap.class.getDeclaredField("loadFactor"));
+                    mapFieldOff = 
UNSAFE.objectFieldOffset(HashSet.class.getDeclaredField("map"));
+                }
+                catch (NoSuchFieldException e) {
+                    throw new IOException(e);
+                }
+            }
+            else if (cls == LinkedList.class)
+                type = TYPE_LINKED_LIST;
+            else if (cls == LinkedHashMap.class) {
+                type = TYPE_LINKED_HASH_MAP;
+
+                try {
+                    loadFactorFieldOff = 
UNSAFE.objectFieldOffset(HashMap.class.getDeclaredField("loadFactor"));
+                    accessOrderFieldOff = 
UNSAFE.objectFieldOffset(LinkedHashMap.class.getDeclaredField("accessOrder"));
+                }
+                catch (NoSuchFieldException e) {
+                    throw new IOException(e);
+                }
+            }
+            else if (cls == LinkedHashSet.class) {
+                type = TYPE_LINKED_HASH_SET;
+
+                try {
+                    loadFactorFieldOff = 
UNSAFE.objectFieldOffset(HashMap.class.getDeclaredField("loadFactor"));
+                    mapFieldOff = 
UNSAFE.objectFieldOffset(HashSet.class.getDeclaredField("map"));
+                }
+                catch (NoSuchFieldException e) {
+                    throw new IOException(e);
+                }
+            }
+            else if (cls == Date.class)
+                type = TYPE_DATE;
+            else if (cls == Class.class) {
+                type = TYPE_CLS;
+
+                isCls = true;
+            }
+            else {
+                Class<?> c = cls;
+
+                while ((writeReplaceMtd == null || readResolveMtd == null) && 
c != null && !c.equals(Object.class)) {
+                    if (writeReplaceMtd == null) {
+                        try {
+                            writeReplaceMtd = 
c.getDeclaredMethod("writeReplace");
+
+                            if (!isStatic(writeReplaceMtd.getModifiers()) &&
+                                !(isPrivate(writeReplaceMtd.getModifiers()) && 
c != cls) &&
+                                
writeReplaceMtd.getReturnType().equals(Object.class))
+                                writeReplaceMtd.setAccessible(true);
+                            else
+                                // Set method back to null if it has incorrect 
signature.
+                                writeReplaceMtd = null;
+                        }
+                        catch (NoSuchMethodException ignored) {
+                            // No-op.
+                        }
+                    }
+
+                    if (readResolveMtd == null) {
+                        try {
+                            readResolveMtd = 
c.getDeclaredMethod("readResolve");
+
+                            if (!isStatic(readResolveMtd.getModifiers()) &&
+                                !(isPrivate(readResolveMtd.getModifiers()) && 
c != cls) &&
+                                
readResolveMtd.getReturnType().equals(Object.class))
+                                readResolveMtd.setAccessible(true);
+                            else
+                                // Set method back to null if it has incorrect 
signature.
+                                readResolveMtd = null;
+                        }
+                        catch (NoSuchMethodException ignored) {
+                            // No-op.
+                        }
+                    }
+
+                    c = c.getSuperclass();
+                }
+
+                if (Externalizable.class.isAssignableFrom(cls)) {
+                    type = TYPE_EXTERNALIZABLE;
+
+                    try {
+                        constructor = cls.getDeclaredConstructor();
+
+                        constructor.setAccessible(true);
+                    }
+                    catch (NoSuchMethodException e) {
+                        throw new IOException("Externalizable class doesn't 
have default constructor: " + cls, e);
+                    }
+                }
+                else {
+                    type = TYPE_SERIALIZABLE;
+
+                    isSerial = Serializable.class.isAssignableFrom(cls);
+
+                    writeObjMtds = new ArrayList<>();
+                    readObjMtds = new ArrayList<>();
+                    List<List<Field>> fields = new ArrayList<>();
+                    List<List<T2<IgniteOptimizedFieldType, Long>>> fieldOffs = 
new ArrayList<>();
+                    List<Map<String, IgniteBiTuple<Integer, 
IgniteOptimizedFieldType>>> fieldInfoMaps = new ArrayList<>();
+                    List<List<IgniteBiTuple<Integer, 
IgniteOptimizedFieldType>>> fieldInfoLists = new ArrayList<>();
+
+                    for (c = cls; c != null && !c.equals(Object.class); c = 
c.getSuperclass()) {
+                        Method mtd;
+
+                        try {
+                            mtd = c.getDeclaredMethod("writeObject", 
ObjectOutputStream.class);
+
+                            int mod = mtd.getModifiers();
+
+                            if (!isStatic(mod) && isPrivate(mod) && 
mtd.getReturnType() == Void.TYPE)
+                                mtd.setAccessible(true);
+                            else
+                                // Set method back to null if it has incorrect 
signature.
+                                mtd = null;
+                        }
+                        catch (NoSuchMethodException ignored) {
+                            mtd = null;
+                        }
+
+                        writeObjMtds.add(mtd);
+
+                        try {
+                            mtd = c.getDeclaredMethod("readObject", 
ObjectInputStream.class);
+
+                            int mod = mtd.getModifiers();
+
+                            if (!isStatic(mod) && isPrivate(mod) && 
mtd.getReturnType() == Void.TYPE)
+                                mtd.setAccessible(true);
+                            else
+                                // Set method back to null if it has incorrect 
signature.
+                                mtd = null;
+                        }
+                        catch (NoSuchMethodException ignored) {
+                            mtd = null;
+                        }
+
+                        readObjMtds.add(mtd);
+
+                        Field[] clsFields0 = c.getDeclaredFields();
+
+                        Arrays.sort(clsFields0, new Comparator<Field>() {
+                            @Override public int compare(Field f1, Field f2) {
+                                return f1.getName().compareTo(f2.getName());
+                            }
+                        });
+
+                        List<Field> clsFields = new 
ArrayList<>(clsFields0.length);
+                        List<T2<IgniteOptimizedFieldType, Long>> clsFieldOffs =
+                            new ArrayList<>(clsFields0.length);
+
+                        for (int i = 0; i < clsFields0.length; i++) {
+                            Field f = clsFields0[i];
+
+                            int mod = f.getModifiers();
+
+                            if (!isStatic(mod) && !isTransient(mod)) {
+                                IgniteOptimizedFieldType type = 
fieldType(f.getType());
+
+                                clsFields.add(f);
+                                clsFieldOffs.add(new T2<>(type, 
UNSAFE.objectFieldOffset(f)));
+                            }
+                        }
+
+                        fields.add(clsFields);
+                        fieldOffs.add(clsFieldOffs);
+
+                        Map<String, IgniteBiTuple<Integer, 
IgniteOptimizedFieldType>> fieldInfoMap = null;
+
+                        try {
+                            Field serFieldsDesc = 
c.getDeclaredField("serialPersistentFields");
+
+                            int mod = serFieldsDesc.getModifiers();
+
+                            if (serFieldsDesc.getType() == 
ObjectStreamField[].class &&
+                                isPrivate(mod) && isStatic(mod) && 
isFinal(mod)) {
+                                serFieldsDesc.setAccessible(true);
+
+                                ObjectStreamField[] serFields = 
(ObjectStreamField[])serFieldsDesc.get(null);
+
+                                fieldInfoMap = new HashMap<>();
+
+                                for (int i = 0; i < serFields.length; i++) {
+                                    ObjectStreamField serField = serFields[i];
+
+                                    fieldInfoMap.put(serField.getName(), 
F.t(i, fieldType(serField.getType())));
+                                }
+                            }
+                        }
+                        catch (NoSuchFieldException ignored) {
+                            // No-op.
+                        }
+                        catch (IllegalAccessException e) {
+                            throw new IOException("Failed to get value of 
'serialPersistentFields' field in class: " +
+                                cls.getName(), e);
+                        }
+
+                        if (fieldInfoMap == null) {
+                            fieldInfoMap = new HashMap<>();
+
+                            for (int i = 0; i < clsFields.size(); i++) {
+                                Field f = clsFields.get(i);
+
+                                fieldInfoMap.put(f.getName(), F.t(i, 
fieldType(f.getType())));
+                            }
+                        }
+
+                        fieldInfoMaps.add(fieldInfoMap);
+
+                        List<IgniteBiTuple<Integer, IgniteOptimizedFieldType>> 
fieldInfoList =
+                            new ArrayList<>(fieldInfoMap.values());
+
+                        Collections.sort(fieldInfoList, new 
Comparator<IgniteBiTuple<Integer, IgniteOptimizedFieldType>>() {
+                            @Override public int 
compare(IgniteBiTuple<Integer, IgniteOptimizedFieldType> t1,
+                                IgniteBiTuple<Integer, 
IgniteOptimizedFieldType> t2) {
+                                return t1.get1().compareTo(t2.get1());
+                            }
+                        });
+
+                        fieldInfoLists.add(fieldInfoList);
+                    }
+
+                    Collections.reverse(writeObjMtds);
+                    Collections.reverse(readObjMtds);
+                    Collections.reverse(fields);
+                    Collections.reverse(fieldOffs);
+                    Collections.reverse(fieldInfoMaps);
+                    Collections.reverse(fieldInfoLists);
+
+                    this.fields = new Fields(fields, fieldOffs, 
fieldInfoLists, fieldInfoMaps);
+                }
+            }
+        }
+
+        shortId = GridOptimizedMarshallerUtils.computeSerialVersionUid(cls, 
fields != null ? fields.ownFields() : null).shortValue();
+    }
+
+    /**
+     * @return Excluded flag.
+     */
+    boolean excluded() {
+        return excluded;
+    }
+
+    /**
+     * @return Class.
+     */
+    Class<?> describedClass() {
+        return cls;
+    }
+
+    /**
+     * @return Header.
+     */
+    Integer header() {
+        return hdr;
+    }
+
+    /**
+     * @return ID.
+     */
+    Integer id() {
+        return id;
+    }
+
+    /**
+     * @return Short ID.
+     */
+    Short shortId() {
+        return shortId;
+    }
+
+    /**
+     * @return Class name.
+     */
+    String name() {
+        return name;
+    }
+
+    /**
+     * @return Array component type.
+     */
+    Class<?> componentType() {
+        return arrCompType;
+    }
+
+    /**
+     * @return Primitive flag.
+     */
+    boolean isPrimitive() {
+        return isPrimitive;
+    }
+
+    /**
+     * @return Enum flag.
+     */
+    boolean isEnum() {
+        return isEnum;
+    }
+
+    /**
+     * @return {@code True} if descriptor is for {@link Class}.
+     */
+    boolean isClass() {
+        return isCls;
+    }
+
+    /**
+     * Replaces object.
+     *
+     * @param obj Object.
+     * @return Replaced object or {@code null} if there is no {@code 
writeReplace} method.
+     * @throws IOException In case of error.
+     */
+    Object replace(Object obj) throws IOException {
+        if (writeReplaceMtd != null) {
+            try {
+                return writeReplaceMtd.invoke(obj);
+            }
+            catch (IllegalAccessException | InvocationTargetException e) {
+                throw new IOException(e);
+            }
+        }
+
+        return obj;
+    }
+
+    /**
+     * Writes object to stream.
+     *
+     * @param out Output stream.
+     * @param obj Object.
+     * @throws IOException In case of error.
+     */
+    @SuppressWarnings("ForLoopReplaceableByForEach")
+    void write(GridOptimizedObjectOutputStream out, Object obj) throws 
IOException {
+        switch (type) {
+            case TYPE_BYTE:
+                out.writeByte((Byte)obj);
+
+                break;
+
+            case TYPE_SHORT:
+                out.writeShort((Short)obj);
+
+                break;
+
+            case TYPE_INT:
+                out.writeInt((Integer)obj);
+
+                break;
+
+            case TYPE_LONG:
+                out.writeLong((Long)obj);
+
+                break;
+
+            case TYPE_FLOAT:
+                out.writeFloat((Float)obj);
+
+                break;
+
+            case TYPE_DOUBLE:
+                out.writeDouble((Double)obj);
+
+                break;
+
+            case TYPE_CHAR:
+                out.writeChar((Character)obj);
+
+                break;
+
+            case TYPE_BOOLEAN:
+                out.writeBoolean((Boolean)obj);
+
+                break;
+
+            case TYPE_BYTE_ARR:
+                out.writeByteArray((byte[])obj);
+
+                break;
+
+            case TYPE_SHORT_ARR:
+                out.writeShortArray((short[])obj);
+
+                break;
+
+            case TYPE_INT_ARR:
+                out.writeIntArray((int[])obj);
+
+                break;
+
+            case TYPE_LONG_ARR:
+                out.writeLongArray((long[])obj);
+
+                break;
+
+            case TYPE_FLOAT_ARR:
+                out.writeFloatArray((float[])obj);
+
+                break;
+
+            case TYPE_DOUBLE_ARR:
+                out.writeDoubleArray((double[])obj);
+
+                break;
+
+            case TYPE_CHAR_ARR:
+                out.writeCharArray((char[])obj);
+
+                break;
+
+            case TYPE_BOOLEAN_ARR:
+                out.writeBooleanArray((boolean[])obj);
+
+                break;
+
+            case TYPE_OBJ_ARR:
+                out.writeArray((Object[])obj);
+
+                break;
+
+            case TYPE_STR:
+                out.writeString((String)obj);
+
+                break;
+
+            case TYPE_ENUM:
+                out.writeInt(((Enum)obj).ordinal());
+
+                break;
+
+            case TYPE_UUID:
+                out.writeUuid((UUID)obj);
+
+                break;
+
+            case TYPE_PROPS:
+                out.writeProperties((Properties)obj, dfltsFieldOff);
+
+                break;
+
+            case TYPE_ARRAY_LIST:
+                out.writeArrayList((ArrayList<?>)obj);
+
+                break;
+
+            case TYPE_HASH_MAP:
+                out.writeHashMap((HashMap<?, ?>)obj, loadFactorFieldOff, 
false);
+
+                break;
+
+            case TYPE_HASH_SET:
+                out.writeHashSet((HashSet<?>)obj, mapFieldOff, 
loadFactorFieldOff);
+
+                break;
+
+            case TYPE_LINKED_LIST:
+                out.writeLinkedList((LinkedList<?>)obj);
+
+                break;
+
+            case TYPE_LINKED_HASH_MAP:
+                out.writeLinkedHashMap((LinkedHashMap<?, ?>)obj, 
loadFactorFieldOff, accessOrderFieldOff, false);
+
+                break;
+
+            case TYPE_LINKED_HASH_SET:
+                out.writeLinkedHashSet((LinkedHashSet<?>)obj, mapFieldOff, 
loadFactorFieldOff);
+
+                break;
+
+            case TYPE_DATE:
+                out.writeDate((Date)obj);
+
+                break;
+
+            case TYPE_CLS:
+                IgniteOptimizedClassResolver.writeClass(out, 
GridOptimizedMarshallerUtils.classDescriptor((Class<?>) obj, obj));
+
+                break;
+
+            case TYPE_EXTERNALIZABLE:
+                out.writeExternalizable(obj);
+
+                break;
+
+            case TYPE_SERIALIZABLE:
+                if (out.requireSerializable() && !isSerial)
+                    throw new NotSerializableException("Must implement 
java.io.Serializable or " +
+                        "set GridOptimizedMarshaller.setRequireSerializable() 
to false " +
+                        "(note that performance may degrade if object is not 
Serializable): " + name);
+
+                out.writeSerializable(obj, writeObjMtds, fields);
+
+                break;
+
+            default:
+                throw new IllegalStateException("Invalid class type: " + type);
+        }
+    }
+
+    /**
+     * Reads object from stream.
+     *
+     * @param in Input stream.
+     * @return Object.
+     * @throws ClassNotFoundException If class not found.
+     * @throws IOException In case of error.
+     */
+    Object read(GridOptimizedObjectInputStream in) throws 
ClassNotFoundException, IOException {
+        switch (type) {
+            case TYPE_BYTE:
+                return in.readByte();
+
+            case TYPE_SHORT:
+                return in.readShort();
+
+            case TYPE_INT:
+                return in.readInt();
+
+            case TYPE_LONG:
+                return in.readLong();
+
+            case TYPE_FLOAT:
+                return in.readFloat();
+
+            case TYPE_DOUBLE:
+                return in.readDouble();
+
+            case TYPE_CHAR:
+                return in.readChar();
+
+            case TYPE_BOOLEAN:
+                return in.readBoolean();
+
+            case TYPE_BYTE_ARR:
+                return in.readByteArray();
+
+            case TYPE_SHORT_ARR:
+                return in.readShortArray();
+
+            case TYPE_INT_ARR:
+                return in.readIntArray();
+
+            case TYPE_LONG_ARR:
+                return in.readLongArray();
+
+            case TYPE_FLOAT_ARR:
+                return in.readFloatArray();
+
+            case TYPE_DOUBLE_ARR:
+                return in.readDoubleArray();
+
+            case TYPE_CHAR_ARR:
+                return in.readCharArray();
+
+            case TYPE_BOOLEAN_ARR:
+                return in.readBooleanArray();
+
+            case TYPE_OBJ_ARR:
+                return in.readArray(arrCompType);
+
+            case TYPE_STR:
+                return in.readString();
+
+            case TYPE_ENUM:
+                return enumVals[in.readInt()];
+
+            case TYPE_UUID:
+                return in.readUuid();
+
+            case TYPE_PROPS:
+                return in.readProperties();
+
+            case TYPE_ARRAY_LIST:
+                return in.readArrayList();
+
+            case TYPE_HASH_MAP:
+                return in.readHashMap(false);
+
+            case TYPE_HASH_SET:
+                return in.readHashSet(mapFieldOff);
+
+            case TYPE_LINKED_LIST:
+                return in.readLinkedList();
+
+            case TYPE_LINKED_HASH_MAP:
+                return in.readLinkedHashMap(false);
+
+            case TYPE_LINKED_HASH_SET:
+                return in.readLinkedHashSet(mapFieldOff);
+
+            case TYPE_DATE:
+                return in.readDate();
+
+            case TYPE_CLS:
+                return IgniteOptimizedClassResolver.readClass(in, 
in.classLoader()).describedClass();
+
+            case TYPE_EXTERNALIZABLE:
+                return in.readExternalizable(constructor, readResolveMtd);
+
+            case TYPE_SERIALIZABLE:
+                return in.readSerializable(cls, readObjMtds, readResolveMtd, 
fields);
+
+            default:
+                throw new IllegalStateException("Invalid class type: " + type);
+        }
+    }
+
+    /**
+     * @param cls Class.
+     * @return Type.
+     */
+    @SuppressWarnings("IfMayBeConditional")
+    private IgniteOptimizedFieldType fieldType(Class<?> cls) {
+        IgniteOptimizedFieldType type;
+
+        if (cls == byte.class)
+            type = IgniteOptimizedFieldType.BYTE;
+        else if (cls == short.class)
+            type = IgniteOptimizedFieldType.SHORT;
+        else if (cls == int.class)
+            type = IgniteOptimizedFieldType.INT;
+        else if (cls == long.class)
+            type = IgniteOptimizedFieldType.LONG;
+        else if (cls == float.class)
+            type = IgniteOptimizedFieldType.FLOAT;
+        else if (cls == double.class)
+            type = IgniteOptimizedFieldType.DOUBLE;
+        else if (cls == char.class)
+            type = IgniteOptimizedFieldType.CHAR;
+        else if (cls == boolean.class)
+            type = IgniteOptimizedFieldType.BOOLEAN;
+        else
+            type = IgniteOptimizedFieldType.OTHER;
+
+        return type;
+    }
+
+    /**
+     * Encapsulates data about class fields.
+     */
+    @SuppressWarnings("PackageVisibleInnerClass")
+    static class Fields {
+        /** Fields. */
+        private final List<List<Field>> fields;
+
+        /** Fields offsets. */
+        private final List<List<T2<IgniteOptimizedFieldType, Long>>> fieldOffs;
+
+        /** Fields details lists. */
+        private final List<List<IgniteBiTuple<Integer, 
IgniteOptimizedFieldType>>> fieldInfoLists;
+
+        /** Fields details maps. */
+        private final List<Map<String, IgniteBiTuple<Integer, 
IgniteOptimizedFieldType>>> fieldInfoMaps;
+
+        /**
+         * Creates new instance.
+         *
+         * @param fields Fields.
+         * @param fieldOffs Field offsets.
+         * @param fieldInfoLists List of field details sequences for each type 
in the object's class hierarchy.
+         * @param fieldInfoMaps List of field details maps for each type in 
the object's class hierarchy.
+         */
+        Fields(List<List<Field>> fields, 
List<List<T2<IgniteOptimizedFieldType, Long>>> fieldOffs,
+            List<List<IgniteBiTuple<Integer, IgniteOptimizedFieldType>>> 
fieldInfoLists,
+            List<Map<String, IgniteBiTuple<Integer, 
IgniteOptimizedFieldType>>> fieldInfoMaps) {
+            this.fields = fields;
+            this.fieldOffs = fieldOffs;
+            this.fieldInfoLists = fieldInfoLists;
+            this.fieldInfoMaps = fieldInfoMaps;
+        }
+
+        /**
+         * Returns class's own fields (excluding inherited).
+         *
+         * @return List of fields or {@code null} if fields list is empty.
+         */
+        List<Field> ownFields() {
+            return fields.isEmpty() ? null : fields.get(fields.size() - 1);
+        }
+
+        /**
+         * Returns field types and their offsets.
+         *
+         * @param i hierarchy level where 0 corresponds to top level.
+         * @return list of pairs where first value is field type and second 
value is its offset.
+         */
+        List<T2<IgniteOptimizedFieldType, Long>> fieldOffs(int i) {
+            return fieldOffs.get(i);
+        }
+
+        /**
+         * Returns field sequence numbers and their types as list.
+         *
+         * @param i hierarchy level where 0 corresponds to top level.
+         * @return list of pairs (field number, field type) for the given 
hierarchy level.
+         */
+        List<IgniteBiTuple<Integer, IgniteOptimizedFieldType>> 
fieldInfoList(int i) {
+            return fieldInfoLists.get(i);
+        }
+
+        /**
+         * Returns field sequence numbers and their types as map where key is 
a field name,
+         *
+         * @param i hierarchy level where 0 corresponds to top level.
+         * @return map of field names and their details.
+         */
+        Map<String, IgniteBiTuple<Integer, IgniteOptimizedFieldType>> 
fieldInfoMap(int i) {
+            return fieldInfoMaps.get(i);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/f586cfc2/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/IgniteOptimizedClassResolver.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/IgniteOptimizedClassResolver.java
 
b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/IgniteOptimizedClassResolver.java
new file mode 100644
index 0000000..eb01ff4
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/IgniteOptimizedClassResolver.java
@@ -0,0 +1,469 @@
+/* @java.file.header */
+
+/*  _________        _____ __________________        _____
+ *  __  ____/___________(_)______  /__  ____/______ ____(_)_______
+ *  _  / __  __  ___/__  / _  __  / _  / __  _  __ `/__  / __  __ \
+ *  / /_/ /  _  /    _  /  / /_/ /  / /_/ /  / /_/ / _  /  _  / / /
+ *  \____/   /_/     /_/   \_,__/   \____/   \__,_/  /_/   /_/ /_/
+ */
+
+package org.apache.ignite.marshaller.optimized;
+
+import org.apache.ignite.lang.*;
+import org.gridgain.grid.util.*;
+import org.gridgain.grid.util.typedef.*;
+import org.gridgain.grid.util.typedef.internal.*;
+import org.jdk8.backport.*;
+import org.jetbrains.annotations.*;
+
+import java.io.*;
+import java.math.*;
+import java.sql.*;
+import java.util.*;
+import java.util.Date;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.*;
+import java.util.concurrent.locks.*;
+
+/**
+ * Resolves class names by serialVersionUID.
+ */
+@SuppressWarnings({"UnnecessaryFullyQualifiedName", "unchecked"})
+class IgniteOptimizedClassResolver {
+    /** File name to generate. */
+    private static final String FILE_NAME = "optimized-classnames.properties";
+
+    /** */
+    private static final Map<String, Integer> ggxName2id = new HashMap<>();
+
+    /** */
+    private static final T2<Class<?>, IgniteOptimizedClassDescriptor>[] 
ggxId2name;
+
+    /** */
+    private static final Map<String, Integer> ggName2id = new HashMap<>();
+
+    /** */
+    private static final T3<String, Class<?>, 
IgniteOptimizedClassDescriptor>[] ggId2name;
+
+    /** */
+    private static Map<String, Integer> usrName2Id;
+
+    /** */
+    private static T3<String, Class<?>, IgniteOptimizedClassDescriptor>[] 
usrId2Name;
+
+    /** */
+    private static final int HEADER_NAME = 255;
+
+    /** */
+    private static final int HEADER_GG_NAME = 254;
+
+    /** */
+    private static final int HEADER_USER_NAME = 253;
+
+    /** */
+    private static final int HEADER_ARRAY = 252;
+
+    /**
+     * Initialize predefined classes to optimize.
+     */
+    static {
+        Class[] superOptCls = new Class[] {
+            // Array types.
+            byte[].class,
+            short[].class,
+            int[].class,
+            long[].class,
+            float[].class,
+            double[].class,
+            boolean[].class,
+            char[].class,
+
+            // Boxed types.
+            Byte.class,
+            Short.class,
+            Integer.class,
+            Long.class,
+            Float.class,
+            Double.class,
+            Boolean.class,
+            Character.class,
+            String.class,
+
+            // Atomic.
+            AtomicBoolean.class,AtomicInteger.class,
+            AtomicLong.class,AtomicReference.class,
+            AtomicMarkableReference.class,
+            AtomicStampedReference.class,
+            AtomicIntegerArray.class,
+            AtomicReferenceArray.class,
+
+            // Concurrent types.
+            ConcurrentHashMap.class,
+            ConcurrentLinkedQueue.class,
+            ConcurrentSkipListMap.class,
+            ConcurrentSkipListSet.class,
+            LinkedBlockingDeque.class,
+            LinkedBlockingQueue.class,
+            PriorityBlockingQueue.class,
+            CopyOnWriteArrayList.class,
+            CopyOnWriteArraySet.class,
+
+            // Locks.
+            ReentrantLock.class,
+            ReentrantReadWriteLock.class,
+            ReentrantReadWriteLock.ReadLock.class,
+            ReentrantReadWriteLock.WriteLock.class,
+
+            // Util types.
+            Date.class,
+            UUID.class,
+            Calendar.class,
+            Random.class,
+            Calendar.class,
+            Currency.class,
+            ArrayList.class,
+            LinkedList.class,
+            Stack.class,
+            Vector.class,
+            HashMap.class,
+            HashSet.class,
+            Hashtable.class,
+            TreeMap.class,
+            TreeSet.class,
+            IdentityHashMap.class,
+            LinkedHashMap.class,
+            LinkedHashSet.class,
+            ArrayDeque.class,
+            BitSet.class,
+            EnumMap.class,
+            EnumSet.class,
+
+            // SQL types.
+            java.sql.Date.class,
+            Time.class,
+            Timestamp.class,
+
+            // Math types.
+            BigDecimal.class,
+            BigInteger.class,
+
+            // GridGain types.
+            IgniteUuid.class,
+            GridBoundedConcurrentOrderedSet.class,
+            GridBoundedLinkedHashSet.class,
+            GridConcurrentHashSet.class,
+            ConcurrentLinkedDeque8.class,
+            GridConcurrentPhantomHashSet.class,
+            GridConcurrentSkipListSet.class,
+            GridConcurrentWeakHashSet.class,
+            GridIdentityHashSet.class,
+            GridLeanSet.class,
+            GridSetWrapper.class
+        };
+
+        // Have to leave a range for special purposes.
+        assert superOptCls.length < 230;
+
+        ggxId2name = new T2[superOptCls.length];
+
+        for (int i = 0; i < superOptCls.length; i++) {
+            Class cls = superOptCls[i];
+
+            ggxName2id.put(cls.getName(), i);
+            ggxId2name[i] = new T2<Class<?>, 
IgniteOptimizedClassDescriptor>(cls, null);
+        }
+
+        BufferedReader reader = new BufferedReader(new InputStreamReader(
+            IgniteOptimizedClassResolver.class.getResourceAsStream(FILE_NAME),
+            GridOptimizedMarshallerUtils.UTF_8));
+
+        List<T3<String, Class<?>, IgniteOptimizedClassDescriptor>> ggId2name0 =
+            new LinkedList<>();
+
+        try {
+            for (int i = 0; ; i++) {
+                String clsName = reader.readLine();
+
+                if (clsName == null)
+                    break;
+
+                ggName2id.put(clsName, i);
+                ggId2name0.add(new T3<String, Class<?>, 
IgniteOptimizedClassDescriptor>(clsName, null, null));
+            }
+
+            ggId2name = ggId2name0.toArray(new T3[ggId2name0.size()]);
+        }
+        catch (IOException e) {
+            throw new AssertionError(e);
+        }
+        finally {
+            U.close(reader, null);
+        }
+    }
+
+    /**
+     * Ensure singleton.
+     */
+    private IgniteOptimizedClassResolver() {
+        // No-op.
+    }
+
+    /**
+     * @param usrName2id0 From name to ID.
+     * @param usrId2Name0 From ID to name.
+     */
+    static void userClasses(@Nullable Map<String, Integer> usrName2id0,
+        @Nullable T3<String, Class<?>, IgniteOptimizedClassDescriptor>[] 
usrId2Name0) {
+        usrName2Id = usrName2id0;
+        usrId2Name = usrId2Name0;
+    }
+
+    /**
+     * @param in DataInput to read from.
+     * @param clsLdr ClassLoader.
+     * @return Class descriptor.
+     * @throws IOException If serial version UID failed.
+     * @throws ClassNotFoundException If the class cannot be located by the 
specified class loader.
+     */
+    static IgniteOptimizedClassDescriptor readClass(DataInput in, ClassLoader 
clsLdr)
+        throws IOException, ClassNotFoundException {
+        assert in != null;
+        assert clsLdr != null;
+
+        int hdr = in.readByte() & 0xff;
+
+        if (hdr < ggxId2name.length) {
+            T2<Class<?>, IgniteOptimizedClassDescriptor> ggxT = 
ggxId2name[hdr];
+
+            IgniteOptimizedClassDescriptor desc = ggxT.get2();
+
+            if (desc == null) {
+                desc = 
GridOptimizedMarshallerUtils.classDescriptor(ggxT.get1(), null);
+
+                ggxT.set2(desc);
+            }
+
+            return desc;
+        }
+
+        String name;
+        Class<?> cls;
+        IgniteOptimizedClassDescriptor desc;
+
+        switch (hdr) {
+            case HEADER_GG_NAME:
+                int ggId = in.readInt();
+
+                T3<String, Class<?>, IgniteOptimizedClassDescriptor> ggT;
+
+                try {
+                    ggT = ggId2name[ggId];
+                }
+                catch (ArrayIndexOutOfBoundsException e) {
+                    throw new ClassNotFoundException("Failed to find optimized 
class ID " +
+                        "(is same GridGain version running on all nodes?): " + 
ggId, e);
+                }
+
+                name = ggT.get1();
+                cls = ggT.get2();
+                desc = ggT.get3();
+
+                if (desc == null) {
+                    if (clsLdr == U.gridClassLoader()) {
+                        if (cls == null) {
+                            cls = forName(name, clsLdr);
+
+                            ggT.set2(cls);
+                        }
+
+                        desc = 
GridOptimizedMarshallerUtils.classDescriptor(cls, null);
+
+                        ggT.set3(desc);
+                    }
+                    else {
+                        cls = forName(name, clsLdr);
+
+                        desc = 
GridOptimizedMarshallerUtils.classDescriptor(cls, null);
+                    }
+                }
+
+                break;
+
+            case HEADER_USER_NAME:
+                int usrId = in.readInt();
+
+                T3<String, Class<?>, IgniteOptimizedClassDescriptor> usrT;
+
+                try {
+                    if (usrId2Name != null)
+                        usrT = usrId2Name[usrId];
+                    else
+                        throw new ClassNotFoundException("Failed to find user 
defined class ID " +
+                            "(make sure to register identical classes on all 
nodes for optimization): " + usrId);
+                }
+                catch (ArrayIndexOutOfBoundsException e) {
+                    throw new ClassNotFoundException("Failed to find user 
defined class ID " +
+                        "(make sure to register identical classes on all nodes 
for optimization): " + usrId, e);
+                }
+
+                name = usrT.get1();
+                cls = usrT.get2();
+                desc = usrT.get3();
+
+                if (desc == null) {
+                    if (cls == null) {
+                        cls = forName(name, clsLdr);
+
+                        usrT.set2(cls);
+                    }
+
+                    desc = GridOptimizedMarshallerUtils.classDescriptor(cls, 
null);
+
+                    usrT.set3(desc);
+                }
+
+                break;
+
+            case HEADER_ARRAY:
+                name = readClass(in, clsLdr).name();
+
+                name = name.charAt(0) == '[' ? "[" + name : "[L" + name + ';';
+
+                cls = forName(name, clsLdr);
+
+                return GridOptimizedMarshallerUtils.classDescriptor(cls, null);
+
+            case HEADER_NAME:
+                name = in.readUTF();
+
+                cls = forName(name, clsLdr);
+
+                desc = GridOptimizedMarshallerUtils.classDescriptor(cls, null);
+
+                break;
+
+            default:
+                throw new IOException("Unexpected optimized stream header: " + 
hdr);
+        }
+
+        short actual = desc.shortId();
+
+        short exp = in.readShort();
+
+        if (actual != exp)
+            throw new ClassNotFoundException("Optimized stream class checksum 
mismatch " +
+                "(is same version of marshalled class present on all nodes?) " 
+
+                "[expected=" + exp + ", actual=" + actual + ", cls=" + cls + 
']');
+
+        return desc;
+    }
+
+    /**
+     * @param out Output.
+     * @param desc Class descriptor.
+     * @throws IOException In case of error.
+     */
+    static void writeClass(DataOutput out, IgniteOptimizedClassDescriptor 
desc) throws IOException {
+        assert out != null;
+        assert desc != null;
+
+        int hdr = desc.header();
+
+        out.writeByte(hdr);
+
+        switch (hdr) {
+            case HEADER_GG_NAME:
+            case HEADER_USER_NAME:
+                out.writeInt(desc.id());
+                out.writeShort(desc.shortId());
+
+                return;
+
+            case HEADER_ARRAY:
+                writeClass(out, 
GridOptimizedMarshallerUtils.classDescriptor(desc.componentType(), null));
+
+                return;
+
+            case HEADER_NAME:
+                out.writeUTF(desc.name());
+                out.writeShort(desc.shortId());
+        }
+    }
+
+    /**
+     * @param cls Class to write.
+     * @return Data for {@code writeClass} method.
+     */
+    static T2<Integer, Integer> writeClassData(Class<?> cls) {
+        assert cls != null;
+
+        String name = cls.getName();
+
+        Integer superHdr = ggxName2id.get(name);
+
+        if (superHdr != null)
+            return new T2<>(superHdr, null);
+
+        Integer id;
+
+        if ((id = ggName2id.get(name)) != null)
+            return new T2<>(HEADER_GG_NAME, id);
+
+        if (usrName2Id != null && (id = usrName2Id.get(name)) != null)
+            return new T2<>(HEADER_USER_NAME, id);
+
+        if (cls.isArray())
+            return new T2<>(HEADER_ARRAY, null);
+
+        return new T2<>(HEADER_NAME, null);
+    }
+
+    /**
+     * @param name Class name.
+     * @param ldr Class loader.
+     * @return Class.
+     * @throws ClassNotFoundException If class not found.
+     */
+    private static Class<?> forName(String name, ClassLoader ldr) throws 
ClassNotFoundException {
+        Class<?> cls = primitive(name);
+
+        if (cls == null)
+            cls = GridOptimizedMarshallerUtils.forName(name, ldr);
+
+        return cls;
+    }
+
+    /**
+     * @param name Name of primitive class.
+     * @return Primitive type class or null.
+     */
+    @SuppressWarnings("TypeMayBeWeakened")
+    @Nullable private static Class<?> primitive(String name) {
+        if (name.length() > 7)
+            return null;
+
+        switch (name.charAt(0)) {
+            case 'b':
+                if ("boolean".equals(name))
+                    return boolean.class;
+
+                return "byte".equals(name) ? byte.class : null;
+            case 's':
+                return "short".equals(name) ? short.class : null;
+            case 'i':
+                return "int".equals(name) ? int.class : null;
+            case 'l':
+                return "long".equals(name) ? long.class : null;
+            case 'c':
+                return "char".equals(name) ? char.class : null;
+            case 'f':
+                return "float".equals(name) ? float.class : null;
+            case 'd':
+                return "double".equals(name) ? double.class : null;
+            case 'v':
+                return "void".equals(name) ? void.class : null;
+        }
+
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/f586cfc2/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/IgniteOptimizedFieldType.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/IgniteOptimizedFieldType.java
 
b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/IgniteOptimizedFieldType.java
new file mode 100644
index 0000000..9cf14ca
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/IgniteOptimizedFieldType.java
@@ -0,0 +1,42 @@
+/* @java.file.header */
+
+/*  _________        _____ __________________        _____
+ *  __  ____/___________(_)______  /__  ____/______ ____(_)_______
+ *  _  / __  __  ___/__  / _  __  / _  / __  _  __ `/__  / __  __ \
+ *  / /_/ /  _  /    _  /  / /_/ /  / /_/ /  / /_/ / _  /  _  / / /
+ *  \____/   /_/     /_/   \_,__/   \____/   \__,_/  /_/   /_/ /_/
+ */
+
+package org.apache.ignite.marshaller.optimized;
+
+/**
+ * Field type used to calculate {@code Unsafe} offsets into objects.
+ */
+enum IgniteOptimizedFieldType {
+    /** */
+    BYTE,
+
+    /** */
+    SHORT,
+
+    /** */
+    INT,
+
+    /** */
+    LONG,
+
+    /** */
+    FLOAT,
+
+    /** */
+    DOUBLE,
+
+    /** */
+    CHAR,
+
+    /** */
+    BOOLEAN,
+
+    /** */
+    OTHER
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/f586cfc2/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/IgniteOptimizedMarshallable.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/IgniteOptimizedMarshallable.java
 
b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/IgniteOptimizedMarshallable.java
new file mode 100644
index 0000000..9fbac3c
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/IgniteOptimizedMarshallable.java
@@ -0,0 +1,57 @@
+/* @java.file.header */
+
+/*  _________        _____ __________________        _____
+ *  __  ____/___________(_)______  /__  ____/______ ____(_)_______
+ *  _  / __  __  ___/__  / _  __  / _  / __  _  __ `/__  / __  __ \
+ *  / /_/ /  _  /    _  /  / /_/ /  / /_/ /  / /_/ / _  /  _  / / /
+ *  \____/   /_/     /_/   \_,__/   \____/   \__,_/  /_/   /_/ /_/
+ */
+
+package org.apache.ignite.marshaller.optimized;
+
+import java.util.*;
+
+/**
+ * Optional interface which helps make serialization even faster by removing 
internal
+ * look-ups for classes.
+ * <p>
+ * All implementation must have the following:
+ * <ul>
+ * <li>
+ *     Must have static filed (private or public) declared of type {@link 
Object}
+ *     with name {@code GG_CLASS_ID}. GridGain will reflectively initialize 
this field with
+ *     proper class ID during system startup.
+ * </li>
+ * <li>
+ *     Must return the value of {@code GG_CLASS_ID} field from {@link 
#ggClassId} method.
+ * </li>
+ * </ul>
+ * Here is a sample implementation:
+ * <pre name="code" class="java">
+ * // For better performance consider implementing java.io.Externalizable 
interface.
+ * class ExampleMarshallable implements GridOptimizedMarshallable, 
Serializable {
+ *     // Class ID field required by 'GridOptimizedMarshallable'.
+ *     private static Object GG_CLASS_ID;
+ *
+ *     ...
+ *
+ *     &#64; public Object ggClassId() {
+ *         return GG_CLASS_ID;
+ *     }
+ * }
+ * </pre>
+ * <p>
+ * Note that for better performance you should also specify list of classes you
+ * plan to serialize via {@link IgniteOptimizedMarshaller#setClassNames(List)} 
method.
+ */
+public interface IgniteOptimizedMarshallable {
+    /** */
+    public static final String CLS_ID_FIELD_NAME = "GG_CLASS_ID";
+
+    /**
+     * Implementation of this method should simply return value of {@code 
GG_CLASS_ID} field.
+     *
+     * @return Class ID for optimized marshalling.
+     */
+    public Object ggClassId();
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/f586cfc2/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/IgniteOptimizedMarshaller.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/IgniteOptimizedMarshaller.java
 
b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/IgniteOptimizedMarshaller.java
new file mode 100644
index 0000000..80d30cc
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/IgniteOptimizedMarshaller.java
@@ -0,0 +1,408 @@
+/* @java.file.header */
+
+/*  _________        _____ __________________        _____
+ *  __  ____/___________(_)______  /__  ____/______ ____(_)_______
+ *  _  / __  __  ___/__  / _  __  / _  / __  _  __ `/__  / __  __ \
+ *  / /_/ /  _  /    _  /  / /_/ /  / /_/ /  / /_/ / _  /  _  / / /
+ *  \____/   /_/     /_/   \_,__/   \____/   \__,_/  /_/   /_/ /_/
+ */
+
+package org.apache.ignite.marshaller.optimized;
+
+import org.apache.ignite.marshaller.*;
+import org.gridgain.grid.*;
+import org.gridgain.grid.util.*;
+import org.gridgain.grid.util.typedef.*;
+import org.gridgain.grid.util.typedef.internal.*;
+import org.jetbrains.annotations.*;
+import sun.misc.*;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+
+/**
+ * Optimized implementation of {@link GridMarshaller}. Unlike {@link 
org.apache.ignite.marshaller.jdk.IgniteJdkMarshaller},
+ * which is based on standard {@link ObjectOutputStream}, this marshaller does 
not
+ * enforce that all serialized objects implement {@link Serializable} 
interface. It is also
+ * about 20 times faster as it removes lots of serialization overhead that 
exists in
+ * default JDK implementation.
+ * <p>
+ * {@code GridOptimizedMarshaller} is tested only on Java HotSpot VM on other 
VMs
+ * it could yield unexpected results. It is the default marshaller on Java 
HotSpot VMs
+ * and will be used if no other marshaller was explicitly configured.
+ * <p>
+ * <h1 class="header">Configuration</h1>
+ * <h2 class="header">Mandatory</h2>
+ * This marshaller has no mandatory configuration parameters.
+ * <h2 class="header">Java Example</h2>
+ * <pre name="code" class="java">
+ * GridOptimizedMarshaller marshaller = new GridOptimizedMarshaller();
+ *
+ * // Enforce Serializable interface.
+ * marshaller.setRequireSerializable(true);
+ *
+ * GridConfiguration cfg = new GridConfiguration();
+ *
+ * // Override marshaller.
+ * cfg.setMarshaller(marshaller);
+ *
+ * // Starts grid.
+ * G.start(cfg);
+ * </pre>
+ * <h2 class="header">Spring Example</h2>
+ * GridOptimizedMarshaller can be configured from Spring XML configuration 
file:
+ * <pre name="code" class="xml">
+ * &lt;bean id="grid.custom.cfg" class="org.gridgain.grid.GridConfiguration" 
singleton="true"&gt;
+ *     ...
+ *     &lt;property name="marshaller"&gt;
+ *         &lt;bean 
class="org.gridgain.grid.marshaller.optimized.GridOptimizedMarshaller"&gt;
+ *             &lt;property name="requireSerializable"&gt;true&lt;/property&gt;
+ *         &lt;/bean&gt;
+ *     &lt;/property&gt;
+ *     ...
+ * &lt;/bean&gt;
+ * </pre>
+ * <p>
+ * <img src="http://www.gridgain.com/images/spring-small.png";>
+ * <br>
+ * For information about Spring framework visit <a 
href="http://www.springframework.org/";>www.springframework.org</a>
+ * <h2 class="header">Injection Example</h2>
+ * GridMarshaller can be injected in users task, job or SPI as following:
+ * <pre name="code" class="java">
+ * public class MyGridJob implements GridComputeJob {
+ *     ...
+ *     &#64;GridMarshallerResource
+ *     private GridMarshaller marshaller;
+ *     ...
+ * }
+ * </pre>
+ * or
+ * <pre name="code" class="java">
+ * public class MyGridJob implements GridComputeJob {
+ *     ...
+ *     private GridMarshaller marshaller;
+ *     ...
+ *     &#64;GridMarshallerResource
+ *     public void setMarshaller(GridMarshaller marshaller) {
+ *         this.marshaller = marshaller;
+ *     }
+ *     ...
+ * }
+ * </pre>
+ */
+public class IgniteOptimizedMarshaller extends GridAbstractMarshaller {
+    /** Whether or not to require an object to be serializable in order to be 
marshalled. */
+    private boolean requireSer = true;
+
+    /** Default class loader. */
+    private final ClassLoader dfltClsLdr = getClass().getClassLoader();
+
+    /**
+     * Initializes marshaller not to enforce {@link Serializable} interface.
+     *
+     * @throws GridRuntimeException If this marshaller is not supported on the 
current JVM.
+     */
+    public IgniteOptimizedMarshaller() {
+        if (!available())
+            throw new GridRuntimeException("Using GridOptimizedMarshaller on 
unsupported JVM version (some of " +
+                "JVM-private APIs required for the marshaller to work are 
missing).");
+    }
+
+    /**
+     * Initializes marshaller with given serialization flag. If {@code true},
+     * then objects will be required to implement {@link Serializable} in order
+     * to be serialize.
+     *
+     * @param requireSer Flag to enforce {@link Serializable} interface or 
not. If {@code true},
+     *      then objects will be required to implement {@link Serializable} in 
order to be
+     *      marshalled, if {@code false}, then such requirement will be 
relaxed.
+     * @throws GridRuntimeException If this marshaller is not supported on the 
current JVM.
+     */
+    public IgniteOptimizedMarshaller(boolean requireSer) {
+        this();
+
+        this.requireSer = requireSer;
+    }
+
+    /**
+     * Initializes marshaller with given serialization flag. If {@code true},
+     * then objects will be required to implement {@link Serializable} in order
+     * to be serialize.
+     *
+     * @param requireSer Flag to enforce {@link Serializable} interface or 
not. If {@code true},
+     *      then objects will be required to implement {@link Serializable} in 
order to be
+     *      marshalled, if {@code false}, then such requirement will be 
relaxed.
+     * @param clsNames User preregistered class names.
+     * @param clsNamesPath Path to a file with user preregistered class names.
+     * @param poolSize Object streams pool size.
+     * @throws GridException If an I/O error occurs while writing stream 
header.
+     * @throws GridRuntimeException If this marshaller is not supported on the 
current JVM.
+     */
+    public IgniteOptimizedMarshaller(boolean requireSer, @Nullable 
List<String> clsNames,
+                                     @Nullable String clsNamesPath, int 
poolSize) throws GridException {
+        this(requireSer);
+
+        setClassNames(clsNames);
+        setClassNamesPath(clsNamesPath);
+        setPoolSize(poolSize);
+    }
+
+    /**
+     * Adds provided class names for marshalling optimization.
+     * <p>
+     * <b>NOTE</b>: these collections of classes must be identical on all 
nodes and in the same order.
+     *
+     * @param clsNames User preregistered class names to add.
+     */
+    @SuppressWarnings("unchecked")
+    public void setClassNames(@Nullable List<String> clsNames) {
+        if (clsNames != null && !clsNames.isEmpty()) {
+            String[] clsNamesArr = clsNames.toArray(new 
String[clsNames.size()]);
+
+            Arrays.sort(clsNamesArr);
+
+            Map<String, Integer> name2id = U.newHashMap(clsNamesArr.length);
+            T3<String, Class<?>, IgniteOptimizedClassDescriptor>[] id2name = 
new T3[clsNamesArr.length];
+
+            int i = 0;
+
+            for (String name : clsNamesArr) {
+                name2id.put(name, i);
+                id2name[i++] = new T3<>(name, null, null);
+            }
+
+            IgniteOptimizedClassResolver.userClasses(name2id, id2name);
+        }
+    }
+
+    /**
+     * Specifies a name of the file which lists all class names to be 
optimized.
+     * The file path can either be absolute path, relative to {@code 
GRIDGAIN_HOME},
+     * or specify a resource file on the class path.
+     * <p>
+     * The format of the file is class name per line, like this:
+     * <pre>
+     * ...
+     * com.example.Class1
+     * com.example.Class2
+     * ...
+     * </pre>
+     * <p>
+     * <b>NOTE</b>: this class list must be identical on all nodes and in the 
same order.
+     *
+     * @param path Path to a file with user preregistered class names.
+     * @throws GridException If an error occurs while writing stream header.
+     */
+    public void setClassNamesPath(@Nullable String path) throws GridException {
+        if (path == null)
+            return;
+
+        URL url = GridUtils.resolveGridGainUrl(path, false);
+
+        if (url == null)
+            throw new GridException("Failed to find resource for name: " + 
path);
+
+        List<String> clsNames;
+
+        try {
+            clsNames = new LinkedList<>();
+
+            try (BufferedReader reader = new BufferedReader(new 
InputStreamReader(url.openStream(), GridOptimizedMarshallerUtils.UTF_8))) {
+                String clsName;
+
+                while ((clsName = reader.readLine()) != null)
+                    clsNames.add(clsName);
+            }
+        }
+        catch (IOException e) {
+            throw new GridException("Failed to read class names from path: " + 
path, e);
+        }
+
+        setClassNames(clsNames);
+    }
+
+    /**
+     * Specifies size of cached object streams used by marshaller. Object 
streams are cached for
+     * performance reason to avoid costly recreation for every serialization 
routine. If {@code 0} (default),
+     * pool is not used and each thread has its own cached object stream which 
it keeps reusing.
+     * <p>
+     * Since each stream has an internal buffer, creating a stream for each 
thread can lead to
+     * high memory consumption if many large messages are marshalled or 
unmarshalled concurrently.
+     * Consider using pool in this case. This will limit number of streams 
that can be created and,
+     * therefore, decrease memory consumption.
+     * <p>
+     * NOTE: Using streams pool can decrease performance since streams will be 
shared between
+     * different threads which will lead to more frequent context switching.
+     *
+     * @param poolSize Streams pool size. If {@code 0}, pool is not used.
+     */
+    public void setPoolSize(int poolSize) {
+        GridOptimizedObjectStreamRegistry.poolSize(poolSize);
+    }
+
+    /**
+     * @return Whether to enforce {@link Serializable} interface.
+     */
+    public boolean isRequireSerializable() {
+        return requireSer;
+    }
+
+    /**
+     * Sets flag to enforce {@link Serializable} interface or not.
+     *
+     * @param requireSer Flag to enforce {@link Serializable} interface or 
not. If {@code true},
+     *      then objects will be required to implement {@link Serializable} in 
order to be
+     *      marshalled, if {@code false}, then such requirement will be 
relaxed.
+     */
+    public void setRequireSerializable(boolean requireSer) {
+        this.requireSer = requireSer;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void marshal(@Nullable Object obj, OutputStream out) 
throws GridException {
+        assert out != null;
+
+        GridOptimizedObjectOutputStream objOut = null;
+
+        try {
+            objOut = GridOptimizedObjectStreamRegistry.out();
+
+            objOut.requireSerializable(requireSer);
+
+            objOut.out().outputStream(out);
+
+            objOut.writeObject(obj);
+        }
+        catch (IOException e) {
+            throw new GridException("Failed to serialize object: " + obj, e);
+        }
+        finally {
+            GridOptimizedObjectStreamRegistry.closeOut(objOut);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public byte[] marshal(@Nullable Object obj) throws GridException 
{
+        GridOptimizedObjectOutputStream objOut = null;
+
+        try {
+            objOut = GridOptimizedObjectStreamRegistry.out();
+
+            objOut.requireSerializable(requireSer);
+
+            objOut.writeObject(obj);
+
+            return objOut.out().array();
+        }
+        catch (IOException e) {
+            throw new GridException("Failed to serialize object: " + obj, e);
+        }
+        finally {
+            GridOptimizedObjectStreamRegistry.closeOut(objOut);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public <T> T unmarshal(InputStream in, @Nullable ClassLoader 
clsLdr) throws GridException {
+        assert in != null;
+
+        GridOptimizedObjectInputStream objIn = null;
+
+        try {
+            objIn = GridOptimizedObjectStreamRegistry.in();
+
+            objIn.classLoader(clsLdr != null ? clsLdr : dfltClsLdr);
+
+            objIn.in().inputStream(in);
+
+            return (T)objIn.readObject();
+        }
+        catch (IOException e) {
+            throw new GridException("Failed to deserialize object with given 
class loader: " + clsLdr, e);
+        }
+        catch (ClassNotFoundException e) {
+            throw new GridException("Failed to find class with given class 
loader for unmarshalling " +
+                "(make sure same versions of all classes are available on all 
nodes or enable peer-class-loading): " +
+                clsLdr, e);
+        }
+        finally {
+            GridOptimizedObjectStreamRegistry.closeIn(objIn);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public <T> T unmarshal(byte[] arr, @Nullable ClassLoader clsLdr) 
throws GridException {
+        assert arr != null;
+
+        GridOptimizedObjectInputStream objIn = null;
+
+        try {
+            objIn = GridOptimizedObjectStreamRegistry.in();
+
+            objIn.classLoader(clsLdr != null ? clsLdr : dfltClsLdr);
+
+            objIn.in().bytes(arr, arr.length);
+
+            return (T)objIn.readObject();
+        }
+        catch (IOException e) {
+            throw new GridException("Failed to deserialize object with given 
class loader: " + clsLdr, e);
+        }
+        catch (ClassNotFoundException e) {
+            throw new GridException("Failed to find class with given class 
loader for unmarshalling " +
+                "(make sure same version of all classes are available on all 
nodes or enable peer-class-loading): " +
+                clsLdr, e);
+        }
+        finally {
+            GridOptimizedObjectStreamRegistry.closeIn(objIn);
+        }
+    }
+
+    /**
+     * Checks whether {@code GridOptimizedMarshaller} is able to work on the 
current JVM.
+     * <p>
+     * As long as {@code GridOptimizedMarshaller} uses JVM-private API, which 
is not guaranteed
+     * to be available on all JVM, this method should be called to ensure 
marshaller could work properly.
+     * <p>
+     * Result of this method is automatically checked in constructor.
+     *
+     * @return {@code true} if {@code GridOptimizedMarshaller} can work on the 
current JVM or
+     *  {@code false} if it can't.
+     */
+    @SuppressWarnings({"TypeParameterExtendsFinalClass", "ErrorNotRethrown"})
+    public static boolean available() {
+        try {
+            Unsafe unsafe = GridUnsafe.unsafe();
+
+            Class<? extends Unsafe> unsafeCls = unsafe.getClass();
+
+            unsafeCls.getMethod("allocateInstance", Class.class);
+            unsafeCls.getMethod("copyMemory", Object.class, long.class, 
Object.class, long.class, long.class);
+
+            return true;
+        }
+        catch (Exception ignored) {
+            return false;
+        }
+        catch (NoClassDefFoundError ignored) {
+            return false;
+        }
+    }
+
+    /**
+     * Undeployment callback invoked when class loader is being undeployed.
+     *
+     * @param ldr Class loader being undeployed.
+     */
+    public static void onUndeploy(ClassLoader ldr) {
+        GridOptimizedMarshallerUtils.onUndeploy(ldr);
+    }
+
+    /**
+     * Clears internal caches and frees memory. Usually called on system stop.
+     */
+    public static void clearCache() {
+        GridOptimizedMarshallerUtils.clearCache();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/f586cfc2/modules/core/src/main/java/org/gridgain/client/marshaller/optimized/GridClientOptimizedMarshaller.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/gridgain/client/marshaller/optimized/GridClientOptimizedMarshaller.java
 
b/modules/core/src/main/java/org/gridgain/client/marshaller/optimized/GridClientOptimizedMarshaller.java
index f7d48a5..52f451b 100644
--- 
a/modules/core/src/main/java/org/gridgain/client/marshaller/optimized/GridClientOptimizedMarshaller.java
+++ 
b/modules/core/src/main/java/org/gridgain/client/marshaller/optimized/GridClientOptimizedMarshaller.java
@@ -19,7 +19,7 @@ import java.nio.*;
 import java.util.*;
 
 /**
- * Wrapper, that adapts {@link 
org.apache.ignite.marshaller.optimized.GridOptimizedMarshaller} to
+ * Wrapper, that adapts {@link 
org.apache.ignite.marshaller.optimized.IgniteOptimizedMarshaller} to
  * {@link GridClientMarshaller} interface.
  */
 public class GridClientOptimizedMarshaller implements GridClientMarshaller {
@@ -27,13 +27,13 @@ public class GridClientOptimizedMarshaller implements 
GridClientMarshaller {
     public static final byte ID = 1;
 
     /** Optimized marshaller. */
-    private final GridOptimizedMarshaller opMarsh;
+    private final IgniteOptimizedMarshaller opMarsh;
 
     /**
      * Default constructor.
      */
     public GridClientOptimizedMarshaller() {
-        opMarsh = new GridOptimizedMarshaller();
+        opMarsh = new IgniteOptimizedMarshaller();
     }
 
     /**
@@ -47,12 +47,12 @@ public class GridClientOptimizedMarshaller implements 
GridClientMarshaller {
      * @param poolSize Object streams pool size.
      * @throws IOException If an I/O error occurs while writing stream header.
      * @throws GridRuntimeException If this marshaller is not supported on the 
current JVM.
-     * @see GridOptimizedMarshaller
+     * @see org.apache.ignite.marshaller.optimized.IgniteOptimizedMarshaller
      */
     public GridClientOptimizedMarshaller(boolean requireSer, List<String> 
clsNames, String clsNamesPath, int poolSize)
         throws IOException {
         try {
-            opMarsh = new GridOptimizedMarshaller(requireSer, clsNames, 
clsNamesPath, poolSize);
+            opMarsh = new IgniteOptimizedMarshaller(requireSer, clsNames, 
clsNamesPath, poolSize);
         }
         catch (GridException e) {
             throw new IOException(e);

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/f586cfc2/modules/core/src/main/java/org/gridgain/grid/cache/affinity/rendezvous/GridCacheRendezvousAffinityFunction.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/gridgain/grid/cache/affinity/rendezvous/GridCacheRendezvousAffinityFunction.java
 
b/modules/core/src/main/java/org/gridgain/grid/cache/affinity/rendezvous/GridCacheRendezvousAffinityFunction.java
index 7ebc4dc..2d004ae 100644
--- 
a/modules/core/src/main/java/org/gridgain/grid/cache/affinity/rendezvous/GridCacheRendezvousAffinityFunction.java
+++ 
b/modules/core/src/main/java/org/gridgain/grid/cache/affinity/rendezvous/GridCacheRendezvousAffinityFunction.java
@@ -85,7 +85,7 @@ public class GridCacheRendezvousAffinityFunction implements 
GridCacheAffinityFun
     private GridCacheAffinityNodeHashResolver hashIdRslvr = new 
GridCacheAffinityNodeAddressHashResolver();
 
     /** Marshaller. */
-    private GridMarshaller marshaller = new GridOptimizedMarshaller(false);
+    private GridMarshaller marshaller = new IgniteOptimizedMarshaller(false);
 
     /**
      * Empty constructor with all defaults.

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/f586cfc2/modules/core/src/main/java/org/gridgain/grid/kernal/GridGainEx.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/gridgain/grid/kernal/GridGainEx.java 
b/modules/core/src/main/java/org/gridgain/grid/kernal/GridGainEx.java
index fcfc385..23cfdb7 100644
--- a/modules/core/src/main/java/org/gridgain/grid/kernal/GridGainEx.java
+++ b/modules/core/src/main/java/org/gridgain/grid/kernal/GridGainEx.java
@@ -1598,7 +1598,7 @@ public class GridGainEx {
 
                     marsh = new IgniteJdkMarshaller();
                 }
-                else if (!GridOptimizedMarshaller.available()) {
+                else if (!IgniteOptimizedMarshaller.available()) {
                     U.warn(log, "GridOptimizedMarshaller is not supported on 
this JVM " +
                         "(only recent 1.6 and 1.7 versions HotSpot VMs are 
supported). " +
                         "To enable fast marshalling upgrade to recent 1.6 or 
1.7 HotSpot VM release. " +
@@ -1609,9 +1609,9 @@ public class GridGainEx {
                     marsh = new IgniteJdkMarshaller();
                 }
                 else
-                    marsh = new GridOptimizedMarshaller();
+                    marsh = new IgniteOptimizedMarshaller();
             }
-            else if (marsh instanceof GridOptimizedMarshaller && 
!U.isHotSpot()) {
+            else if (marsh instanceof IgniteOptimizedMarshaller && 
!U.isHotSpot()) {
                 U.warn(log, "Using GridOptimizedMarshaller on untested JVM 
(only Java HotSpot VMs were tested) - " +
                     "object serialization behavior could yield unexpected 
results.",
                     "Using GridOptimizedMarshaller on untested JVM.");

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/f586cfc2/modules/core/src/main/java/org/gridgain/grid/kernal/GridKernal.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/gridgain/grid/kernal/GridKernal.java 
b/modules/core/src/main/java/org/gridgain/grid/kernal/GridKernal.java
index 8525afe..9353504 100644
--- a/modules/core/src/main/java/org/gridgain/grid/kernal/GridKernal.java
+++ b/modules/core/src/main/java/org/gridgain/grid/kernal/GridKernal.java
@@ -1180,9 +1180,9 @@ public class GridKernal extends ClusterGroupAdapter 
implements GridEx, IgniteMBe
         if (cfg.getIncludeEventTypes() != null && 
cfg.getIncludeEventTypes().length != 0)
             perf.add("Disable grid events (remove 'includeEventTypes' from 
configuration)");
 
-        if (GridOptimizedMarshaller.available() && !(cfg.getMarshaller() 
instanceof GridOptimizedMarshaller))
+        if (IgniteOptimizedMarshaller.available() && !(cfg.getMarshaller() 
instanceof IgniteOptimizedMarshaller))
             perf.add("Enable optimized marshaller (set 'marshaller' to " +
-                GridOptimizedMarshaller.class.getSimpleName() + ')');
+                IgniteOptimizedMarshaller.class.getSimpleName() + ')');
     }
 
     /**
@@ -1979,7 +1979,7 @@ public class GridKernal extends ClusterGroupAdapter 
implements GridEx, IgniteMBe
             notifyLifecycleBeansEx(LifecycleEventType.AFTER_GRID_STOP);
 
             // Clean internal class/classloader caches to avoid stopped 
contexts held in memory.
-            GridOptimizedMarshaller.clearCache();
+            IgniteOptimizedMarshaller.clearCache();
             GridMarshallerExclusions.clearCache();
             GridEnumCache.clear();
 

Reply via email to