diff --git a/metastore/src/java/org/apache/hadoop/hive/metastore/ObjectStore.java b/metastore/src/java/org/apache/hadoop/hive/metastore/ObjectStore.java index c39c725..a63519a 100644 --- a/metastore/src/java/org/apache/hadoop/hive/metastore/ObjectStore.java +++ b/metastore/src/java/org/apache/hadoop/hive/metastore/ObjectStore.java @@ -158,8 +158,11 @@ import org.datanucleus.ClassLoaderResolver; import org.datanucleus.ClassLoaderResolverImpl; import org.datanucleus.NucleusContext; +import org.datanucleus.api.jdo.JDOPersistenceManager; import org.datanucleus.api.jdo.JDOPersistenceManagerFactory; import org.datanucleus.store.rdbms.exceptions.MissingTableException; +import org.datanucleus.store.scostore.Store; +import org.datanucleus.util.WeakValueMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -8448,22 +8451,55 @@ private static void clearOutPmfClassLoaderCache(PersistenceManagerFactory pmf) { JDOPersistenceManagerFactory jdoPmf = (JDOPersistenceManagerFactory) pmf; NucleusContext nc = jdoPmf.getNucleusContext(); try { + Field pmCache = pmf.getClass().getDeclaredField("pmCache"); + pmCache.setAccessible(true); + Set pmSet = (Set)pmCache.get(pmf); + for (JDOPersistenceManager pm : pmSet) { + org.datanucleus.ExecutionContext ec = (org.datanucleus.ExecutionContext)pm.getExecutionContext(); + if (ec instanceof org.datanucleus.ExecutionContextThreadedImpl) { + ClassLoaderResolver clr = ((org.datanucleus.ExecutionContextThreadedImpl)ec).getClassLoaderResolver(); + clearClr(clr); + } + } + org.datanucleus.plugin.PluginManager pluginManager = jdoPmf.getNucleusContext().getPluginManager(); + Field registryField = pluginManager.getClass().getDeclaredField("registry"); + registryField.setAccessible(true); + org.datanucleus.plugin.PluginRegistry registry = (org.datanucleus.plugin.PluginRegistry)registryField.get(pluginManager); + if (registry instanceof org.datanucleus.plugin.NonManagedPluginRegistry) { + org.datanucleus.plugin.NonManagedPluginRegistry nRegistry = (org.datanucleus.plugin.NonManagedPluginRegistry)registry; + Field clrField = nRegistry.getClass().getDeclaredField("clr"); + clrField.setAccessible(true); + ClassLoaderResolver clr = (ClassLoaderResolver)clrField.get(nRegistry); + clearClr(clr); + } + if (nc instanceof org.datanucleus.PersistenceNucleusContextImpl) { + org.datanucleus.PersistenceNucleusContextImpl pnc = (org.datanucleus.PersistenceNucleusContextImpl)nc; + org.datanucleus.store.types.TypeManagerImpl tm = (org.datanucleus.store.types.TypeManagerImpl)pnc.getTypeManager(); + Field clrField = tm.getClass().getDeclaredField("clr"); + clrField.setAccessible(true); + ClassLoaderResolver clr = (ClassLoaderResolver)clrField.get(tm); + clearClr(clr); + Field storeMgrField = pnc.getClass().getDeclaredField("storeMgr"); + storeMgrField.setAccessible(true); + org.datanucleus.store.rdbms.RDBMSStoreManager storeMgr = (org.datanucleus.store.rdbms.RDBMSStoreManager)storeMgrField.get(pnc); + Field backingStoreField = storeMgr.getClass().getDeclaredField("backingStoreByMemberName"); + backingStoreField.setAccessible(true); + Map backingStoreByMemberName = (Map)backingStoreField.get(storeMgr); + for (Store store : backingStoreByMemberName.values()) { + org.datanucleus.store.rdbms.scostore.BaseContainerStore baseStore = (org.datanucleus.store.rdbms.scostore.BaseContainerStore)store; + clrField = org.datanucleus.store.rdbms.scostore.BaseContainerStore.class.getDeclaredField("clr"); + clrField.setAccessible(true); + clr = (ClassLoaderResolver)clrField.get(baseStore); + clearClr(clr); + } + } Field classLoaderResolverMap = AbstractNucleusContext.class.getDeclaredField( "classLoaderResolverMap"); classLoaderResolverMap.setAccessible(true); Map loaderMap = (Map) classLoaderResolverMap.get(nc); for (ClassLoaderResolver clr : loaderMap.values()){ - if (clr != null){ - if (clr instanceof ClassLoaderResolverImpl){ - ClassLoaderResolverImpl clri = (ClassLoaderResolverImpl) clr; - long resourcesCleared = clearFieldMap(clri,"resources"); - long loadedClassesCleared = clearFieldMap(clri,"loadedClasses"); - long unloadedClassesCleared = clearFieldMap(clri, "unloadedClasses"); - LOG.debug("Cleared ClassLoaderResolverImpl: " + - resourcesCleared + "," + loadedClassesCleared + "," + unloadedClassesCleared); - } - } + clearClr(clr); } classLoaderResolverMap.set(nc, new HashMap()); LOG.debug("Removed cached classloaders from DataNucleus NucleusContext"); @@ -8472,13 +8508,25 @@ private static void clearOutPmfClassLoaderCache(PersistenceManagerFactory pmf) { } } + private static void clearClr(ClassLoaderResolver clr) throws Exception { + if (clr != null){ + if (clr instanceof ClassLoaderResolverImpl){ + ClassLoaderResolverImpl clri = (ClassLoaderResolverImpl) clr; + long resourcesCleared = clearFieldMap(clri,"resources"); + long loadedClassesCleared = clearFieldMap(clri,"loadedClasses"); + long unloadedClassesCleared = clearFieldMap(clri, "unloadedClasses"); + LOG.debug("Cleared ClassLoaderResolverImpl: " + + resourcesCleared + "," + loadedClassesCleared + "," + unloadedClassesCleared); + } + } + } private static long clearFieldMap(ClassLoaderResolverImpl clri, String mapFieldName) throws Exception { Field mapField = ClassLoaderResolverImpl.class.getDeclaredField(mapFieldName); mapField.setAccessible(true); Map map = (Map) mapField.get(clri); long sz = map.size(); - map.clear(); + mapField.set(clri, Collections.synchronizedMap(new WeakValueMap())); return sz; }