use of org.datanucleus.store.scostore.Store in project hive by apache.
the class ObjectStore method clearOutPmfClassLoaderCache.
private static void clearOutPmfClassLoaderCache(PersistenceManagerFactory pmf) {
if ((pmf == null) || (!(pmf instanceof JDOPersistenceManagerFactory))) {
return;
}
// NOTE : This is hacky, and this section of code is fragile depending on DN code varnames
// so it's likely to stop working at some time in the future, especially if we upgrade DN
// versions, so we actively need to find a better way to make sure the leak doesn't happen
// instead of just clearing out the cache after every call.
JDOPersistenceManagerFactory jdoPmf = (JDOPersistenceManagerFactory) pmf;
NucleusContext nc = jdoPmf.getNucleusContext();
try {
Field pmCache = pmf.getClass().getDeclaredField("pmCache");
pmCache.setAccessible(true);
Set<JDOPersistenceManager> pmSet = (Set<JDOPersistenceManager>) pmCache.get(pmf);
for (JDOPersistenceManager pm : pmSet) {
org.datanucleus.ExecutionContext ec = 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<String, Store> backingStoreByMemberName = (Map<String, Store>) 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<String, ClassLoaderResolver> loaderMap = (Map<String, ClassLoaderResolver>) classLoaderResolverMap.get(nc);
for (ClassLoaderResolver clr : loaderMap.values()) {
clearClr(clr);
}
classLoaderResolverMap.set(nc, new HashMap<String, ClassLoaderResolver>());
LOG.debug("Removed cached classloaders from DataNucleus NucleusContext");
} catch (Exception e) {
LOG.warn("Failed to remove cached classloaders from DataNucleus NucleusContext", e);
}
}
Aggregations