Repository: ignite Updated Branches: refs/heads/ignite-1272 787347a98 -> 9c93f8bc7
ignite-1272: storing user portable class descriptors only for classes that are loaded by default class loader Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/9c93f8bc Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/9c93f8bc Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/9c93f8bc Branch: refs/heads/ignite-1272 Commit: 9c93f8bc747ab73acd6e8fad75ba2e0ed56cc217 Parents: 787347a Author: Denis Magda <dma...@gridgain.com> Authored: Wed Oct 7 10:54:46 2015 +0300 Committer: Denis Magda <dma...@gridgain.com> Committed: Wed Oct 7 10:54:46 2015 +0300 ---------------------------------------------------------------------- .../internal/portable/PortableContext.java | 90 +++++--------------- 1 file changed, 23 insertions(+), 67 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/9c93f8bc/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java index d5a3c5d..0c762dd 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java @@ -112,9 +112,8 @@ public class PortableContext implements Externalizable { /** */ private final ConcurrentMap<Class<?>, PortableClassDescriptor> descByCls = new ConcurrentHashMap8<>(); - /** */ - private final ConcurrentMap<ClassLoader, ConcurrentMap<Integer, PortableClassDescriptor>> userTypes - = new ConcurrentHashMap8<>(0); + /** Holds classes loaded by default class loader only. */ + private final ConcurrentMap<Integer, PortableClassDescriptor> userTypes = new ConcurrentHashMap8<>(); /** */ private final Map<Integer, PortableClassDescriptor> predefinedTypes = new HashMap<>(); @@ -129,7 +128,7 @@ public class PortableContext implements Externalizable { private final Map<Class<? extends Map>, Byte> mapTypes = new HashMap<>(); /** */ - private final Map<Integer, PortableIdMapper> mappers = new ConcurrentHashMap8<>(0); + private final ConcurrentMap<Integer, PortableIdMapper> mappers = new ConcurrentHashMap8<>(0); /** */ private final Map<String, PortableIdMapper> typeMappers = new ConcurrentHashMap8<>(0); @@ -468,12 +467,12 @@ public class PortableContext implements Externalizable { if (ldr == null) ldr = dfltLdr; - if (userType) { - desc = userTypesMap(ldr).get(typeId); + // If the type hasn't been loaded by default class loader then we mustn't return the descriptor from here + // giving a chance to a custom class loader to reload type's class. + if (userType && ldr.equals(dfltLdr)) { + desc = userTypes.get(typeId); - // If the type hasn't been loaded by default class loader then we mustn't return the descriptor from here - // giving a chance to a custom class loader to reload type's class. - if (desc != null && ldr.equals(dfltLdr)) + if (desc != null) return desc; } @@ -485,13 +484,15 @@ public class PortableContext implements Externalizable { desc = descByCls.get(cls); } catch (ClassNotFoundException e) { - if (userType && !ldr.equals(dfltLdr) && (desc = descriptorLoadingFailover(typeId, ldr)) != null) + // Class might have been loaded by default class loader. + if (userType && !ldr.equals(dfltLdr) && (desc = descriptorForTypeId(true, typeId, dfltLdr)) != null) return desc; throw new PortableInvalidClassException(e); } catch (IgniteCheckedException e) { - if (userType && !ldr.equals(dfltLdr) && (desc = descriptorLoadingFailover(typeId, ldr)) != null) + // Class might have been loaded by default class loader. + if (userType && !ldr.equals(dfltLdr) && (desc = descriptorForTypeId(true, typeId, dfltLdr)) != null) return desc; throw new PortableException("Failed resolve class for ID: " + typeId, e); @@ -507,29 +508,6 @@ public class PortableContext implements Externalizable { } /** - * The method must be used in case when it wasn't possible to load user type's class using custom class loader. - * - * There are several reasons why this may happen. First, type's name can be not registered in a system cache. - * Second, class might have been predefined explicitly and loaded by default class loader. - * - * @param typeId Type ID. - * @param ldr Class loader that failed to load type's class. - * @return Type descriptor on success, {@code null} on failure. - */ - private PortableClassDescriptor descriptorLoadingFailover(int typeId, ClassLoader ldr) { - assert !ldr.equals(dfltLdr); - - // Type name can be not registered in a system cache. Try to get from local map. - PortableClassDescriptor desc = userTypesMap(ldr).get(typeId); - - if (desc == null) - // Class might have been loaded by default class loader. - desc = descriptorForTypeId(true, typeId, dfltLdr); - - return desc; - } - - /** * Creates and registers {@link PortableClassDescriptor} for the given {@code class}. * * @param cls Class. @@ -577,7 +555,7 @@ public class PortableContext implements Externalizable { String typeName = typeName(cls.getName()); - PortableIdMapper idMapper = idMapper(typeName); + PortableIdMapper idMapper = userTypeIdMapper(typeName); int typeId = idMapper.typeId(typeName); @@ -605,10 +583,13 @@ public class PortableContext implements Externalizable { // perform put() instead of putIfAbsent() because "registered" flag might have been changed or class loader // might have reloaded described class. - userTypesMap(IgniteUtils.detectClassLoader(cls)).put(typeId, desc); + if (IgniteUtils.detectClassLoader(cls).equals(dfltLdr)) + userTypes.put(typeId, desc); descByCls.put(cls, desc); + mappers.putIfAbsent(typeId, idMapper); + // TODO uncomment for https://issues.apache.org/jira/browse/IGNITE-1377 // if (registerMetadata && isMetaDataEnabled(typeId)) // metaHnd.addMeta(typeId, new PortableMetaDataImpl(typeName, desc.fieldsMeta(), null)); @@ -658,7 +639,7 @@ public class PortableContext implements Externalizable { if (marshCtx.isSystemType(typeName)) return typeName.hashCode(); - return idMapper(shortTypeName).typeId(shortTypeName); + return userTypeIdMapper(shortTypeName).typeId(shortTypeName); } /** @@ -667,14 +648,14 @@ public class PortableContext implements Externalizable { * @return Field ID. */ public int fieldId(int typeId, String fieldName) { - return idMapper(typeId).fieldId(typeId, fieldName); + return userTypeIdMapper(typeId).fieldId(typeId, fieldName); } /** * @param typeId Type ID. * @return Instance of ID mapper. */ - public PortableIdMapper idMapper(int typeId) { + public PortableIdMapper userTypeIdMapper(int typeId) { PortableIdMapper idMapper = mappers.get(typeId); if (idMapper != null) @@ -683,11 +664,6 @@ public class PortableContext implements Externalizable { if (predefinedTypes.containsKey(typeId)) return DFLT_ID_MAPPER; - for (ConcurrentMap<Integer, PortableClassDescriptor> types : userTypes.values()) { - if (types.containsKey(typeId)) - return DFLT_ID_MAPPER; - } - return BASIC_CLS_ID_MAPPER; } @@ -695,7 +671,7 @@ public class PortableContext implements Externalizable { * @param typeName Type name. * @return Instance of ID mapper. */ - private PortableIdMapper idMapper(String typeName) { + private PortableIdMapper userTypeIdMapper(String typeName) { PortableIdMapper idMapper = typeMappers.get(typeName); return idMapper != null ? idMapper : DFLT_ID_MAPPER; @@ -828,7 +804,8 @@ public class PortableContext implements Externalizable { fieldsMeta = desc.fieldsMeta(); - userTypesMap(IgniteUtils.detectClassLoader(cls)).put(id, desc); + if (IgniteUtils.detectClassLoader(cls).equals(dfltLdr)) + userTypes.put(id, desc); descByCls.put(cls, desc); } @@ -996,27 +973,6 @@ public class PortableContext implements Externalizable { } /** - * Returns user type map for specific class loader. - * - * @param ldr Class loader that loaded user type's class. - * @return User type map. - */ - private ConcurrentMap<Integer, PortableClassDescriptor> userTypesMap(ClassLoader ldr) { - ConcurrentMap<Integer, PortableClassDescriptor> ldrMap = userTypes.get(ldr); - - if (ldrMap == null) { - ConcurrentMap<Integer, PortableClassDescriptor> old = userTypes.putIfAbsent(ldr, - ldrMap = new ConcurrentHashMap8<>()); - - if (old != null) - ldrMap = old; - } - - return ldrMap; - } - - - /** */ private static class IdMapperWrapper implements PortableIdMapper { /** */