ignite-1272: storing user class descriptors in a new map depending on their class loader. Implemented onUndeploy method for portable marshaller
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/1ff1fea0 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/1ff1fea0 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/1ff1fea0 Branch: refs/heads/ignite-1272 Commit: 1ff1fea046acf1721557942e2c4f057e64223619 Parents: 3fa7e4f Author: Denis Magda <dma...@gridgain.com> Authored: Wed Sep 23 14:17:51 2015 +0300 Committer: Denis Magda <dma...@gridgain.com> Committed: Wed Sep 23 14:17:51 2015 +0300 ---------------------------------------------------------------------- .../deployment/GridDeploymentLocalStore.java | 8 +-- .../GridDeploymentPerLoaderStore.java | 8 +-- .../GridDeploymentPerVersionStore.java | 8 +-- .../internal/portable/PortableContext.java | 59 ++++++++++++++++++-- .../portable/api/PortableMarshaller.java | 5 ++ .../ignite/marshaller/AbstractMarshaller.java | 12 +++- .../ignite/marshaller/jdk/JdkMarshaller.java | 7 ++- .../optimized/OptimizedMarshaller.java | 4 +- 8 files changed, 89 insertions(+), 22 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/1ff1fea0/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentLocalStore.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentLocalStore.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentLocalStore.java index 420eea8..d095efb 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentLocalStore.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentLocalStore.java @@ -39,7 +39,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.lang.IgniteUuid; -import org.apache.ignite.marshaller.optimized.OptimizedMarshaller; +import org.apache.ignite.marshaller.AbstractMarshaller; import org.apache.ignite.spi.IgniteSpiException; import org.apache.ignite.spi.deployment.DeploymentListener; import org.apache.ignite.spi.deployment.DeploymentResource; @@ -541,8 +541,8 @@ class GridDeploymentLocalStore extends GridDeploymentStoreAdapter { ctx.resource().onUndeployed(dep); // Clear optimized marshaller's cache. - if (ctx.config().getMarshaller() instanceof OptimizedMarshaller) - ((OptimizedMarshaller)ctx.config().getMarshaller()).onUndeploy(ldr); + if (ctx.config().getMarshaller() instanceof AbstractMarshaller) + ((AbstractMarshaller)ctx.config().getMarshaller()).onUndeploy(ldr); clearSerializationCaches(); @@ -572,4 +572,4 @@ class GridDeploymentLocalStore extends GridDeploymentStoreAdapter { undeploy(ldr); } } -} \ No newline at end of file +} http://git-wip-us.apache.org/repos/asf/ignite/blob/1ff1fea0/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentPerLoaderStore.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentPerLoaderStore.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentPerLoaderStore.java index 6ca74eb..4ba308c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentPerLoaderStore.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentPerLoaderStore.java @@ -39,7 +39,7 @@ import org.apache.ignite.internal.util.GridClassLoaderCache; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.lang.IgniteUuid; -import org.apache.ignite.marshaller.optimized.OptimizedMarshaller; +import org.apache.ignite.marshaller.AbstractMarshaller; import org.apache.ignite.spi.deployment.DeploymentSpi; import static org.apache.ignite.events.EventType.EVT_CLASS_DEPLOYED; @@ -511,8 +511,8 @@ public class GridDeploymentPerLoaderStore extends GridDeploymentStoreAdapter { ctx.cache().onUndeployed(ldr); // Clear optimized marshaller's cache. - if (ctx.config().getMarshaller() instanceof OptimizedMarshaller) - ((OptimizedMarshaller)ctx.config().getMarshaller()).onUndeploy(ldr); + if (ctx.config().getMarshaller() instanceof AbstractMarshaller) + ((AbstractMarshaller)ctx.config().getMarshaller()).onUndeploy(ldr); clearSerializationCaches(); @@ -527,4 +527,4 @@ public class GridDeploymentPerLoaderStore extends GridDeploymentStoreAdapter { return S.toString(IsolatedDeployment.class, this, super.toString()); } } -} \ No newline at end of file +} http://git-wip-us.apache.org/repos/asf/ignite/blob/1ff1fea0/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentPerVersionStore.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentPerVersionStore.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentPerVersionStore.java index 6f9e968..fabbcb2 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentPerVersionStore.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentPerVersionStore.java @@ -46,7 +46,7 @@ import org.apache.ignite.internal.util.typedef.internal.LT; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.lang.IgniteUuid; -import org.apache.ignite.marshaller.optimized.OptimizedMarshaller; +import org.apache.ignite.marshaller.AbstractMarshaller; import org.apache.ignite.spi.deployment.DeploymentSpi; import org.jetbrains.annotations.Nullable; import org.jsr166.ConcurrentHashMap8; @@ -1281,8 +1281,8 @@ public class GridDeploymentPerVersionStore extends GridDeploymentStoreAdapter { ctx.cache().onUndeployed(ldr); // Clear optimized marshaller's cache. - if (ctx.config().getMarshaller() instanceof OptimizedMarshaller) - ((OptimizedMarshaller)ctx.config().getMarshaller()).onUndeploy(ldr); + if (ctx.config().getMarshaller() instanceof AbstractMarshaller) + ((AbstractMarshaller)ctx.config().getMarshaller()).onUndeploy(ldr); clearSerializationCaches(); @@ -1297,4 +1297,4 @@ public class GridDeploymentPerVersionStore extends GridDeploymentStoreAdapter { return S.toString(SharedDeployment.class, this, "super", super.toString()); } } -} \ No newline at end of file +} http://git-wip-us.apache.org/repos/asf/ignite/blob/1ff1fea0/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 1c2cba2..c6b9b51 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 @@ -110,7 +110,8 @@ public class PortableContext implements Externalizable { private final ConcurrentMap<Class<?>, PortableClassDescriptor> descByCls = new ConcurrentHashMap8<>(); /** */ - private final ConcurrentMap<Integer, PortableClassDescriptor> userTypes = new ConcurrentHashMap8<>(0); + private final ConcurrentMap<ClassLoader, ConcurrentMap<Integer, PortableClassDescriptor>> userTypes + = new ConcurrentHashMap8<>(0); /** */ private final Map<Integer, PortableClassDescriptor> predefinedTypes = new HashMap<>(); @@ -465,11 +466,11 @@ public class PortableContext implements Externalizable { ldr = IgniteUtils.gridClassLoader(); if (userType) { - desc = userTypes.get(typeId); + 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 (desc != null && ldr == IgniteUtils.gridClassLoader() && desc.describedClass().getClassLoader() == ldr) + if (desc != null && ldr.equals(IgniteUtils.gridClassLoader())) return desc; } @@ -572,7 +573,8 @@ 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. - userTypes.put(typeId, desc); + userTypesMap(IgniteUtils.detectClassLoader(cls)).put(typeId, desc); + descByCls.put(cls, desc); // TODO uncomment for https://issues.apache.org/jira/browse/IGNITE-1377 @@ -646,9 +648,14 @@ public class PortableContext implements Externalizable { if (idMapper != null) return idMapper; - if (userTypes.containsKey(typeId) || predefinedTypes.containsKey(typeId)) + 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; } @@ -789,7 +796,8 @@ public class PortableContext implements Externalizable { fieldsMeta = desc.fieldsMeta(); - userTypes.put(id, desc); + userTypesMap(IgniteUtils.detectClassLoader(cls)).put(id, desc); + descByCls.put(cls, desc); } @@ -938,6 +946,45 @@ public class PortableContext implements Externalizable { } /** + * Undeployment callback invoked when class loader is being undeployed. + * + * Some marshallers may want to clean their internal state that uses the undeployed class loader somehow. + * + * @param ldr Class loader being undeployed. + */ + public void onUndeploy(ClassLoader ldr) { + userTypes.remove(ldr); + + for (Class<?> cls : descByCls.keySet()) { + if (ldr.equals(cls.getClassLoader())) + descByCls.remove(cls); + } + + U.clearClassCache(ldr); + } + + /** + * 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 { /** */ http://git-wip-us.apache.org/repos/asf/ignite/blob/1ff1fea0/modules/core/src/main/java/org/apache/ignite/internal/portable/api/PortableMarshaller.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/api/PortableMarshaller.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/api/PortableMarshaller.java index de0df8d..2da4af1 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/portable/api/PortableMarshaller.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/api/PortableMarshaller.java @@ -355,4 +355,9 @@ public class PortableMarshaller extends AbstractMarshaller { throw new PortableException("Failed to unmarshal the object from InputStream", e); } } + + /** {@inheritDoc} */ + @Override public void onUndeploy(ClassLoader ldr) { + impl.context().onUndeploy(ldr); + } } http://git-wip-us.apache.org/repos/asf/ignite/blob/1ff1fea0/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 8c79a93..dd5bad0 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 @@ -37,6 +37,16 @@ public abstract class AbstractMarshaller implements Marshaller { /** Context. */ protected MarshallerContext ctx; + + /** + * Undeployment callback invoked when class loader is being undeployed. + * + * Some marshallers may want to clean their internal state that uses the undeployed class loader somehow. + * + * @param ldr Class loader being undeployed. + */ + public abstract void onUndeploy(ClassLoader ldr); + /** {@inheritDoc} */ @Override public void setContext(MarshallerContext ctx) { this.ctx = ctx; @@ -71,4 +81,4 @@ public abstract class AbstractMarshaller implements Marshaller { U.close(in, null); } } -} \ No newline at end of file +} http://git-wip-us.apache.org/repos/asf/ignite/blob/1ff1fea0/modules/core/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshaller.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshaller.java b/modules/core/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshaller.java index 0f4cf1f..9e0e823 100644 --- a/modules/core/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshaller.java +++ b/modules/core/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshaller.java @@ -115,7 +115,12 @@ public class JdkMarshaller extends AbstractMarshaller { } /** {@inheritDoc} */ + @Override public void onUndeploy(ClassLoader ldr) { + + } + + /** {@inheritDoc} */ @Override public String toString() { return S.toString(JdkMarshaller.class, this); } -} \ No newline at end of file +} http://git-wip-us.apache.org/repos/asf/ignite/blob/1ff1fea0/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 b9b782a..caccd99 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 @@ -288,7 +288,7 @@ public class OptimizedMarshaller extends AbstractMarshaller { * * @param ldr Class loader being undeployed. */ - public void onUndeploy(ClassLoader ldr) { + @Override public void onUndeploy(ClassLoader ldr) { for (Class<?> cls : clsMap.keySet()) { if (ldr.equals(cls.getClassLoader())) clsMap.remove(cls); @@ -296,4 +296,4 @@ public class OptimizedMarshaller extends AbstractMarshaller { U.clearClassCache(ldr); } -} \ No newline at end of file +}