use of org.datanucleus.NucleusContext in project hive by apache.
the class TestJdbcWithMiniHS2 method getNucleusClassLoaderResolverMapSize.
@SuppressWarnings("unchecked")
private int getNucleusClassLoaderResolverMapSize() {
Field classLoaderResolverMap;
Field pmf;
JDOPersistenceManagerFactory jdoPmf = null;
NucleusContext nc = null;
Map<String, ClassLoaderResolver> cMap;
try {
pmf = PersistenceManagerProvider.class.getDeclaredField("pmf");
if (pmf != null) {
pmf.setAccessible(true);
jdoPmf = (JDOPersistenceManagerFactory) pmf.get(null);
if (jdoPmf != null) {
nc = jdoPmf.getNucleusContext();
}
}
} catch (Exception e) {
System.out.println(e);
}
if (nc != null) {
try {
classLoaderResolverMap = AbstractNucleusContext.class.getDeclaredField("classLoaderResolverMap");
if (classLoaderResolverMap != null) {
classLoaderResolverMap.setAccessible(true);
cMap = (Map<String, ClassLoaderResolver>) classLoaderResolverMap.get(nc);
if (cMap != null) {
return cMap.size();
}
}
} catch (Exception e) {
System.out.println(e);
}
}
return -1;
}
use of org.datanucleus.NucleusContext in project hive by apache.
the class PersistenceManagerProvider method clearOutPmfClassLoaderCache.
/**
* Removed cached classloaders from DataNucleus
* DataNucleus caches classloaders in NucleusContext.
* In UDFs, this can result in classloaders not getting GCed resulting in PermGen leaks.
* This is particularly an issue when using embedded metastore with HiveServer2,
* since the current classloader gets modified with each new add jar,
* becoming the classloader for downstream classes, which DataNucleus ends up using.
* The NucleusContext cache gets freed up only on calling a close on it.
* We're not closing NucleusContext since it does a bunch of other things which we don't want.
* We're not clearing the cache HashMap by calling HashMap#clear to avoid concurrency issues.
*/
public static void clearOutPmfClassLoaderCache() {
pmfWriteLock.lock();
try {
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);
}
} finally {
pmfWriteLock.unlock();
}
}
use of org.datanucleus.NucleusContext in project datanucleus-core by datanucleus.
the class TypeManagerTest method setUp.
/**
* Create a TypeManager for testing.
*/
protected void setUp() throws Exception {
ClassLoaderResolver clr = new ClassLoaderResolverImpl();
Properties props = new Properties();
props.setProperty("bundle-check-action", "EXCEPTION");
PluginManager pluginMgr = new PluginManager(null, clr, props);
NucleusContext nucCtx = new PersistenceNucleusContextImpl(null, null, pluginMgr);
typeMgr = nucCtx.getTypeManager();
}
use of org.datanucleus.NucleusContext in project datanucleus-core by datanucleus.
the class DataNucleusEnhancer method getFileMetadataForInput.
/**
* Method that processes the registered components to enhance, and loads the metadata for
* them into the MetaDataManager, returning the associated FileMetaData.
* @return The FileMetaData for the registered components.
*/
protected Collection<FileMetaData> getFileMetadataForInput() {
Iterator<EnhanceComponent> iter = componentsToEnhance.iterator();
Collection<FileMetaData> fileMetaData = new ArrayList<FileMetaData>();
while (iter.hasNext()) {
EnhanceComponent comp = iter.next();
FileMetaData[] filemds = null;
switch(comp.getType()) {
case // Of the form "mydomain.MyClass"
EnhanceComponent.CLASS:
if (comp.getValue() instanceof String) {
// Single class
String className = (String) comp.getValue();
if (bytesForClassesToEnhanceByClassName != null && bytesForClassesToEnhanceByClassName.get(className) != null) {
// Retrieve the meta-data "file"
AbstractClassMetaData cmd = metadataMgr.getMetaDataForClass(className, clr);
if (cmd != null) {
filemds = new FileMetaData[] { cmd.getPackageMetaData().getFileMetaData() };
} else {
// No meta-data has been registered for this byte-defined class!
}
} else {
filemds = metadataMgr.loadClasses(new String[] { (String) comp.getValue() }, userClassLoader);
}
} else {
// Multiple classes
filemds = metadataMgr.loadClasses((String[]) comp.getValue(), userClassLoader);
}
break;
case // Absolute/relative filename(s)
EnhanceComponent.CLASS_FILE:
if (comp.getValue() instanceof String) {
// Single class file
String className = null;
String classFilename = (String) comp.getValue();
if (!StringUtils.getFileForFilename(classFilename).exists()) {
String msg = Localiser.msg("005003", classFilename);
addMessage(msg, true);
} else {
className = ClassEnhancerImpl.getClassNameForFileName(classFilename);
}
if (className != null) {
filemds = metadataMgr.loadClasses(new String[] { className }, userClassLoader);
}
} else {
// Multiple class files
Collection<String> classNames = new ArrayList<String>();
String[] classFilenames = (String[]) comp.getValue();
for (int i = 0; i < classFilenames.length; i++) {
String className = null;
if (!StringUtils.getFileForFilename(classFilenames[i]).exists()) {
String msg = Localiser.msg("005003", classFilenames[i]);
addMessage(msg, true);
} else {
className = ClassEnhancerImpl.getClassNameForFileName(classFilenames[i]);
}
if (className != null) {
classNames.add(className);
}
}
filemds = metadataMgr.loadClasses(classNames.toArray(new String[classNames.size()]), userClassLoader);
}
break;
case // Absolute/relative filename(s)
EnhanceComponent.MAPPING_FILE:
if (comp.getValue() instanceof String) {
// Single mapping file
filemds = metadataMgr.loadMetadataFiles(new String[] { (String) comp.getValue() }, userClassLoader);
} else {
// Multiple mapping files
filemds = metadataMgr.loadMetadataFiles((String[]) comp.getValue(), userClassLoader);
}
break;
case // Absolute/relative filename(s)
EnhanceComponent.JAR_FILE:
if (comp.getValue() instanceof String) {
// Single jar file
filemds = metadataMgr.loadJar((String) comp.getValue(), userClassLoader);
} else {
// Multiple jar files
String[] jarFilenames = (String[]) comp.getValue();
Collection<FileMetaData> filemdsColl = new HashSet<FileMetaData>();
for (int i = 0; i < jarFilenames.length; i++) {
FileMetaData[] fmds = metadataMgr.loadJar(jarFilenames[i], userClassLoader);
for (int j = 0; j < fmds.length; j++) {
filemdsColl.add(fmds[j]);
}
}
filemds = filemdsColl.toArray(new FileMetaData[filemdsColl.size()]);
}
break;
case EnhanceComponent.PERSISTENCE_UNIT:
PersistenceUnitMetaData pumd = null;
try {
Object puValue = comp.getValue();
if (puValue instanceof String) {
// Extract the metadata for the persistence-unit
NucleusContext nucleusCtx = metadataMgr.getNucleusContext();
String filename = nucleusCtx.getConfiguration().getStringProperty(PropertyNames.PROPERTY_PERSISTENCE_XML_FILENAME);
boolean validateXML = nucleusCtx.getConfiguration().getBooleanProperty(PropertyNames.PROPERTY_METADATA_XML_VALIDATE);
boolean supportXMLNamespaces = nucleusCtx.getConfiguration().getBooleanProperty(PropertyNames.PROPERTY_METADATA_XML_NAMESPACE_AWARE);
pumd = MetaDataUtils.getMetaDataForPersistenceUnit(nucleusCtx.getPluginManager(), filename, (String) comp.getValue(), validateXML, supportXMLNamespaces, clr);
} else {
pumd = (PersistenceUnitMetaData) puValue;
}
} catch (NucleusException ne) {
// No "persistence.xml" files found yet they have specified a persistence-unit name!
throw new NucleusEnhanceException(Localiser.msg("005008", comp.getValue()));
}
if (pumd == null) {
throw new NucleusEnhanceException(Localiser.msg("005009", comp.getValue()));
}
filemds = metadataMgr.loadPersistenceUnit(pumd, userClassLoader);
break;
default:
break;
}
if (filemds != null) {
for (int i = 0; i < filemds.length; i++) {
fileMetaData.add(filemds[i]);
}
}
}
return fileMetaData;
}
use of org.datanucleus.NucleusContext in project datanucleus-core by datanucleus.
the class ClassEnhancerImpl method isPersistable.
/**
* Check if the class is Persistable or is going to be enhanced based on the metadata
* @param className the class name
* @return true if Persistable
*/
public boolean isPersistable(String className) {
if (className.equals(this.className) && (cmd.getPersistenceModifier() != ClassPersistenceModifier.PERSISTENCE_AWARE)) {
// This is our class so yes it will be persistable
return true;
}
NucleusContext nucleusCtx = metaDataMgr.getNucleusContext();
// Allow for Enhancer classLoader
Class cls = clr.classForName(className, new EnhancerClassLoader(clr));
if (nucleusCtx.getApiAdapter().isPersistable(cls)) {
return true;
}
AbstractClassMetaData cmd = metaDataMgr.getMetaDataForClass(cls, clr);
if (cmd != null && cmd.getPersistenceModifier() == ClassPersistenceModifier.PERSISTENCE_CAPABLE) {
// The specified class has MetaData and will be enhanced shortly
return true;
}
return false;
}
Aggregations