You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by vo...@apache.org on 2017/04/14 11:22:49 UTC
[09/10] ignite git commit: IGNITE-4938: Moved OptimizedMarshaller to
private package. This closes #1793.
IGNITE-4938: Moved OptimizedMarshaller to private package. This closes #1793.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/a1b5b8c3
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/a1b5b8c3
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/a1b5b8c3
Branch: refs/heads/master
Commit: a1b5b8c39c847b308c3180bc5308b0a09adf75ec
Parents: b3b5395
Author: Alexander Paschenko <al...@gmail.com>
Authored: Fri Apr 14 14:21:57 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Fri Apr 14 14:21:58 2017 +0300
----------------------------------------------------------------------
examples/config/filesystem/example-igfs.xml | 7 -
.../MemcacheRestExampleNodeStartup.java | 7 -
.../optimized/OptimizedMarshallerAopTest.java | 105 +
.../optimized/OptimizedMarshallerAopTest.java | 104 -
modules/clients/src/test/config/jdbc-config.xml | 2 +-
.../apache/ignite/IgniteSystemProperties.java | 2 +-
.../apache/ignite/internal/IgniteKernal.java | 2 +-
.../internal/binary/BinaryClassDescriptor.java | 2 +-
.../ignite/internal/binary/BinaryContext.java | 2 +-
.../GridClientOptimizedMarshaller.java | 2 +-
.../GridClientZipOptimizedMarshaller.java | 2 +-
.../optimized/OptimizedClassDescriptor.java | 1141 +++++++++
.../optimized/OptimizedFieldType.java | 50 +
.../optimized/OptimizedMarshaller.java | 313 +++
.../optimized/OptimizedMarshallerIdMapper.java | 33 +
.../optimized/OptimizedMarshallerUtils.java | 551 +++++
.../optimized/OptimizedObjectInputStream.java | 1231 ++++++++++
.../optimized/OptimizedObjectOutputStream.java | 875 +++++++
.../OptimizedObjectStreamRegistry.java | 244 ++
.../apache/ignite/marshaller/Marshaller.java | 3 +-
.../ignite/marshaller/jdk/JdkMarshaller.java | 3 +-
.../optimized/OptimizedClassDescriptor.java | 1141 ---------
.../optimized/OptimizedFieldType.java | 50 -
.../optimized/OptimizedMarshaller.java | 313 ---
.../optimized/OptimizedMarshallerIdMapper.java | 33 -
.../optimized/OptimizedMarshallerUtils.java | 551 -----
.../optimized/OptimizedObjectInputStream.java | 1231 ----------
.../optimized/OptimizedObjectOutputStream.java | 875 -------
.../OptimizedObjectStreamRegistry.java | 244 --
.../marshaller/optimized/package-info.java | 22 -
.../resources/META-INF/classnames.properties | 2 +-
modules/core/src/test/config/example-cache.xml | 2 +-
modules/core/src/test/config/igfs-loopback.xml | 2 +-
modules/core/src/test/config/igfs-shmem.xml | 2 +-
.../src/test/config/spring-start-nodes-attr.xml | 2 +-
.../core/src/test/config/spring-start-nodes.xml | 2 +-
.../config/websession/example-cache-base.xml | 2 +-
.../IgniteExternalizableAbstractTest.java | 2 +-
...dbcPojoStoreOptimizedMarshallerSelfTest.java | 2 +-
.../apache/ignite/igfs/IgfsPathSelfTest.java | 2 +-
.../internal/GridLifecycleAwareSelfTest.java | 2 +-
.../managers/GridManagerStopSelfTest.java | 2 +-
.../GridDiscoveryManagerAttributesSelfTest.java | 2 +-
.../OptimizedMarshallerEnumSelfTest.java | 87 +
.../OptimizedMarshallerNodeFailoverTest.java | 358 +++
.../OptimizedMarshallerPooledSelfTest.java | 46 +
.../optimized/OptimizedMarshallerSelfTest.java | 284 +++
...arshallerSerialPersistentFieldsSelfTest.java | 116 +
.../optimized/OptimizedMarshallerTest.java | 790 +++++++
.../OptimizedObjectStreamSelfTest.java | 2162 ++++++++++++++++++
.../TestTcpDiscoveryIpFinderAdapter.java | 43 +
.../CacheStartupInDeploymentModesTest.java | 2 +-
.../cache/GridCacheEntryMemorySizeSelfTest.java | 2 +-
...ridCacheStoreManagerDeserializationTest.java | 2 +-
.../cache/GridCacheVersionSelfTest.java | 2 +-
.../distributed/CacheAffinityEarlyTest.java | 2 +-
.../CacheGetFutureHangsSelfTest.java | 2 +-
.../IgniteCacheCreatePutMultiNodeSelfTest.java | 2 +-
.../distributed/IgniteCacheCreatePutTest.java | 2 +-
.../near/GridCacheNearTxForceKeyTest.java | 1 -
.../CacheEntryProcessorNonSerializableTest.java | 2 +-
.../igfs/IgfsAbstractBaseSelfTest.java | 2 +-
.../processors/igfs/IgfsFileInfoSelfTest.java | 2 +-
.../service/ClosureServiceClientsNodesTest.java | 2 +-
...ent2ClassLoadersOptimizedMarshallerTest.java | 2 +-
...mentClassLoadingOptimizedMarshallerTest.java | 2 +-
...namicProxySerializationMultiJvmSelfTest.java | 2 +-
.../GridMarshallerPerformanceTest.java | 2 +-
.../OptimizedMarshallerEnumSelfTest.java | 87 -
.../OptimizedMarshallerNodeFailoverTest.java | 357 ---
.../OptimizedMarshallerPooledSelfTest.java | 44 -
.../optimized/OptimizedMarshallerSelfTest.java | 283 ---
...arshallerSerialPersistentFieldsSelfTest.java | 114 -
.../optimized/OptimizedMarshallerTest.java | 790 -------
.../OptimizedObjectStreamSelfTest.java | 2157 -----------------
.../TestTcpDiscoveryIpFinderAdapter.java | 43 -
.../marshaller/optimized/package-info.java | 22 -
.../IgniteMessagingWithClientTest.java | 2 +-
...pClientDiscoveryMarshallerCheckSelfTest.java | 2 +-
.../TcpDiscoveryMarshallerCheckSelfTest.java | 2 +-
.../configvariations/ConfigVariations.java | 2 +-
.../junits/IgniteTestResources.java | 2 +-
.../testsuites/IgniteBinaryBasicTestSuite.java | 14 +-
.../IgniteMarshallerSelfTestSuite.java | 14 +-
.../webapp/META-INF/ignite-webapp-config.xml | 2 +-
.../test/config/hadoop-fs-open-test/grid-0.xml | 2 +-
.../test/config/hadoop-fs-open-test/grid-1.xml | 2 +-
.../test/config/hadoop-fs-open-test/grid-2.xml | 2 +-
.../test/config/igfs-cli-config-dual-async.xml | 2 +-
.../test/config/igfs-cli-config-dual-sync.xml | 2 +-
.../src/test/config/igfs-cli-config-primary.xml | 2 +-
.../src/test/config/igfs-cli-config-proxy.xml | 2 +-
.../IgniteHadoopFileSystemAbstractSelfTest.java | 2 +-
.../cache/IgniteCacheNoClassQuerySelfTest.java | 2 +-
.../h2/sql/AbstractH2CompareQueryTest.java | 2 +-
.../FetchingQueryCursorStressTest.java | 2 +-
.../Config/marshaller-invalid.xml | 2 +-
.../GridSpringBeanSerializationSelfTest.java | 2 +-
.../generator/ConfigurationGenerator.js | 2 +-
.../webapp2/META-INF/ignite-webapp-config.xml | 2 +-
.../ignite-int-max-values-onheap-config.xml | 2 +-
modules/yardstick/config/ignite-jdbc-config.xml | 2 +-
102 files changed, 8506 insertions(+), 8551 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/a1b5b8c3/examples/config/filesystem/example-igfs.xml
----------------------------------------------------------------------
diff --git a/examples/config/filesystem/example-igfs.xml b/examples/config/filesystem/example-igfs.xml
index 2236821..454dc9f 100644
--- a/examples/config/filesystem/example-igfs.xml
+++ b/examples/config/filesystem/example-igfs.xml
@@ -50,13 +50,6 @@
Configuration below demonstrates how to setup a IgniteFs node with file data.
-->
<bean id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
- <property name="marshaller">
- <bean class="org.apache.ignite.marshaller.optimized.OptimizedMarshaller">
- <!-- Set to false to allow non-serializable objects in examples, default is true. -->
- <property name="requireSerializable" value="false"/>
- </bean>
- </property>
-
<property name="fileSystemConfiguration">
<list>
<bean class="org.apache.ignite.configuration.FileSystemConfiguration">
http://git-wip-us.apache.org/repos/asf/ignite/blob/a1b5b8c3/examples/src/main/java/org/apache/ignite/examples/misc/client/memcache/MemcacheRestExampleNodeStartup.java
----------------------------------------------------------------------
diff --git a/examples/src/main/java/org/apache/ignite/examples/misc/client/memcache/MemcacheRestExampleNodeStartup.java b/examples/src/main/java/org/apache/ignite/examples/misc/client/memcache/MemcacheRestExampleNodeStartup.java
index 3c835be..439e042 100644
--- a/examples/src/main/java/org/apache/ignite/examples/misc/client/memcache/MemcacheRestExampleNodeStartup.java
+++ b/examples/src/main/java/org/apache/ignite/examples/misc/client/memcache/MemcacheRestExampleNodeStartup.java
@@ -23,7 +23,6 @@ import org.apache.ignite.Ignition;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.ConnectorConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.marshaller.optimized.OptimizedMarshaller;
import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
@@ -64,12 +63,6 @@ public class MemcacheRestExampleNodeStartup {
cfg.setConnectorConfiguration(new ConnectorConfiguration());
- OptimizedMarshaller marsh = new OptimizedMarshaller();
-
- marsh.setRequireSerializable(false);
-
- cfg.setMarshaller(marsh);
-
CacheConfiguration cacheCfg = new CacheConfiguration();
cacheCfg.setAtomicityMode(TRANSACTIONAL);
http://git-wip-us.apache.org/repos/asf/ignite/blob/a1b5b8c3/modules/aop/src/test/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerAopTest.java
----------------------------------------------------------------------
diff --git a/modules/aop/src/test/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerAopTest.java b/modules/aop/src/test/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerAopTest.java
new file mode 100644
index 0000000..a1c52ab
--- /dev/null
+++ b/modules/aop/src/test/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerAopTest.java
@@ -0,0 +1,105 @@
+/*
+ * 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.marshaller.optimized;
+
+import java.util.concurrent.atomic.AtomicInteger;
+import org.apache.ignite.compute.gridify.Gridify;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.events.Event;
+import org.apache.ignite.internal.marshaller.optimized.OptimizedMarshaller;
+import org.apache.ignite.internal.util.typedef.G;
+import org.apache.ignite.internal.util.typedef.X;
+import org.apache.ignite.lang.IgnitePredicate;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+
+import static org.apache.ignite.events.EventType.EVT_TASK_FINISHED;
+
+/**
+ * Test use GridOptimizedMarshaller and AspectJ AOP.
+ *
+ * The following configuration needs to be applied to enable AspectJ byte code
+ * weaving.
+ * <ul>
+ * <li>
+ * JVM configuration should include:
+ * <tt>-javaagent:[IGNITE_HOME]/libs/aspectjweaver-1.7.2.jar</tt>
+ * </li>
+ * <li>
+ * Classpath should contain the <tt>[IGNITE_HOME]/modules/tests/config/aop/aspectj</tt> folder.
+ * </li>
+ * </ul>
+ */
+public class OptimizedMarshallerAopTest extends GridCommonAbstractTest {
+ /** */
+ private static final AtomicInteger cntr = new AtomicInteger();
+
+ /**
+ * Constructs a test.
+ */
+ public OptimizedMarshallerAopTest() {
+ super(false /* start grid. */);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void beforeTestsStarted() throws Exception {
+ IgniteConfiguration cfg = new IgniteConfiguration();
+
+ cfg.setMarshaller(new OptimizedMarshaller());
+
+ G.start(cfg);
+
+ assert G.allGrids().size() == 1;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void afterTestsStopped() throws Exception {
+ stopAllGrids();
+
+ assert G.allGrids().isEmpty();
+ }
+
+ /**
+ * JUnit.
+ *
+ * @throws Exception If failed.
+ */
+ public void testUp() throws Exception {
+ G.ignite().events().localListen(new IgnitePredicate<Event>() {
+ @Override public boolean apply(Event evt) {
+ cntr.incrementAndGet();
+
+ return true;
+ }
+ }, EVT_TASK_FINISHED);
+
+ gridify1();
+
+ assertEquals("Method gridify() wasn't executed on grid.", 1, cntr.get());
+ }
+
+ /**
+ * Method grid-enabled with {@link org.apache.ignite.compute.gridify.Gridify} annotation.
+ * <p>
+ * Note that default {@code Gridify} configuration is used, so this method
+ * will be executed on remote node with the same argument.
+ */
+ @Gridify
+ private void gridify1() {
+ X.println("Executes on grid");
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/a1b5b8c3/modules/aop/src/test/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerAopTest.java
----------------------------------------------------------------------
diff --git a/modules/aop/src/test/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerAopTest.java b/modules/aop/src/test/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerAopTest.java
deleted file mode 100644
index 7985fb2..0000000
--- a/modules/aop/src/test/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerAopTest.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * 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.marshaller.optimized;
-
-import java.util.concurrent.atomic.AtomicInteger;
-import org.apache.ignite.compute.gridify.Gridify;
-import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.events.Event;
-import org.apache.ignite.internal.util.typedef.G;
-import org.apache.ignite.internal.util.typedef.X;
-import org.apache.ignite.lang.IgnitePredicate;
-import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
-
-import static org.apache.ignite.events.EventType.EVT_TASK_FINISHED;
-
-/**
- * Test use GridOptimizedMarshaller and AspectJ AOP.
- *
- * The following configuration needs to be applied to enable AspectJ byte code
- * weaving.
- * <ul>
- * <li>
- * JVM configuration should include:
- * <tt>-javaagent:[IGNITE_HOME]/libs/aspectjweaver-1.7.2.jar</tt>
- * </li>
- * <li>
- * Classpath should contain the <tt>[IGNITE_HOME]/modules/tests/config/aop/aspectj</tt> folder.
- * </li>
- * </ul>
- */
-public class OptimizedMarshallerAopTest extends GridCommonAbstractTest {
- /** */
- private static final AtomicInteger cntr = new AtomicInteger();
-
- /**
- * Constructs a test.
- */
- public OptimizedMarshallerAopTest() {
- super(false /* start grid. */);
- }
-
- /** {@inheritDoc} */
- @Override protected void beforeTestsStarted() throws Exception {
- IgniteConfiguration cfg = new IgniteConfiguration();
-
- cfg.setMarshaller(new OptimizedMarshaller());
-
- G.start(cfg);
-
- assert G.allGrids().size() == 1;
- }
-
- /** {@inheritDoc} */
- @Override protected void afterTestsStopped() throws Exception {
- stopAllGrids();
-
- assert G.allGrids().isEmpty();
- }
-
- /**
- * JUnit.
- *
- * @throws Exception If failed.
- */
- public void testUp() throws Exception {
- G.ignite().events().localListen(new IgnitePredicate<Event>() {
- @Override public boolean apply(Event evt) {
- cntr.incrementAndGet();
-
- return true;
- }
- }, EVT_TASK_FINISHED);
-
- gridify1();
-
- assertEquals("Method gridify() wasn't executed on grid.", 1, cntr.get());
- }
-
- /**
- * Method grid-enabled with {@link org.apache.ignite.compute.gridify.Gridify} annotation.
- * <p>
- * Note that default {@code Gridify} configuration is used, so this method
- * will be executed on remote node with the same argument.
- */
- @Gridify
- private void gridify1() {
- X.println("Executes on grid");
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/a1b5b8c3/modules/clients/src/test/config/jdbc-config.xml
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/config/jdbc-config.xml b/modules/clients/src/test/config/jdbc-config.xml
index 27d2617..7bba410 100644
--- a/modules/clients/src/test/config/jdbc-config.xml
+++ b/modules/clients/src/test/config/jdbc-config.xml
@@ -32,7 +32,7 @@
<property name="localHost" value="127.0.0.1"/>
<property name="marshaller">
- <bean class="org.apache.ignite.marshaller.optimized.OptimizedMarshaller">
+ <bean class="org.apache.ignite.internal.marshaller.optimized.OptimizedMarshaller">
<property name="requireSerializable" value="false"/>
</bean>
</property>
http://git-wip-us.apache.org/repos/asf/ignite/blob/a1b5b8c3/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java b/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
index 0b4644f..1216db8 100644
--- a/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
+++ b/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
@@ -24,7 +24,7 @@ import java.util.Map;
import java.util.Properties;
import javax.net.ssl.HostnameVerifier;
import org.apache.ignite.lang.IgnitePredicate;
-import org.apache.ignite.marshaller.optimized.OptimizedMarshaller;
+import org.apache.ignite.internal.marshaller.optimized.OptimizedMarshaller;
import org.jetbrains.annotations.Nullable;
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/a1b5b8c3/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
index 286ced0..c991319 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
@@ -170,7 +170,7 @@ import org.apache.ignite.lifecycle.LifecycleAware;
import org.apache.ignite.lifecycle.LifecycleBean;
import org.apache.ignite.lifecycle.LifecycleEventType;
import org.apache.ignite.marshaller.MarshallerExclusions;
-import org.apache.ignite.marshaller.optimized.OptimizedMarshaller;
+import org.apache.ignite.internal.marshaller.optimized.OptimizedMarshaller;
import org.apache.ignite.mxbean.ClusterLocalNodeMetricsMXBean;
import org.apache.ignite.mxbean.IgniteMXBean;
import org.apache.ignite.mxbean.StripedExecutorMXBean;
http://git-wip-us.apache.org/repos/asf/ignite/blob/a1b5b8c3/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java
index 92e4874..f6e637f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java
@@ -48,7 +48,7 @@ import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.marshaller.MarshallerExclusions;
-import org.apache.ignite.marshaller.optimized.OptimizedMarshaller;
+import org.apache.ignite.internal.marshaller.optimized.OptimizedMarshaller;
import org.jetbrains.annotations.Nullable;
import static org.apache.ignite.internal.processors.query.QueryUtils.isGeometryClass;
http://git-wip-us.apache.org/repos/asf/ignite/blob/a1b5b8c3/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java
index 1ce2d65..f339253 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java
@@ -87,7 +87,7 @@ import org.apache.ignite.lang.IgniteBiTuple;
import org.apache.ignite.lang.IgniteUuid;
import org.apache.ignite.marshaller.MarshallerContext;
import org.apache.ignite.marshaller.MarshallerUtils;
-import org.apache.ignite.marshaller.optimized.OptimizedMarshaller;
+import org.apache.ignite.internal.marshaller.optimized.OptimizedMarshaller;
import org.jetbrains.annotations.Nullable;
import org.jsr166.ConcurrentHashMap8;
http://git-wip-us.apache.org/repos/asf/ignite/blob/a1b5b8c3/modules/core/src/main/java/org/apache/ignite/internal/client/marshaller/optimized/GridClientOptimizedMarshaller.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/marshaller/optimized/GridClientOptimizedMarshaller.java b/modules/core/src/main/java/org/apache/ignite/internal/client/marshaller/optimized/GridClientOptimizedMarshaller.java
index 6a4b5e8..75f1807 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/client/marshaller/optimized/GridClientOptimizedMarshaller.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/client/marshaller/optimized/GridClientOptimizedMarshaller.java
@@ -26,7 +26,7 @@ import org.apache.ignite.internal.MarshallerContextImpl;
import org.apache.ignite.internal.client.marshaller.GridClientMarshaller;
import org.apache.ignite.internal.processors.rest.client.message.GridClientMessage;
import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.marshaller.optimized.OptimizedMarshaller;
+import org.apache.ignite.internal.marshaller.optimized.OptimizedMarshaller;
import org.apache.ignite.plugin.PluginProvider;
import org.jetbrains.annotations.Nullable;
http://git-wip-us.apache.org/repos/asf/ignite/blob/a1b5b8c3/modules/core/src/main/java/org/apache/ignite/internal/client/marshaller/optimized/GridClientZipOptimizedMarshaller.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/marshaller/optimized/GridClientZipOptimizedMarshaller.java b/modules/core/src/main/java/org/apache/ignite/internal/client/marshaller/optimized/GridClientZipOptimizedMarshaller.java
index b709634..bc8220f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/client/marshaller/optimized/GridClientZipOptimizedMarshaller.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/client/marshaller/optimized/GridClientZipOptimizedMarshaller.java
@@ -31,7 +31,7 @@ import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.internal.client.marshaller.GridClientMarshaller;
import org.apache.ignite.internal.processors.rest.client.message.GridClientMessage;
import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.marshaller.optimized.OptimizedMarshaller;
+import org.apache.ignite.internal.marshaller.optimized.OptimizedMarshaller;
import org.apache.ignite.plugin.PluginProvider;
import org.jetbrains.annotations.Nullable;
http://git-wip-us.apache.org/repos/asf/ignite/blob/a1b5b8c3/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedClassDescriptor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedClassDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedClassDescriptor.java
new file mode 100644
index 0000000..4c0ce17
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedClassDescriptor.java
@@ -0,0 +1,1141 @@
+/*
+ * 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.marshaller.optimized;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.NotSerializableException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamField;
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Proxy;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.ignite.internal.util.GridUnsafe;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgniteProductVersion;
+import org.apache.ignite.marshaller.MarshallerContext;
+import org.apache.ignite.marshaller.MarshallerExclusions;
+import org.apache.ignite.internal.util.SerializableTransient;
+import org.apache.ignite.marshaller.MarshallerUtils;
+
+import static java.lang.reflect.Modifier.isFinal;
+import static java.lang.reflect.Modifier.isPrivate;
+import static java.lang.reflect.Modifier.isStatic;
+import static java.lang.reflect.Modifier.isTransient;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.ARRAY_LIST;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.BOOLEAN;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.BOOLEAN_ARR;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.BYTE;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.BYTE_ARR;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.CHAR;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.CHAR_ARR;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.CLS;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.DATE;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.DOUBLE;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.DOUBLE_ARR;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.ENUM;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.EXTERNALIZABLE;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.FLOAT;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.FLOAT_ARR;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.HASH_MAP;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.HASH_SET;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.HASH_SET_MAP_OFF;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.INT;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.INT_ARR;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.LINKED_HASH_MAP;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.LINKED_HASH_SET;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.LINKED_LIST;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.LONG;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.LONG_ARR;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.OBJ_ARR;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.PROPS;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.PROXY;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.SERIALIZABLE;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.SHORT;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.SHORT_ARR;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.STR;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.UUID;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.computeSerialVersionUid;
+
+/**
+ * Class descriptor.
+ */
+class OptimizedClassDescriptor {
+ /** Class. */
+ private final Class<?> cls;
+
+ /** Context. */
+ private final MarshallerContext ctx;
+
+ /** */
+ private ConcurrentMap<Class, OptimizedClassDescriptor> clsMap;
+
+ /** ID mapper. */
+ private final OptimizedMarshallerIdMapper mapper;
+
+ /** Class name. */
+ private final String name;
+
+ /** Type ID. */
+ private final int typeId;
+
+ /** Short ID. */
+ private final short checksum;
+
+ /** Class type. */
+ private int type;
+
+ /** Primitive flag. */
+ private boolean isPrimitive;
+
+ /** Enum flag. */
+ private boolean isEnum;
+
+ /** Serializable flag. */
+ private boolean isSerial;
+
+ /** Excluded flag. */
+ private boolean excluded;
+
+ /** {@code True} if descriptor is for {@link Class}. */
+ private boolean isCls;
+
+ /** 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;
+
+ /** Access order field offset. */
+ private long accessOrderFieldOff;
+
+ /** Proxy interfaces. */
+ private Class<?>[] proxyIntfs;
+
+ /** Method returns serializable transient fields. */
+ private Method serTransMtd;
+
+ /**
+ * Creates descriptor for class.
+ *
+ * @param typeId Type ID.
+ * @param clsMap Class descriptors by class map.
+ * @param cls Class.
+ * @param ctx Context.
+ * @param mapper ID mapper.
+ * @throws IOException In case of error.
+ */
+ @SuppressWarnings("ForLoopReplaceableByForEach")
+ OptimizedClassDescriptor(Class<?> cls,
+ int typeId,
+ ConcurrentMap<Class, OptimizedClassDescriptor> clsMap,
+ MarshallerContext ctx,
+ OptimizedMarshallerIdMapper mapper)
+ throws IOException {
+ this.cls = cls;
+ this.typeId = typeId;
+ this.clsMap = clsMap;
+ this.ctx = ctx;
+ this.mapper = mapper;
+
+ name = cls.getName();
+
+ excluded = MarshallerExclusions.isExcluded(cls);
+
+ if (!excluded) {
+ Class<?> parent;
+
+ if (cls == byte.class || cls == Byte.class) {
+ type = BYTE;
+
+ isPrimitive = true;
+ }
+ else if (cls == short.class || cls == Short.class) {
+ type = SHORT;
+
+ isPrimitive = true;
+ }
+ else if (cls == int.class || cls == Integer.class) {
+ type = INT;
+
+ isPrimitive = true;
+ }
+ else if (cls == long.class || cls == Long.class) {
+ type = LONG;
+
+ isPrimitive = true;
+ }
+ else if (cls == float.class || cls == Float.class) {
+ type = FLOAT;
+
+ isPrimitive = true;
+ }
+ else if (cls == double.class || cls == Double.class) {
+ type = DOUBLE;
+
+ isPrimitive = true;
+ }
+ else if (cls == char.class || cls == Character.class) {
+ type = CHAR;
+
+ isPrimitive = true;
+ }
+ else if (cls == boolean.class || cls == Boolean.class) {
+ type = BOOLEAN;
+
+ isPrimitive = true;
+ }
+ else if (cls == byte[].class)
+ type = BYTE_ARR;
+ else if (cls == short[].class)
+ type = SHORT_ARR;
+ else if (cls == int[].class)
+ type = INT_ARR;
+ else if (cls == long[].class)
+ type = LONG_ARR;
+ else if (cls == float[].class)
+ type = FLOAT_ARR;
+ else if (cls == double[].class)
+ type = DOUBLE_ARR;
+ else if (cls == char[].class)
+ type = CHAR_ARR;
+ else if (cls == boolean[].class)
+ type = BOOLEAN_ARR;
+ else if (cls.isArray())
+ type = OBJ_ARR;
+ else if (cls == String.class)
+ type = STR;
+ else if (cls.isEnum()) {
+ 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 = ENUM;
+
+ isEnum = true;
+ enumVals = parent.getEnumConstants();
+ }
+ else if (cls == UUID.class)
+ type = UUID;
+ else if (cls == Properties.class) {
+ type = PROPS;
+
+ try {
+ dfltsFieldOff = GridUnsafe.objectFieldOffset(Properties.class.getDeclaredField("defaults"));
+ }
+ catch (NoSuchFieldException e) {
+ throw new IOException(e);
+ }
+ }
+ else if (cls == ArrayList.class)
+ type = ARRAY_LIST;
+ else if (cls == HashMap.class) {
+ type = HASH_MAP;
+
+ try {
+ loadFactorFieldOff = GridUnsafe.objectFieldOffset(HashMap.class.getDeclaredField("loadFactor"));
+ }
+ catch (NoSuchFieldException e) {
+ throw new IOException(e);
+ }
+ }
+ else if (cls == HashSet.class) {
+ type = HASH_SET;
+
+ try {
+ loadFactorFieldOff = GridUnsafe.objectFieldOffset(HashMap.class.getDeclaredField("loadFactor"));
+ }
+ catch (NoSuchFieldException e) {
+ throw new IOException(e);
+ }
+ }
+ else if (cls == LinkedList.class)
+ type = LINKED_LIST;
+ else if (cls == LinkedHashMap.class) {
+ type = LINKED_HASH_MAP;
+
+ try {
+ loadFactorFieldOff =
+ GridUnsafe.objectFieldOffset(HashMap.class.getDeclaredField("loadFactor"));
+ accessOrderFieldOff =
+ GridUnsafe.objectFieldOffset(LinkedHashMap.class.getDeclaredField("accessOrder"));
+ }
+ catch (NoSuchFieldException e) {
+ throw new IOException(e);
+ }
+ }
+ else if (cls == LinkedHashSet.class) {
+ type = LINKED_HASH_SET;
+
+ try {
+ loadFactorFieldOff = GridUnsafe.objectFieldOffset(HashMap.class.getDeclaredField("loadFactor"));
+ }
+ catch (NoSuchFieldException e) {
+ throw new IOException(e);
+ }
+ }
+ else if (cls == Date.class)
+ type = DATE;
+ else if (cls == Class.class) {
+ type = CLS;
+
+ isCls = true;
+ }
+ else if (Proxy.class.isAssignableFrom(cls)) {
+ type = PROXY;
+
+ proxyIntfs = cls.getInterfaces();
+ }
+ 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 = EXTERNALIZABLE;
+
+ try {
+ constructor = !Modifier.isStatic(cls.getModifiers()) && cls.getDeclaringClass() != null ?
+ cls.getDeclaredConstructor(cls.getDeclaringClass()) :
+ cls.getDeclaredConstructor();
+
+ constructor.setAccessible(true);
+ }
+ catch (NoSuchMethodException e) {
+ throw new IOException("Externalizable class doesn't have default constructor: " + cls, e);
+ }
+ }
+ else {
+ type = SERIALIZABLE;
+
+ isSerial = Serializable.class.isAssignableFrom(cls);
+
+ writeObjMtds = new ArrayList<>();
+ readObjMtds = new ArrayList<>();
+ List<ClassFields> fields = 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);
+
+ final SerializableTransient serTransAn = c.getAnnotation(SerializableTransient.class);
+
+ // Custom serialization policy for transient fields.
+ if (serTransAn != null) {
+ try {
+ serTransMtd = c.getDeclaredMethod(serTransAn.methodName(), cls, IgniteProductVersion.class);
+
+ int mod = serTransMtd.getModifiers();
+
+ if (isStatic(mod) && isPrivate(mod)
+ && serTransMtd.getReturnType() == String[].class)
+ serTransMtd.setAccessible(true);
+ else
+ // Set method back to null if it has incorrect signature.
+ serTransMtd = null;
+ }
+ catch (NoSuchMethodException ignored) {
+ serTransMtd = null;
+ }
+ }
+
+ Field[] clsFields0 = c.getDeclaredFields();
+
+ Map<String, Field> fieldNames = new HashMap<>();
+
+ for (Field f : clsFields0)
+ fieldNames.put(f.getName(), f);
+
+ List<FieldInfo> clsFields = new ArrayList<>(clsFields0.length);
+
+ boolean hasSerialPersistentFields = false;
+
+ try {
+ Field serFieldsDesc = c.getDeclaredField("serialPersistentFields");
+
+ int mod = serFieldsDesc.getModifiers();
+
+ if (serFieldsDesc.getType() == ObjectStreamField[].class &&
+ isPrivate(mod) && isStatic(mod) && isFinal(mod)) {
+ hasSerialPersistentFields = true;
+
+ serFieldsDesc.setAccessible(true);
+
+ ObjectStreamField[] serFields = (ObjectStreamField[]) serFieldsDesc.get(null);
+
+ for (int i = 0; i < serFields.length; i++) {
+ ObjectStreamField serField = serFields[i];
+
+ FieldInfo fieldInfo;
+
+ if (!fieldNames.containsKey(serField.getName())) {
+ fieldInfo = new FieldInfo(null,
+ serField.getName(),
+ -1,
+ fieldType(serField.getType()));
+ }
+ else {
+ Field f = fieldNames.get(serField.getName());
+
+ fieldInfo = new FieldInfo(f,
+ serField.getName(),
+ GridUnsafe.objectFieldOffset(f),
+ fieldType(serField.getType()));
+ }
+
+ clsFields.add(fieldInfo);
+ }
+ }
+ }
+ catch (NoSuchFieldException ignored) {
+ // No-op.
+ }
+ catch (IllegalAccessException e) {
+ throw new IOException("Failed to get value of 'serialPersistentFields' field in class: " +
+ cls.getName(), e);
+ }
+
+ if (!hasSerialPersistentFields) {
+ for (int i = 0; i < clsFields0.length; i++) {
+ Field f = clsFields0[i];
+
+ int mod = f.getModifiers();
+
+ if (!isStatic(mod) && !isTransient(mod)) {
+ FieldInfo fieldInfo = new FieldInfo(f, f.getName(),
+ GridUnsafe.objectFieldOffset(f), fieldType(f.getType()));
+
+ clsFields.add(fieldInfo);
+ }
+ }
+ }
+
+ Collections.sort(clsFields, new Comparator<FieldInfo>() {
+ @Override public int compare(FieldInfo t1, FieldInfo t2) {
+ return t1.name().compareTo(t2.name());
+ }
+ });
+
+ fields.add(new ClassFields(clsFields));
+ }
+
+ Collections.reverse(writeObjMtds);
+ Collections.reverse(readObjMtds);
+ Collections.reverse(fields);
+
+ this.fields = new Fields(fields);
+ }
+ }
+ }
+
+ checksum = computeSerialVersionUid(cls, fields != null ? fields.ownFields() : null);
+ }
+
+ /**
+ * @return Excluded flag.
+ */
+ boolean excluded() {
+ return excluded;
+ }
+
+ /**
+ * @return Class.
+ */
+ Class<?> describedClass() {
+ return cls;
+ }
+
+ /**
+ * @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;
+ }
+
+ /**
+ * @return {@code True} if descriptor is for {@link Proxy}.
+ */
+ boolean isProxy() {
+ return type == PROXY;
+ }
+
+ /**
+ * 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(OptimizedObjectOutputStream out, Object obj) throws IOException {
+ out.write(type);
+
+ switch (type) {
+ case BYTE:
+ out.writeByte((Byte)obj);
+
+ break;
+
+ case SHORT:
+ out.writeShort((Short)obj);
+
+ break;
+
+ case INT:
+ out.writeInt((Integer)obj);
+
+ break;
+
+ case LONG:
+ out.writeLong((Long)obj);
+
+ break;
+
+ case FLOAT:
+ out.writeFloat((Float)obj);
+
+ break;
+
+ case DOUBLE:
+ out.writeDouble((Double)obj);
+
+ break;
+
+ case CHAR:
+ out.writeChar((Character)obj);
+
+ break;
+
+ case BOOLEAN:
+ out.writeBoolean((Boolean)obj);
+
+ break;
+
+ case BYTE_ARR:
+ out.writeByteArray((byte[])obj);
+
+ break;
+
+ case SHORT_ARR:
+ out.writeShortArray((short[])obj);
+
+ break;
+
+ case INT_ARR:
+ out.writeIntArray((int[])obj);
+
+ break;
+
+ case LONG_ARR:
+ out.writeLongArray((long[])obj);
+
+ break;
+
+ case FLOAT_ARR:
+ out.writeFloatArray((float[])obj);
+
+ break;
+
+ case DOUBLE_ARR:
+ out.writeDoubleArray((double[])obj);
+
+ break;
+
+ case CHAR_ARR:
+ out.writeCharArray((char[])obj);
+
+ break;
+
+ case BOOLEAN_ARR:
+ out.writeBooleanArray((boolean[])obj);
+
+ break;
+
+ case OBJ_ARR:
+ OptimizedClassDescriptor compDesc = OptimizedMarshallerUtils.classDescriptor(clsMap,
+ obj.getClass().getComponentType(),
+ ctx,
+ mapper);
+
+ compDesc.writeTypeData(out);
+
+ out.writeArray((Object[])obj);
+
+ break;
+
+ case STR:
+ out.writeString((String)obj);
+
+ break;
+
+ case UUID:
+ out.writeUuid((UUID)obj);
+
+ break;
+
+ case PROPS:
+ out.writeProperties((Properties)obj, dfltsFieldOff);
+
+ break;
+
+ case ARRAY_LIST:
+ out.writeArrayList((ArrayList<?>)obj);
+
+ break;
+
+ case HASH_MAP:
+ out.writeHashMap((HashMap<?, ?>)obj, loadFactorFieldOff, false);
+
+ break;
+
+ case HASH_SET:
+ out.writeHashSet((HashSet<?>)obj, HASH_SET_MAP_OFF, loadFactorFieldOff);
+
+ break;
+
+ case LINKED_LIST:
+ out.writeLinkedList((LinkedList<?>)obj);
+
+ break;
+
+ case LINKED_HASH_MAP:
+ out.writeLinkedHashMap((LinkedHashMap<?, ?>)obj, loadFactorFieldOff, accessOrderFieldOff, false);
+
+ break;
+
+ case LINKED_HASH_SET:
+ out.writeLinkedHashSet((LinkedHashSet<?>)obj, HASH_SET_MAP_OFF, loadFactorFieldOff);
+
+ break;
+
+ case DATE:
+ out.writeDate((Date)obj);
+
+ break;
+
+ case CLS:
+ OptimizedClassDescriptor clsDesc = OptimizedMarshallerUtils.classDescriptor(clsMap, (Class<?>)obj, ctx, mapper);
+
+ clsDesc.writeTypeData(out);
+
+ break;
+
+ case PROXY:
+ out.writeInt(proxyIntfs.length);
+
+ for (Class<?> intf : proxyIntfs) {
+ OptimizedClassDescriptor intfDesc = OptimizedMarshallerUtils.classDescriptor(clsMap, intf, ctx, mapper);
+
+ intfDesc.writeTypeData(out);
+ }
+
+ InvocationHandler ih = Proxy.getInvocationHandler(obj);
+
+ assert ih != null;
+
+ out.writeObject(ih);
+
+ break;
+
+ case ENUM:
+ writeTypeData(out);
+
+ out.writeInt(((Enum)obj).ordinal());
+
+ break;
+
+ case EXTERNALIZABLE:
+ writeTypeData(out);
+
+ out.writeShort(checksum);
+ out.writeExternalizable(obj);
+
+ break;
+
+ case SERIALIZABLE:
+ if (out.requireSerializable() && !isSerial)
+ throw new NotSerializableException("Must implement java.io.Serializable or " +
+ "set OptimizedMarshaller.setRequireSerializable() to false " +
+ "(note that performance may degrade if object is not Serializable): " + name);
+
+ writeTypeData(out);
+
+ out.writeShort(checksum);
+ out.writeSerializable(obj, writeObjMtds, serializableFields(obj.getClass(), obj, null));
+
+ break;
+
+ default:
+ throw new IllegalStateException("Invalid class type: " + type);
+ }
+ }
+
+ /**
+ * Gets list of serializable fields. If {@link #serTransMtd} method
+ * returns list of transient fields, they will be added to other fields.
+ * Transient fields that are not included in that list will be normally
+ * ignored.
+ *
+ * @param cls Class.
+ * @param obj Object.
+ * @param ver Job sender version.
+ * @return Serializable fields.
+ */
+ @SuppressWarnings("ForLoopReplaceableByForEach")
+ private Fields serializableFields(Class<?> cls, Object obj, IgniteProductVersion ver) {
+ if (serTransMtd == null)
+ return fields;
+
+ try {
+ final String[] transFields = (String[])serTransMtd.invoke(cls, obj, ver);
+
+ if (transFields == null || transFields.length == 0)
+ return fields;
+
+ List<FieldInfo> clsFields = new ArrayList<>();
+
+ clsFields.addAll(fields.fields.get(0).fields);
+
+ for (int i = 0; i < transFields.length; i++) {
+ final String fieldName = transFields[i];
+
+ final Field f = cls.getDeclaredField(fieldName);
+
+ FieldInfo fieldInfo = new FieldInfo(f, f.getName(),
+ GridUnsafe.objectFieldOffset(f), fieldType(f.getType()));
+
+ clsFields.add(fieldInfo);
+ }
+
+ Collections.sort(clsFields, new Comparator<FieldInfo>() {
+ @Override public int compare(FieldInfo t1, FieldInfo t2) {
+ return t1.name().compareTo(t2.name());
+ }
+ });
+
+ List<ClassFields> fields = new ArrayList<>();
+
+ fields.add(new ClassFields(clsFields));
+
+ return new Fields(fields);
+ }
+ catch (Exception ignored) {
+ return fields;
+ }
+ }
+
+ /**
+ * @param out Output stream.
+ * @throws IOException In case of error.
+ */
+ void writeTypeData(OptimizedObjectOutputStream out) throws IOException {
+ out.writeInt(typeId);
+
+ if (typeId == 0)
+ out.writeUTF(name);
+ }
+
+ /**
+ * Reads object from stream.
+ *
+ * @param in Input stream.
+ * @return Object.
+ * @throws ClassNotFoundException If class not found.
+ * @throws IOException In case of error.
+ */
+ Object read(OptimizedObjectInputStream in) throws ClassNotFoundException, IOException {
+ switch (type) {
+ case ENUM:
+ return enumVals[in.readInt()];
+
+ case EXTERNALIZABLE:
+ verifyChecksum(in.readShort());
+
+ return in.readExternalizable(constructor, readResolveMtd);
+
+ case SERIALIZABLE:
+ verifyChecksum(in.readShort());
+
+ // If no serialize method, then unmarshal as usual.
+ if (serTransMtd != null)
+ return in.readSerializable(cls, readObjMtds, readResolveMtd,
+ serializableFields(cls, null, MarshallerUtils.jobSenderVersion()));
+ else
+ return in.readSerializable(cls, readObjMtds, readResolveMtd, fields);
+
+ default:
+ assert false : "Unexpected type: " + type;
+
+ return null;
+ }
+ }
+
+ /**
+ * @param checksum Checksum.
+ * @throws ClassNotFoundException If checksum is wrong.
+ * @throws IOException In case of error.
+ */
+ private void verifyChecksum(short checksum) throws ClassNotFoundException, IOException {
+ if (checksum != this.checksum)
+ throw new ClassNotFoundException("Optimized stream class checksum mismatch " +
+ "(is same version of marshalled class present on all nodes?) " +
+ "[expected=" + this.checksum + ", actual=" + checksum + ", cls=" + cls + ']');
+ }
+
+ /**
+ * @param cls Class.
+ * @return Type.
+ */
+ @SuppressWarnings("IfMayBeConditional")
+ private OptimizedFieldType fieldType(Class<?> cls) {
+ OptimizedFieldType type;
+
+ if (cls == byte.class)
+ type = OptimizedFieldType.BYTE;
+ else if (cls == short.class)
+ type = OptimizedFieldType.SHORT;
+ else if (cls == int.class)
+ type = OptimizedFieldType.INT;
+ else if (cls == long.class)
+ type = OptimizedFieldType.LONG;
+ else if (cls == float.class)
+ type = OptimizedFieldType.FLOAT;
+ else if (cls == double.class)
+ type = OptimizedFieldType.DOUBLE;
+ else if (cls == char.class)
+ type = OptimizedFieldType.CHAR;
+ else if (cls == boolean.class)
+ type = OptimizedFieldType.BOOLEAN;
+ else
+ type = OptimizedFieldType.OTHER;
+
+ return type;
+ }
+
+ /**
+ * Information about one field.
+ */
+ @SuppressWarnings("PackageVisibleInnerClass")
+ static class FieldInfo {
+ /** Field. */
+ private final Field field;
+
+ /** Field offset. */
+ private final long fieldOffs;
+
+ /** Field type. */
+ private final OptimizedFieldType fieldType;
+
+ /** Field name. */
+ private final String fieldName;
+
+ /**
+ * @param field Field.
+ * @param name Field name.
+ * @param offset Field offset.
+ * @param type Grid optimized field type.
+ */
+ FieldInfo(Field field, String name, long offset, OptimizedFieldType type) {
+ this.field = field;
+ fieldOffs = offset;
+ fieldType = type;
+ fieldName = name;
+ }
+
+ /**
+ * @return Returns field.
+ */
+ Field field() {
+ return field;
+ }
+
+ /**
+ * @return Offset.
+ */
+ long offset() {
+ return fieldOffs;
+ }
+
+ /**
+ * @return Type.
+ */
+ OptimizedFieldType type() {
+ return fieldType;
+ }
+
+ /**
+ * @return Name.
+ */
+ String name() {
+ return fieldName;
+ }
+ }
+
+ /**
+ * Information about one class.
+ */
+ static class ClassFields {
+ /** Fields. */
+ private final List<FieldInfo> fields;
+
+ private final Map<String, Integer> nameToIndex;
+
+ /**
+ * @param fields Field infos.
+ */
+ ClassFields(List<FieldInfo> fields) {
+ this.fields = fields;
+
+ nameToIndex = U.newHashMap(fields.size());
+
+ for (int i = 0; i < fields.size(); ++i)
+ nameToIndex.put(fields.get(i).name(), i);
+ }
+
+ /**
+ * @return Class fields.
+ */
+ List<FieldInfo> fields() {
+ return fields;
+ }
+
+ /**
+ * @return Fields count.
+ */
+ int size() {
+ return fields.size();
+ }
+
+ /**
+ * @param i Field's index.
+ * @return FieldInfo.
+ */
+ FieldInfo get(int i) {
+ return fields.get(i);
+ }
+
+ /**
+ * @param name Field's name.
+ * @return Field's index.
+ */
+ int getIndex(String name) {
+ assert nameToIndex.containsKey(name);
+
+ return nameToIndex.get(name);
+ }
+ }
+
+ /**
+ * Encapsulates data about class fields.
+ */
+ @SuppressWarnings("PackageVisibleInnerClass")
+ static class Fields {
+ /** Fields. */
+ private final List<ClassFields> fields;
+
+ /** Own fields (excluding inherited). */
+ private final List<Field> ownFields;
+
+ /**
+ * Creates new instance.
+ *
+ * @param fields Fields.
+ */
+ Fields(List<ClassFields> fields) {
+ this.fields = fields;
+
+ if (fields.isEmpty())
+ ownFields = null;
+ else {
+ ownFields = new ArrayList<>(fields.size());
+
+ for (FieldInfo f : fields.get(fields.size() - 1).fields()) {
+ if (f.field() != null)
+ ownFields.add(f.field);
+ }
+ }
+ }
+
+ /**
+ * Returns class's own fields (excluding inherited).
+ *
+ * @return List of fields or {@code null} if fields list is empty.
+ */
+ List<Field> ownFields() {
+ return ownFields;
+ }
+
+ /**
+ * 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.
+ */
+ ClassFields fields(int i) {
+ return fields.get(i);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/a1b5b8c3/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedFieldType.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedFieldType.java b/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedFieldType.java
new file mode 100644
index 0000000..39cad13
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedFieldType.java
@@ -0,0 +1,50 @@
+/*
+ * 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.marshaller.optimized;
+
+/**
+ * Field type used to calculate {@code Unsafe} offsets into objects.
+ */
+enum OptimizedFieldType {
+ /** */
+ BYTE,
+
+ /** */
+ SHORT,
+
+ /** */
+ INT,
+
+ /** */
+ LONG,
+
+ /** */
+ FLOAT,
+
+ /** */
+ DOUBLE,
+
+ /** */
+ CHAR,
+
+ /** */
+ BOOLEAN,
+
+ /** */
+ OTHER
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/a1b5b8c3/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshaller.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshaller.java b/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshaller.java
new file mode 100644
index 0000000..3f40d63
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshaller.java
@@ -0,0 +1,313 @@
+/*
+ * 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.marshaller.optimized;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.util.concurrent.ConcurrentMap;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.IgniteSystemProperties;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.marshaller.AbstractNodeNameAwareMarshaller;
+import org.jetbrains.annotations.Nullable;
+import org.jsr166.ConcurrentHashMap8;
+import sun.misc.Unsafe;
+
+import static org.apache.ignite.IgniteSystemProperties.IGNITE_OPTIMIZED_MARSHALLER_USE_DEFAULT_SUID;
+
+/**
+ * Optimized implementation of {@link org.apache.ignite.marshaller.Marshaller}.
+ * Unlike {@link org.apache.ignite.marshaller.jdk.JdkMarshaller},
+ * 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 OptimizedMarshaller} 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">
+ * OptimizedMarshaller marshaller = new OptimizedMarshaller();
+ *
+ * // Enforce Serializable interface.
+ * marshaller.setRequireSerializable(true);
+ *
+ * IgniteConfiguration cfg = new IgniteConfiguration();
+ *
+ * // 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">
+ * <bean id="grid.custom.cfg" class="org.apache.ignite.configuration.IgniteConfiguration" singleton="true">
+ * ...
+ * <property name="marshaller">
+ * <bean class="org.apache.ignite.internal.marshaller.optimized.OptimizedMarshaller">
+ * <property name="requireSerializable">true</property>
+ * </bean>
+ * </property>
+ * ...
+ * </bean>
+ * </pre>
+ * <p>
+ * <img src="http://ignite.apache.org/images/spring-small.png">
+ * <br>
+ * For information about Spring framework visit <a href="http://www.springframework.org/">www.springframework.org</a>
+ */
+public class OptimizedMarshaller extends AbstractNodeNameAwareMarshaller {
+ /** Use default {@code serialVersionUID} for {@link Serializable} classes. */
+ public static final boolean USE_DFLT_SUID =
+ IgniteSystemProperties.getBoolean(IGNITE_OPTIMIZED_MARSHALLER_USE_DEFAULT_SUID, false);
+
+ /** Default class loader. */
+ private final ClassLoader dfltClsLdr = getClass().getClassLoader();
+
+ /** Whether or not to require an object to be serializable in order to be marshalled. */
+ private boolean requireSer = true;
+
+ /** ID mapper. */
+ private OptimizedMarshallerIdMapper mapper;
+
+ /** Class descriptors by class. */
+ private final ConcurrentMap<Class, OptimizedClassDescriptor> clsMap = new ConcurrentHashMap8<>();
+
+ /**
+ * Creates new marshaller will all defaults.
+ *
+ * @throws IgniteException If this marshaller is not supported on the current JVM.
+ */
+ public OptimizedMarshaller() {
+ if (!available())
+ throw new IgniteException("Using OptimizedMarshaller on unsupported JVM version (some of " +
+ "JVM-private APIs required for the marshaller to work are missing).");
+ }
+
+ /**
+ * Creates new marshaller providing whether it should
+ * require {@link Serializable} interface or not.
+ *
+ * @param requireSer Whether to require {@link Serializable}.
+ */
+ public OptimizedMarshaller(boolean requireSer) {
+ this.requireSer = requireSer;
+ }
+
+ /**
+ * Sets whether marshaller should require {@link Serializable} interface or not.
+ *
+ * @param requireSer Whether to require {@link Serializable}.
+ * @return {@code this} for chaining.
+ */
+ public OptimizedMarshaller setRequireSerializable(boolean requireSer) {
+ this.requireSer = requireSer;
+
+ return this;
+ }
+
+ /**
+ * Sets ID mapper.
+ *
+ * @param mapper ID mapper.
+ * @return {@code this} for chaining.
+ */
+ public OptimizedMarshaller setIdMapper(OptimizedMarshallerIdMapper mapper) {
+ this.mapper = mapper;
+
+ return this;
+ }
+
+ /**
+ * 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.
+ * @return {@code this} for chaining.
+ */
+ public OptimizedMarshaller setPoolSize(int poolSize) {
+ OptimizedObjectStreamRegistry.poolSize(poolSize);
+
+ return this;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void marshal0(@Nullable Object obj, OutputStream out) throws IgniteCheckedException {
+ assert out != null;
+
+ OptimizedObjectOutputStream objOut = null;
+
+ try {
+ objOut = OptimizedObjectStreamRegistry.out();
+
+ objOut.context(clsMap, ctx, mapper, requireSer);
+
+ objOut.out().outputStream(out);
+
+ objOut.writeObject(obj);
+ }
+ catch (IOException e) {
+ throw new IgniteCheckedException("Failed to serialize object: " + obj, e);
+ }
+ finally {
+ OptimizedObjectStreamRegistry.closeOut(objOut);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override protected byte[] marshal0(@Nullable Object obj) throws IgniteCheckedException {
+ OptimizedObjectOutputStream objOut = null;
+
+ try {
+ objOut = OptimizedObjectStreamRegistry.out();
+
+ objOut.context(clsMap, ctx, mapper, requireSer);
+
+ objOut.writeObject(obj);
+
+ return objOut.out().array();
+ }
+ catch (Exception e) {
+ throw new IgniteCheckedException("Failed to serialize object: " + obj, e);
+ }
+ finally {
+ OptimizedObjectStreamRegistry.closeOut(objOut);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @SuppressWarnings("unchecked")
+ @Override protected <T> T unmarshal0(InputStream in, @Nullable ClassLoader clsLdr) throws IgniteCheckedException {
+ assert in != null;
+
+ OptimizedObjectInputStream objIn = null;
+
+ try {
+ objIn = OptimizedObjectStreamRegistry.in();
+
+ objIn.context(clsMap, ctx, mapper, clsLdr != null ? clsLdr : dfltClsLdr);
+
+ objIn.in().inputStream(in);
+
+ return (T)objIn.readObject();
+ }
+ catch (ClassNotFoundException e) {
+ throw new IgniteCheckedException("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=" + clsLdr + ", cls=" + e.getMessage() + "]", e);
+ }
+ catch (Exception e) {
+ throw new IgniteCheckedException("Failed to deserialize object with given class loader: " + clsLdr, e);
+ }
+ finally {
+ OptimizedObjectStreamRegistry.closeIn(objIn);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @SuppressWarnings("unchecked")
+ @Override protected <T> T unmarshal0(byte[] arr, @Nullable ClassLoader clsLdr) throws IgniteCheckedException {
+ assert arr != null;
+
+ OptimizedObjectInputStream objIn = null;
+
+ try {
+ objIn = OptimizedObjectStreamRegistry.in();
+
+ objIn.context(clsMap, ctx, mapper, clsLdr != null ? clsLdr : dfltClsLdr);
+
+ objIn.in().bytes(arr, arr.length);
+
+ return (T)objIn.readObject();
+ }
+ catch (ClassNotFoundException e) {
+ throw new IgniteCheckedException("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=" + clsLdr + ", cls=" + e.getMessage() + "]", e);
+ }
+ catch (Exception e) {
+ throw new IgniteCheckedException("Failed to deserialize object with given class loader: " + clsLdr, e);
+ }
+ finally {
+ OptimizedObjectStreamRegistry.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 {
+ Class<? extends Unsafe> unsafeCls = Unsafe.class;
+
+ 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.
+ */
+ @Override public void onUndeploy(ClassLoader ldr) {
+ for (Class<?> cls : clsMap.keySet()) {
+ if (ldr.equals(cls.getClassLoader()))
+ clsMap.remove(cls);
+ }
+
+ U.clearClassCache(ldr);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/a1b5b8c3/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerIdMapper.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerIdMapper.java b/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerIdMapper.java
new file mode 100644
index 0000000..381e5d0
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerIdMapper.java
@@ -0,0 +1,33 @@
+/*
+ * 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.marshaller.optimized;
+
+/**
+ * ID mapper.
+ */
+public interface OptimizedMarshallerIdMapper {
+ /**
+ * Gets type ID for provided class name.
+ * <p>
+ * If {@code 0} is returned, hash code of class name will be used.
+ *
+ * @param clsName Class name.
+ * @return Type ID.
+ */
+ public int typeId(String clsName);
+}
\ No newline at end of file