IGNITE-141 - Marshallers refactoring
Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/61908d6d Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/61908d6d Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/61908d6d Branch: refs/heads/ignite-141 Commit: 61908d6d0cc68ac2da2c26e49a87ec5555139969 Parents: 706938d Author: Valentin Kulichenko <[email protected]> Authored: Fri Feb 27 19:34:54 2015 -0800 Committer: Valentin Kulichenko <[email protected]> Committed: Fri Feb 27 19:34:54 2015 -0800 ---------------------------------------------------------------------- .../CacheRendezvousAffinityFunction.java | 10 +-- .../apache/ignite/internal/IgniteKernal.java | 87 ++++++++++++++++++++ .../org/apache/ignite/internal/IgnitionEx.java | 56 ++++++++----- .../processors/cache/GridCacheContext.java | 2 +- .../processors/cache/GridCacheProcessor.java | 13 ++- .../processors/cache/GridCacheUtils.java | 18 +++- .../preloader/GridDhtPartitionDemandPool.java | 19 +++++ .../message/GridClientAbstractMessage.java | 1 - .../ignite/marshaller/AbstractMarshaller.java | 8 ++ .../apache/ignite/marshaller/Marshaller.java | 7 ++ .../ignite/marshaller/MarshallerContext.java | 39 +++++++++ .../optimized/OptimizedClassDescriptor.java | 71 ++++++++++------ .../optimized/OptimizedMarshaller.java | 4 + .../optimized/OptimizedMarshallerUtils.java | 83 ++++++++++++++----- .../optimized/OptimizedObjectInputStream.java | 18 ++-- .../optimized/OptimizedObjectOutputStream.java | 33 ++++---- .../marshaller/GridMarshallerAbstractTest.java | 15 ++-- .../jdk/GridJdkMarshallerSelfTest.java | 2 +- .../optimized/OptimizedMarshallerSelfTest.java | 10 +-- .../OptimizedObjectStreamSelfTest.java | 27 +++++- 20 files changed, 403 insertions(+), 120 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/61908d6d/modules/core/src/main/java/org/apache/ignite/cache/affinity/rendezvous/CacheRendezvousAffinityFunction.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/cache/affinity/rendezvous/CacheRendezvousAffinityFunction.java b/modules/core/src/main/java/org/apache/ignite/cache/affinity/rendezvous/CacheRendezvousAffinityFunction.java index f7bc2c5..38570ab 100644 --- a/modules/core/src/main/java/org/apache/ignite/cache/affinity/rendezvous/CacheRendezvousAffinityFunction.java +++ b/modules/core/src/main/java/org/apache/ignite/cache/affinity/rendezvous/CacheRendezvousAffinityFunction.java @@ -24,8 +24,7 @@ import org.apache.ignite.internal.*; import org.apache.ignite.internal.util.typedef.*; import org.apache.ignite.internal.util.typedef.internal.*; import org.apache.ignite.lang.*; -import org.apache.ignite.marshaller.*; -import org.apache.ignite.marshaller.optimized.*; +import org.apache.ignite.resources.*; import org.jetbrains.annotations.*; import java.io.*; @@ -91,8 +90,9 @@ public class CacheRendezvousAffinityFunction implements CacheAffinityFunction, E /** Hash ID resolver. */ private CacheAffinityNodeHashResolver hashIdRslvr = new CacheAffinityNodeAddressHashResolver(); - /** Marshaller. */ - private Marshaller marshaller = new OptimizedMarshaller(false); + /** Ignite instance. */ + @IgniteInstanceResource + private Ignite ignite; /** * Empty constructor with all defaults. @@ -291,7 +291,7 @@ public class CacheRendezvousAffinityFunction implements CacheAffinityFunction, E try { ByteArrayOutputStream out = new ByteArrayOutputStream(); - byte[] nodeHashBytes = marshaller.marshal(nodeHash); + byte[] nodeHashBytes = ignite.configuration().getMarshaller().marshal(nodeHash); out.write(nodeHashBytes, 0, nodeHashBytes.length); // Avoid IOException. out.write(U.intToBytes(part), 0, 4); // Avoid IOException. http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/61908d6d/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 8a21477..82ff680 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 @@ -678,6 +678,8 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable { igfsExecSvc, restExecSvc); + cfg.getMarshaller().setContext(new MarshallerContextImpl(ctx)); + cluster = new IgniteClusterImpl(ctx); U.onGridStart(); @@ -2717,4 +2719,89 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable { @Override public String toString() { return S.toString(IgniteKernal.class, this); } + + /** + */ + private static class MarshallerContextImpl implements MarshallerContext { + private final GridKernalContext ctx; + + /** */ + private GridCacheAdapter<Integer, String> cache; + + /** + * @param ctx Kernal context. + */ + private MarshallerContextImpl(GridKernalContext ctx) { + this.ctx = ctx; + } + + /** {@inheritDoc} */ + @Override public void registerClass(int id, String clsName) { + if (cache == null) + cache = ctx.cache().marshallerCache(); + + // TODO: IGNITE-141 - Do not create thread. + Thread t = new Thread(new MarshallerCacheUpdater(cache, id, clsName)); + + t.start(); + + try { + t.join(); + } + catch (InterruptedException e) { + throw new IgniteException(e); + } + } + + /** {@inheritDoc} */ + @Override public String className(int id) { + if (cache == null) + cache = ctx.cache().marshallerCache(); + + try { + return cache.get(id); + } + catch (IgniteCheckedException e) { + throw U.convertException(e); + } + } + } + + /** + */ + private static class MarshallerCacheUpdater implements Runnable { + /** */ + private final GridCacheAdapter<Integer, String> cache; + + /** */ + private final int typeId; + + /** */ + private final String clsName; + + /** + * @param cache Cache. + * @param typeId Type ID. + * @param clsName Class name. + */ + private MarshallerCacheUpdater(GridCacheAdapter<Integer, String> cache, int typeId, String clsName) { + this.cache = cache; + this.typeId = typeId; + this.clsName = clsName; + } + + /** {@inheritDoc} */ + @Override public void run() { + try { + String old = cache.putIfAbsent(typeId, clsName); + + // TODO: IGNITE-141 - proper message + if (old != null && !old.equals(clsName)) + throw new IgniteException("Collision."); + } + catch (IgniteCheckedException e) { + throw U.convertException(e); + } + } + } } http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/61908d6d/modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java b/modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java index 6503ed9..da21e3b 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java @@ -1693,11 +1693,15 @@ public class IgnitionEx { "\" because it is reserved for internal purposes."); if (CU.isUtilityCache(ccfg.getName())) - throw new IgniteCheckedException("Cache name cannot start with \"" + CU.UTILITY_CACHE_NAME + - "\" because this prefix is reserved for internal purposes."); + throw new IgniteCheckedException("Cache name cannot be \"" + CU.UTILITY_CACHE_NAME + + "\" because it is reserved for internal purposes."); + + if (CU.isMarshallerCache(ccfg.getName())) + throw new IgniteCheckedException("Cache name cannot be \"" + CU.MARSH_CACHE_NAME + + "\" because it is reserved for internal purposes."); } - int addCacheCnt = 1; // Always add utility cache. + int addCacheCnt = 2; // Always add marshaller and utility caches. if (hasHadoop) addCacheCnt++; @@ -1707,7 +1711,7 @@ public class IgnitionEx { copies = new CacheConfiguration[cacheCfgs.length + addCacheCnt]; - int cloneIdx = 1; + int cloneIdx = 2; if (hasHadoop) copies[cloneIdx++] = CU.hadoopSystemCache(); @@ -1719,7 +1723,7 @@ public class IgnitionEx { copies[cloneIdx++] = new CacheConfiguration(ccfg); } else { - int cacheCnt = 1; // Always add utility cache. + int cacheCnt = 2; // Always add marshaller and utility caches. if (hasHadoop) cacheCnt++; @@ -1729,7 +1733,7 @@ public class IgnitionEx { copies = new CacheConfiguration[cacheCnt]; - int cacheIdx = 1; + int cacheIdx = 2; if (hasHadoop) copies[cacheIdx++] = CU.hadoopSystemCache(); @@ -1738,24 +1742,14 @@ public class IgnitionEx { copies[cacheIdx] = atomicsSystemCache(cfg.getAtomicConfiguration(), clientDisco); } - // Always add utility cache. - copies[0] = utilitySystemCache(clientDisco); + // Always add marshaller and utility caches. + copies[0] = marshallerSystemCache(clientDisco); + copies[1] = utilitySystemCache(clientDisco); myCfg.setCacheConfiguration(copies); myCfg.setCacheSanityCheckEnabled(cfg.isCacheSanityCheckEnabled()); - try { - // Use reflection to avoid loading undesired classes. - Class helperCls = Class.forName("org.apache.ignite.util.GridConfigurationHelper"); - - helperCls.getMethod("overrideConfiguration", IgniteConfiguration.class, Properties.class, - String.class, IgniteLogger.class).invoke(helperCls, myCfg, System.getProperties(), name, log); - } - catch (Exception ignored) { - // No-op. - } - // Ensure that SPIs support multiple grid instances, if required. if (!startCtx.single()) { ensureMultiInstanceSupport(deploySpi); @@ -1920,6 +1914,30 @@ public class IgnitionEx { } /** + * Creates marshaller system cache configuration. + * + * @param client If {@code true} creates client-only cache configuration. + * @return Marshaller system cache configuration. + */ + private static CacheConfiguration marshallerSystemCache(boolean client) { + CacheConfiguration cache = new CacheConfiguration(); + + cache.setName(CU.MARSH_CACHE_NAME); + cache.setCacheMode(REPLICATED); + cache.setAtomicityMode(TRANSACTIONAL); + cache.setSwapEnabled(false); + cache.setQueryIndexEnabled(false); + cache.setPreloadMode(SYNC); + cache.setWriteSynchronizationMode(FULL_SYNC); + cache.setAffinity(new CacheRendezvousAffinityFunction(false, 100)); + + if (client) + cache.setDistributionMode(CLIENT_ONLY); + + return cache; + } + + /** * Creates utility system cache configuration. * * @param client If {@code true} creates client-only cache configuration. http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/61908d6d/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java index 3ec013c..9f570ae 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java @@ -308,7 +308,7 @@ public class GridCacheContext<K, V> implements Externalizable { else cacheId = 1; - sys = CU.UTILITY_CACHE_NAME.equals(cacheName); + sys = CU.MARSH_CACHE_NAME.equals(cacheName) || CU.UTILITY_CACHE_NAME.equals(cacheName); plc = sys ? UTILITY_CACHE_POOL : SYSTEM_POOL; http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/61908d6d/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java index e99c706..97ec4d2 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java @@ -57,14 +57,14 @@ import java.util.*; import static org.apache.ignite.IgniteSystemProperties.*; import static org.apache.ignite.cache.CacheAtomicityMode.*; -import static org.apache.ignite.configuration.CacheConfiguration.*; import static org.apache.ignite.cache.CacheDistributionMode.*; import static org.apache.ignite.cache.CacheMode.*; import static org.apache.ignite.cache.CachePreloadMode.*; import static org.apache.ignite.cache.CacheWriteSynchronizationMode.*; +import static org.apache.ignite.configuration.CacheConfiguration.*; import static org.apache.ignite.configuration.DeploymentMode.*; -import static org.apache.ignite.internal.IgniteNodeAttributes.*; import static org.apache.ignite.internal.IgniteComponentType.*; +import static org.apache.ignite.internal.IgniteNodeAttributes.*; import static org.apache.ignite.internal.processors.cache.GridCacheUtils.*; import static org.apache.ignite.transactions.TransactionIsolation.*; @@ -571,8 +571,8 @@ public class GridCacheProcessor extends GridProcessorAdapter { if (IgniteComponentType.HADOOP.inClassPath()) sysCaches.add(CU.SYS_CACHE_HADOOP_MR); + sysCaches.add(CU.MARSH_CACHE_NAME); sysCaches.add(CU.UTILITY_CACHE_NAME); - sysCaches.add(CU.ATOMICS_CACHE_NAME); CacheConfiguration[] cfgs = ctx.config().getCacheConfiguration(); @@ -1576,6 +1576,13 @@ public class GridCacheProcessor extends GridProcessorAdapter { } /** + * @return Marshaller system cache. + */ + public GridCacheAdapter<Integer, String> marshallerCache() { + return internalCache(CU.MARSH_CACHE_NAME); + } + + /** * Gets utility cache. * * @param keyCls Key class. http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/61908d6d/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java index 1e67907..611d1e8 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java @@ -69,6 +69,9 @@ public class GridCacheUtils { /** Atomics system cache name. */ public static final String ATOMICS_CACHE_NAME = "ignite-atomics-sys-cache"; + /** Marshaller system cache name. */ + public static final String MARSH_CACHE_NAME = "ignite-marshaller-sys-cache"; + /** Default mask name. */ private static final String DEFAULT_MASK_NAME = "<default>"; @@ -1519,7 +1522,15 @@ public class GridCacheUtils { /** * @param cacheName Cache name. - * @return {@code True} if this is security system cache. + * @return {@code True} if this is marshaller system cache. + */ + public static boolean isMarshallerCache(String cacheName) { + return MARSH_CACHE_NAME.equals(cacheName); + } + + /** + * @param cacheName Cache name. + * @return {@code True} if this is utility system cache. */ public static boolean isUtilityCache(String cacheName) { return UTILITY_CACHE_NAME.equals(cacheName); @@ -1527,7 +1538,7 @@ public class GridCacheUtils { /** * @param cacheName Cache name. - * @return {@code True} if this is security system cache. + * @return {@code True} if this is atomics system cache. */ public static boolean isAtomicsCache(String cacheName) { return ATOMICS_CACHE_NAME.equals(cacheName); @@ -1538,7 +1549,8 @@ public class GridCacheUtils { * @return {@code True} if system cache. */ public static boolean isSystemCache(String cacheName) { - return isUtilityCache(cacheName) || isHadoopSystemCache(cacheName) || isAtomicsCache(cacheName); + return isMarshallerCache(cacheName) || isUtilityCache(cacheName) || isHadoopSystemCache(cacheName) || + isAtomicsCache(cacheName); } /** http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/61908d6d/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionDemandPool.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionDemandPool.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionDemandPool.java index 6a1f7a1..b683670 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionDemandPool.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionDemandPool.java @@ -809,6 +809,25 @@ public class GridDhtPartitionDemandPool<K, V> { /** {@inheritDoc} */ @Override protected void body() throws InterruptedException, IgniteInterruptedCheckedException { try { + if (!CU.isMarshallerCache(cctx.name())) { + if (log.isDebugEnabled()) + log.debug("Waiting for marshaller cache preload [cacheName=" + cctx.name() + ']'); + + try { + cctx.kernalContext().cache().marshallerCache().preloader().syncFuture().get(); + } + catch (IgniteInterruptedCheckedException e) { + if (log.isDebugEnabled()) + log.debug("Failed to wait for marshaller cache preload future (grid is stopping): " + + "[cacheName=" + cctx.name() + ']'); + + return; + } + catch (IgniteCheckedException e) { + throw new Error("Ordered preload future should never fail: " + e.getMessage(), e); + } + } + int preloadOrder = cctx.config().getPreloadOrder(); if (preloadOrder > 0) { http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/61908d6d/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/client/message/GridClientAbstractMessage.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/client/message/GridClientAbstractMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/client/message/GridClientAbstractMessage.java index 495b3cf..c6557bc 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/client/message/GridClientAbstractMessage.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/client/message/GridClientAbstractMessage.java @@ -17,7 +17,6 @@ package org.apache.ignite.internal.processors.rest.client.message; -import org.apache.ignite.internal.util.*; import org.apache.ignite.internal.util.typedef.internal.*; import java.io.*; http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/61908d6d/modules/core/src/main/java/org/apache/ignite/marshaller/AbstractMarshaller.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/AbstractMarshaller.java b/modules/core/src/main/java/org/apache/ignite/marshaller/AbstractMarshaller.java index 4ac4005..fd08a02 100644 --- a/modules/core/src/main/java/org/apache/ignite/marshaller/AbstractMarshaller.java +++ b/modules/core/src/main/java/org/apache/ignite/marshaller/AbstractMarshaller.java @@ -33,6 +33,14 @@ public abstract class AbstractMarshaller implements Marshaller { /** Default initial buffer size for the {@link GridByteArrayOutputStream}. */ public static final int DFLT_BUFFER_SIZE = 512; + /** Context. */ + protected MarshallerContext ctx; + + /** {@inheritDoc} */ + @Override public void setContext(MarshallerContext ctx) { + this.ctx = ctx; + } + /** {@inheritDoc} */ @Override public byte[] marshal(@Nullable Object obj) throws IgniteCheckedException { GridByteArrayOutputStream out = null; http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/61908d6d/modules/core/src/main/java/org/apache/ignite/marshaller/Marshaller.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/Marshaller.java b/modules/core/src/main/java/org/apache/ignite/marshaller/Marshaller.java index e2956dd..127a53c 100644 --- a/modules/core/src/main/java/org/apache/ignite/marshaller/Marshaller.java +++ b/modules/core/src/main/java/org/apache/ignite/marshaller/Marshaller.java @@ -66,6 +66,13 @@ import java.io.*; */ public interface Marshaller { /** + * Sets marshaller context. + * + * @param ctx Marshaller context. + */ + public void setContext(MarshallerContext ctx); + + /** * Marshals object to the output stream. This method should not close * given output stream. * http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/61908d6d/modules/core/src/main/java/org/apache/ignite/marshaller/MarshallerContext.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/MarshallerContext.java b/modules/core/src/main/java/org/apache/ignite/marshaller/MarshallerContext.java new file mode 100644 index 0000000..b499c05 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/marshaller/MarshallerContext.java @@ -0,0 +1,39 @@ +/* + * 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; + +/** + * Marshaller context. + */ +public interface MarshallerContext { + /** + * Registers class name for provided type ID. + * + * @param id Type ID. + * @param clsName Class name. + */ + public void registerClass(int id, String clsName); + + /** + * Gets class name for provided type ID. + * + * @param id Type ID. + * @return Class name. + */ + public String className(int id); +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/61908d6d/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedClassDescriptor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedClassDescriptor.java b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedClassDescriptor.java index 90ac2d1..7c3c205 100644 --- a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedClassDescriptor.java +++ b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedClassDescriptor.java @@ -132,8 +132,14 @@ class OptimizedClassDescriptor { /** Class. */ private Class<?> cls; + /** Context. */ + private MarshallerContext ctx; + + /** Type ID. */ + private int typeId; + /** Short ID. */ - private Short shortId; + private short checksum; /** Class name. */ private String name; @@ -196,11 +202,16 @@ class OptimizedClassDescriptor { * Creates descriptor for class. * * @param cls Class. + * @param ctx Context. * @throws IOException In case of error. */ - @SuppressWarnings({"ForLoopReplaceableByForEach", "MapReplaceableByEnumMap"}) - OptimizedClassDescriptor(Class<?> cls) throws IOException { + @SuppressWarnings("ForLoopReplaceableByForEach") + OptimizedClassDescriptor(Class<?> cls, MarshallerContext ctx) throws IOException { this.cls = cls; + this.ctx = ctx; + + // TODO: IGNITE-141 - resolve + typeId = cls.getName().hashCode(); excluded = MarshallerExclusions.isExcluded(cls); @@ -396,7 +407,9 @@ class OptimizedClassDescriptor { type = TYPE_EXTERNALIZABLE; try { - constructor = cls.getDeclaredConstructor(); + constructor = !Modifier.isStatic(cls.getModifiers()) && cls.getDeclaringClass() != null ? + cls.getDeclaredConstructor(cls.getDeclaringClass()) : + cls.getDeclaredConstructor(); constructor.setAccessible(true); } @@ -548,7 +561,7 @@ class OptimizedClassDescriptor { } } - shortId = OptimizedMarshallerUtils.computeSerialVersionUid(cls, fields != null ? fields.ownFields() : null).shortValue(); + checksum = OptimizedMarshallerUtils.computeSerialVersionUid(cls, fields != null ? fields.ownFields() : null); } /** @@ -566,24 +579,10 @@ class OptimizedClassDescriptor { } /** - * @return Short ID. + * @return Type ID. */ - Short shortId() { - return shortId; - } - - /** - * @return Class name. - */ - String name() { - return name; - } - - /** - * @return Array component type. - */ - Class<?> componentType() { - return arrCompType; + int typeId() { + return typeId; } /** @@ -636,8 +635,6 @@ class OptimizedClassDescriptor { */ @SuppressWarnings("ForLoopReplaceableByForEach") void write(OptimizedObjectOutputStream out, Object obj) throws IOException { - out.writeInt(cls.getName().hashCode()); - switch (type) { case TYPE_BYTE: out.writeByte((Byte)obj); @@ -780,11 +777,15 @@ class OptimizedClassDescriptor { break; case TYPE_CLS: - out.writeInt(((Class<?>)obj).getName().hashCode()); + // TODO: IGNITE-141 - Do not acquire descriptor? + OptimizedClassDescriptor desc = OptimizedMarshallerUtils.classDescriptor((Class<?>)obj, ctx); + + out.writeInt(desc.typeId()); break; case TYPE_EXTERNALIZABLE: + out.writeShort(checksum); out.writeExternalizable(obj); break; @@ -795,6 +796,7 @@ class OptimizedClassDescriptor { "set OptimizedMarshaller.setRequireSerializable() to false " + "(note that performance may degrade if object is not Serializable): " + name); + out.writeShort(checksum); out.writeSerializable(obj, writeObjMtds, fields); break; @@ -899,12 +901,17 @@ class OptimizedClassDescriptor { return in.readDate(); case TYPE_CLS: - return null; // TODO: IGNITE-141 + // TODO: IGNITE-141 - Do not acquire descriptor? + return OptimizedMarshallerUtils.classDescriptor(in.readInt(), in.classLoader(), ctx).describedClass(); case TYPE_EXTERNALIZABLE: + verifyChecksum(in.readShort()); + return in.readExternalizable(constructor, readResolveMtd); case TYPE_SERIALIZABLE: + verifyChecksum(in.readShort()); + return in.readSerializable(cls, readObjMtds, readResolveMtd, fields); default: @@ -913,6 +920,18 @@ class OptimizedClassDescriptor { } /** + * @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. */ http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/61908d6d/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshaller.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshaller.java b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshaller.java index 1e7f802..f107c08 100644 --- a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshaller.java +++ b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshaller.java @@ -137,6 +137,7 @@ public class OptimizedMarshaller extends AbstractMarshaller { try { objOut = OptimizedObjectStreamRegistry.out(); + objOut.context(ctx); objOut.requireSerializable(requireSer); objOut.out().outputStream(out); @@ -158,6 +159,7 @@ public class OptimizedMarshaller extends AbstractMarshaller { try { objOut = OptimizedObjectStreamRegistry.out(); + objOut.context(ctx); objOut.requireSerializable(requireSer); objOut.writeObject(obj); @@ -181,6 +183,7 @@ public class OptimizedMarshaller extends AbstractMarshaller { try { objIn = OptimizedObjectStreamRegistry.in(); + objIn.context(ctx); objIn.classLoader(clsLdr != null ? clsLdr : dfltClsLdr); objIn.in().inputStream(in); @@ -209,6 +212,7 @@ public class OptimizedMarshaller extends AbstractMarshaller { try { objIn = OptimizedObjectStreamRegistry.in(); + objIn.context(ctx); objIn.classLoader(clsLdr != null ? clsLdr : dfltClsLdr); objIn.in().bytes(arr, arr.length); http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/61908d6d/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerUtils.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerUtils.java b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerUtils.java index 7bc606a..df0e149 100644 --- a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerUtils.java +++ b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerUtils.java @@ -17,8 +17,17 @@ package org.apache.ignite.marshaller.optimized; +import org.apache.ignite.internal.processors.cache.*; +import org.apache.ignite.internal.processors.cache.distributed.*; +import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.*; +import org.apache.ignite.internal.processors.cache.transactions.*; +import org.apache.ignite.internal.processors.cache.version.*; import org.apache.ignite.internal.util.*; +import org.apache.ignite.internal.util.lang.*; import org.apache.ignite.internal.util.typedef.*; +import org.apache.ignite.internal.util.typedef.internal.*; +import org.apache.ignite.lang.*; +import org.apache.ignite.marshaller.*; import org.jdk8.backport.*; import sun.misc.*; @@ -48,13 +57,40 @@ class OptimizedMarshallerUtils { /** UTF-8 character name. */ static final Charset UTF_8 = Charset.forName("UTF-8"); + /** Predefined classes. */ + private static final Class<?>[] PREDEFINED = new Class[] { + byte[].class, + Integer.class, + String.class, + UUID.class, + ArrayList.class, + LinkedList.class, + HashSet.class, + HashMap.class, + + GridDhtPartitionMap.class, + GridDhtPartitionFullMap.class, + GridCacheMvccCandidate.class, + GridCacheVersion.class, + IgniteTxEntry.class, + IgnitePredicate[].class, + IgniteExternalizableExpiryPolicy.class, + IgniteTxKey.class, + GridCacheReturn.class, + GridTuple4.class, + GridCacheEntryInfo.class + }; + /** Class descriptors by class. */ - private static final ConcurrentMap<Class<?>, OptimizedClassDescriptor> DESC_BY_CLS = - new ConcurrentHashMap8<>(256); + private static final ConcurrentMap<Class<?>, OptimizedClassDescriptor> DESC_BY_CLS = new ConcurrentHashMap8<>(256); + + /** Classes by ID. */ + private static final ConcurrentMap<Integer, Class<?>> CLS_BY_ID = new ConcurrentHashMap8<>(256); - /** Class descriptors by ID. */ - private static final ConcurrentMap<Integer, OptimizedClassDescriptor> DESC_BY_ID = - new ConcurrentHashMap8<>(256); + static { + for (Class<?> cls : PREDEFINED) + CLS_BY_ID.put(cls.getName().hashCode(), cls); + } /** */ @@ -66,16 +102,20 @@ class OptimizedMarshallerUtils { * Gets descriptor for provided class. * * @param cls Class. + * @param ctx Context. * @return Descriptor. * @throws IOException In case of error. */ - static OptimizedClassDescriptor classDescriptor(Class<?> cls) throws IOException { + static OptimizedClassDescriptor classDescriptor(Class<?> cls, MarshallerContext ctx) throws IOException { OptimizedClassDescriptor desc = DESC_BY_CLS.get(cls); if (desc == null) { - // TODO: IGNITE-141 - Put to cache. + desc = new OptimizedClassDescriptor(cls, ctx); + + if (CLS_BY_ID.putIfAbsent(desc.typeId(), cls) == null) + ctx.registerClass(desc.typeId(), cls.getName()); - OptimizedClassDescriptor old = DESC_BY_CLS.putIfAbsent(cls, desc = new OptimizedClassDescriptor(cls)); + OptimizedClassDescriptor old = DESC_BY_CLS.putIfAbsent(cls, desc); if (old != null) desc = old; @@ -89,27 +129,29 @@ class OptimizedMarshallerUtils { * * @param id ID. * @param ldr Class loader. + * @param ctx Context. * @return Descriptor. * @throws IOException In case of error. * @throws ClassNotFoundException If class was not found. */ - static OptimizedClassDescriptor classDescriptor(int id, ClassLoader ldr) + static OptimizedClassDescriptor classDescriptor(int id, ClassLoader ldr, MarshallerContext ctx) throws IOException, ClassNotFoundException { - OptimizedClassDescriptor desc = DESC_BY_ID.get(id); + Class<?> cls = CLS_BY_ID.get(id); - if (desc == null) { - // TODO: IGNITE-141 - Get from cache. - String clsName = null; + if (cls == null) { + String clsName = ctx.className(id); + + assert clsName != null : id; - Class<?> cls = Class.forName(clsName, true, ldr); + cls = U.forName(clsName, ldr); - OptimizedClassDescriptor old = DESC_BY_ID.putIfAbsent(id, desc = new OptimizedClassDescriptor(cls)); + Class<?> old = CLS_BY_ID.putIfAbsent(id, cls); if (old != null) - desc = old; + cls = old; } - return desc; + return classDescriptor(cls, ctx); } /** @@ -129,7 +171,6 @@ class OptimizedMarshallerUtils { */ public static void clearCache() { DESC_BY_CLS.clear(); - DESC_BY_ID.clear(); } /** @@ -142,9 +183,9 @@ class OptimizedMarshallerUtils { * @throws IOException If failed. */ @SuppressWarnings("ForLoopReplaceableByForEach") - static Long computeSerialVersionUid(Class cls, List<Field> fields) throws IOException { + static short computeSerialVersionUid(Class cls, List<Field> fields) throws IOException { if (Serializable.class.isAssignableFrom(cls) && !Enum.class.isAssignableFrom(cls)) - return ObjectStreamClass.lookup(cls).getSerialVersionUID(); + return (short)ObjectStreamClass.lookup(cls).getSerialVersionUID(); MessageDigest md; @@ -174,7 +215,7 @@ class OptimizedMarshallerUtils { for (int i = Math.min(hashBytes.length, 8) - 1; i >= 0; i--) hash = (hash << 8) | (hashBytes[i] & 0xFF); - return hash; + return (short)hash; } /** http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/61908d6d/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectInputStream.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectInputStream.java b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectInputStream.java index 6b07e08..ad10638 100644 --- a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectInputStream.java +++ b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectInputStream.java @@ -22,6 +22,7 @@ import org.apache.ignite.internal.util.io.*; import org.apache.ignite.internal.util.typedef.*; import org.apache.ignite.internal.util.typedef.internal.*; import org.apache.ignite.lang.*; +import org.apache.ignite.marshaller.*; import sun.misc.*; import java.io.*; @@ -44,6 +45,9 @@ class OptimizedObjectInputStream extends ObjectInputStream { private final HandleTable handles = new HandleTable(10); /** */ + private MarshallerContext ctx; + + /** */ private ClassLoader clsLdr; /** */ @@ -73,10 +77,10 @@ class OptimizedObjectInputStream extends ObjectInputStream { } /** - * @throws IOException In case of error. + * @param ctx Context. */ - OptimizedObjectInputStream() throws IOException { - // No-op. + void context(MarshallerContext ctx) { + this.ctx = ctx; } /** @@ -143,9 +147,9 @@ class OptimizedObjectInputStream extends ObjectInputStream { return handles.lookup(readInt()); case OBJECT: - int clsId = readInt(); + int typeId = readInt(); - OptimizedClassDescriptor desc = OptimizedMarshallerUtils.classDescriptor(clsId, clsLdr); + OptimizedClassDescriptor desc = OptimizedMarshallerUtils.classDescriptor(typeId, clsLdr, ctx); curCls = desc.describedClass(); @@ -174,6 +178,7 @@ class OptimizedObjectInputStream extends ObjectInputStream { * @throws ClassNotFoundException If class not found. * @throws IOException In case of error. */ + @SuppressWarnings("unchecked") <T> T[] readArray(Class<T> compType) throws ClassNotFoundException, IOException { int len = in.readInt(); @@ -438,6 +443,7 @@ class OptimizedObjectInputStream extends ObjectInputStream { * @throws ClassNotFoundException If class not found. * @throws IOException In case of error. */ + @SuppressWarnings("unchecked") HashSet<?> readHashSet(long mapFieldOff) throws ClassNotFoundException, IOException { try { HashSet<Object> set = (HashSet<Object>)UNSAFE.allocateInstance(HashSet.class); @@ -509,6 +515,7 @@ class OptimizedObjectInputStream extends ObjectInputStream { * @throws ClassNotFoundException If class not found. * @throws IOException In case of error. */ + @SuppressWarnings("unchecked") LinkedHashSet<?> readLinkedHashSet(long mapFieldOff) throws ClassNotFoundException, IOException { try { LinkedHashSet<Object> set = (LinkedHashSet<Object>)UNSAFE.allocateInstance(LinkedHashSet.class); @@ -1013,6 +1020,7 @@ class OptimizedObjectInputStream extends ObjectInputStream { * @param dflt Default value. * @return Value. */ + @SuppressWarnings("unchecked") private <T> T value(String name, T dflt) { return objs[fieldInfoMap.get(name).get1()] != null ? (T)objs[fieldInfoMap.get(name).get1()] : dflt; } http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/61908d6d/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectOutputStream.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectOutputStream.java b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectOutputStream.java index 507dde6..fdcb78d 100644 --- a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectOutputStream.java +++ b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectOutputStream.java @@ -21,6 +21,7 @@ import org.apache.ignite.internal.util.*; import org.apache.ignite.internal.util.io.*; import org.apache.ignite.internal.util.typedef.*; import org.apache.ignite.lang.*; +import org.apache.ignite.marshaller.*; import java.io.*; import java.lang.reflect.*; @@ -43,10 +44,13 @@ class OptimizedObjectOutputStream extends ObjectOutputStream { private final GridHandleTable handles = new GridHandleTable(10, 3.00f); /** */ - private boolean requireSer; + private final GridDataOutput out; /** */ - private GridDataOutput out; + private MarshallerContext ctx; + + /** */ + private boolean requireSer; /** */ private Object curObj; @@ -60,20 +64,19 @@ class OptimizedObjectOutputStream extends ObjectOutputStream { /** */ private PutFieldImpl curPut; - /** + * @param out Output. * @throws IOException In case of error. */ - OptimizedObjectOutputStream() throws IOException { - // No-op. + OptimizedObjectOutputStream(GridDataOutput out) throws IOException { + this.out = out; } /** - * @param out Output. - * @throws IOException In case of error. + * @param ctx Context. */ - OptimizedObjectOutputStream(GridDataOutput out) throws IOException { - this.out = out; + void context(MarshallerContext ctx) { + this.ctx = ctx; } /** @@ -91,13 +94,6 @@ class OptimizedObjectOutputStream extends ObjectOutputStream { } /** - * @param out Output. - */ - public void out(GridDataOutput out) { - this.out = out; - } - - /** * @return Output. */ public GridDataOutput out() { @@ -156,7 +152,7 @@ class OptimizedObjectOutputStream extends ObjectOutputStream { else { Class<?> cls = obj.getClass(); - OptimizedClassDescriptor desc = classDescriptor(cls); + OptimizedClassDescriptor desc = classDescriptor(cls, ctx); if (desc.excluded()) { writeByte(NULL); @@ -180,7 +176,7 @@ class OptimizedObjectOutputStream extends ObjectOutputStream { if (obj0 != obj) { obj = obj0; - desc = classDescriptor(obj.getClass()); + desc = classDescriptor(obj.getClass(), ctx); } if (handle >= 0) { @@ -189,6 +185,7 @@ class OptimizedObjectOutputStream extends ObjectOutputStream { } else { writeByte(OBJECT); + writeInt(desc.typeId()); desc.write(this, obj); } http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/61908d6d/modules/core/src/test/java/org/apache/ignite/marshaller/GridMarshallerAbstractTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/marshaller/GridMarshallerAbstractTest.java b/modules/core/src/test/java/org/apache/ignite/marshaller/GridMarshallerAbstractTest.java index 28985c3..5e4cbd6 100644 --- a/modules/core/src/test/java/org/apache/ignite/marshaller/GridMarshallerAbstractTest.java +++ b/modules/core/src/test/java/org/apache/ignite/marshaller/GridMarshallerAbstractTest.java @@ -31,7 +31,6 @@ import org.apache.ignite.internal.processors.streamer.*; import org.apache.ignite.internal.util.*; import org.apache.ignite.internal.util.typedef.*; import org.apache.ignite.lang.*; -import org.apache.ignite.marshaller.optimized.*; import org.apache.ignite.p2p.*; import org.apache.ignite.streamer.*; import org.apache.ignite.streamer.window.*; @@ -103,7 +102,7 @@ public abstract class GridMarshallerAbstractTest extends GridCommonAbstractTest namedCache.setAtomicityMode(TRANSACTIONAL); namedCache.setQueryIndexEnabled(true); - cfg.setMarshaller(new OptimizedMarshaller(false)); + cfg.setMarshaller(marshaller()); cfg.setStreamerConfiguration(streamerConfiguration()); cfg.setCacheConfiguration(new CacheConfiguration(), namedCache); @@ -111,6 +110,11 @@ public abstract class GridMarshallerAbstractTest extends GridCommonAbstractTest } /** + * @return Marshaller. + */ + protected abstract Marshaller marshaller(); + + /** * @return Streamer configuration. */ private static StreamerConfiguration streamerConfiguration() { @@ -136,14 +140,9 @@ public abstract class GridMarshallerAbstractTest extends GridCommonAbstractTest return cfg; } - /** - * @return Grid marshaller. - */ - protected abstract Marshaller createMarshaller(); - /** {@inheritDoc} */ @Override protected void beforeTest() throws Exception { - marsh = createMarshaller(); + marsh = grid().configuration().getMarshaller(); } /** http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/61908d6d/modules/core/src/test/java/org/apache/ignite/marshaller/jdk/GridJdkMarshallerSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/marshaller/jdk/GridJdkMarshallerSelfTest.java b/modules/core/src/test/java/org/apache/ignite/marshaller/jdk/GridJdkMarshallerSelfTest.java index 19e871c..245cc7f 100644 --- a/modules/core/src/test/java/org/apache/ignite/marshaller/jdk/GridJdkMarshallerSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/marshaller/jdk/GridJdkMarshallerSelfTest.java @@ -27,7 +27,7 @@ import org.apache.ignite.testframework.junits.common.*; @GridCommonTest(group = "Marshaller") public class GridJdkMarshallerSelfTest extends GridMarshallerAbstractTest { /** {@inheritDoc} */ - @Override protected Marshaller createMarshaller() { + @Override protected Marshaller marshaller() { return new JdkMarshaller(); } } http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/61908d6d/modules/core/src/test/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerSelfTest.java b/modules/core/src/test/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerSelfTest.java index 1d0967f..2cb1b2d 100644 --- a/modules/core/src/test/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerSelfTest.java @@ -32,12 +32,8 @@ import java.util.concurrent.*; @GridCommonTest(group = "Marshaller") public class OptimizedMarshallerSelfTest extends GridMarshallerAbstractTest { /** {@inheritDoc} */ - @Override protected Marshaller createMarshaller() { - OptimizedMarshaller m = new OptimizedMarshaller(); - - m.setRequireSerializable(false); - - return m; + @Override protected Marshaller marshaller() { + return new OptimizedMarshaller(false); } /** @@ -46,8 +42,6 @@ public class OptimizedMarshallerSelfTest extends GridMarshallerAbstractTest { public void testTestMarshalling() throws Exception { final String msg = "PASSED"; - assert msg != null; - byte[] buf = marshal(new IgniteRunnable() { @Override public void run() { c1.apply(msg); http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/61908d6d/modules/core/src/test/java/org/apache/ignite/marshaller/optimized/OptimizedObjectStreamSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/marshaller/optimized/OptimizedObjectStreamSelfTest.java b/modules/core/src/test/java/org/apache/ignite/marshaller/optimized/OptimizedObjectStreamSelfTest.java index 83e9aba..3d8ea96 100644 --- a/modules/core/src/test/java/org/apache/ignite/marshaller/optimized/OptimizedObjectStreamSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/marshaller/optimized/OptimizedObjectStreamSelfTest.java @@ -39,6 +39,9 @@ import static org.junit.Assert.*; * Test for optimized object streams. */ public class OptimizedObjectStreamSelfTest extends GridCommonAbstractTest { + /** */ + private static final MarshallerContext CTX = new MarshallerContextImpl(); + /** * @throws Exception If failed. */ @@ -216,7 +219,11 @@ public class OptimizedObjectStreamSelfTest extends GridCommonAbstractTest { */ public void testRequireSerializable() throws Exception { try { - new OptimizedMarshaller(true).marshal(new Object()); + OptimizedMarshaller marsh = new OptimizedMarshaller(true); + + marsh.setContext(CTX); + + marsh.marshal(new Object()); assert false : "Exception not thrown."; } @@ -994,6 +1001,7 @@ public class OptimizedObjectStreamSelfTest extends GridCommonAbstractTest { try { out = OptimizedObjectStreamRegistry.out(); + out.context(CTX); out.requireSerializable(true); out.writeObject(obj); @@ -1002,6 +1010,7 @@ public class OptimizedObjectStreamSelfTest extends GridCommonAbstractTest { in = OptimizedObjectStreamRegistry.in(); + in.context(CTX); in.classLoader(getClass().getClassLoader()); in.in().bytes(arr, arr.length); @@ -1044,6 +1053,22 @@ public class OptimizedObjectStreamSelfTest extends GridCommonAbstractTest { } /** */ + private static class MarshallerContextImpl implements MarshallerContext { + /** */ + private final Map<Integer, String> map = new HashMap<>(); + + /** {@inheritDoc} */ + @Override public void registerClass(int id, String clsName) { + map.put(id, clsName); + } + + /** {@inheritDoc} */ + @Override public String className(int id) { + return map.get(id); + } + } + + /** */ private static class IncorrectExternalizable implements Externalizable { /** * Required by {@link Externalizable}.
