You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by sc...@apache.org on 2016/10/20 14:04:09 UTC
svn commit: r1765820 - in
/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource:
ResourceManager.java impl/ResourceManager_impl.java
Author: schor
Date: Thu Oct 20 14:04:08 2016
New Revision: 1765820
URL: http://svn.apache.org/viewvc?rev=1765820&view=rev
Log:
[UIMA-5038] [UIMA-2977] backporting from uima V3, support for common code to load resources, and new destroy method on ResourceManager
Modified:
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/ResourceManager.java
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/impl/ResourceManager_impl.java
Modified: uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/ResourceManager.java
URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/ResourceManager.java?rev=1765820&r1=1765819&r2=1765820&view=diff
==============================================================================
--- uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/ResourceManager.java (original)
+++ uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/ResourceManager.java Thu Oct 20 14:04:08 2016
@@ -315,4 +315,27 @@ public interface ResourceManager {
*/
@Deprecated
public Map<String,XMLizable> getImportCache();
+
+ /**
+ * Loads a user class using either the UIMA extension class loader (if specified) or
+ * the loader the UIMA framework is running in.
+ * @param name the class to load
+ * @return the class
+ * @throws ClassNotFoundException -
+ */
+ public Class<?> loadUserClass(String name) throws ClassNotFoundException;
+
+ /**
+ * Frees all resources held by this ResourceManager, and marks the ResourceManager as having been destroyed.
+ * A destroyed ResourceManager will throw an exception if an attempt is made to continue using it.
+ *
+ * Resources managed by a ResourceManager include all of the external shared Resources and a CAS Pool.
+ * The Resources managed by this manager will have their destroy() methods called, as part of the
+ * execution of this API.
+ *
+ * The framework does not call this method; it is up to the containing application to decide if and when
+ * a ResourceManager instance should be destroyed. This is because the containing application is the only
+ * knowledgeable source; for example a single ResourceManager might be used for multiple UIMA Pipelines.
+ */
+ public void destroy();
}
Modified: uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/impl/ResourceManager_impl.java
URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/impl/ResourceManager_impl.java?rev=1765820&r1=1765819&r2=1765820&view=diff
==============================================================================
--- uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/impl/ResourceManager_impl.java (original)
+++ uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/impl/ResourceManager_impl.java Thu Oct 20 14:04:08 2016
@@ -30,6 +30,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.uima.UIMAFramework;
import org.apache.uima.UIMA_IllegalStateException;
@@ -46,6 +47,7 @@ import org.apache.uima.resource.Resource
import org.apache.uima.resource.ResourceAccessException;
import org.apache.uima.resource.ResourceInitializationException;
import org.apache.uima.resource.ResourceManager;
+import org.apache.uima.resource.ResourceSpecifier;
import org.apache.uima.resource.SharedResourceObject;
import org.apache.uima.resource.metadata.ExternalResourceBinding;
import org.apache.uima.resource.metadata.ResourceManagerConfiguration;
@@ -58,6 +60,34 @@ import org.apache.uima.util.XMLizable;
*
*/
public class ResourceManager_impl implements ResourceManager {
+
+ /**
+ * Ties an External Resource instance to
+ * - its description
+ * -- name
+ * -- textual description
+ * -- a ResourceSpecifier describing how to create it
+ * -- the String name of the Java class that implements the resource)
+ * - its defining UIMA Context
+ *
+ * These are used to validate multiple declarations, and to get
+ * a resource to tie it to a binding
+ */
+ static protected class ResourceRegistration { // make protected https://issues.apache.org/jira/browse/UIMA-2102
+ Resource resource;
+
+ ExternalResourceDescription description;
+
+ String definingContext;
+
+ public ResourceRegistration(Resource resource, ExternalResourceDescription description,
+ String definingContext) {
+ this.resource = resource;
+ this.description = description;
+ this.definingContext = definingContext;
+ }
+ }
+
/**
* resource bundle for log messages
*/
@@ -65,6 +95,7 @@ public class ResourceManager_impl implem
protected static final Class<Resource> EMPTY_RESOURCE_CLASS = Resource.class;
+ private AtomicBoolean isDestroyed = new AtomicBoolean(false);
/**
* a monitor lock for synchronizing get/set of casManager ref
*/
@@ -77,6 +108,7 @@ public class ResourceManager_impl implem
/**
* Map from qualified key names (declared in resource dependency XML) to Resource objects.
+ * This map is many to one (multiple keys may refer to the same Resource object)
*
* Can't be concurrentMap because it (currently) depends on storing nulls
*/
@@ -85,27 +117,37 @@ public class ResourceManager_impl implem
/**
* Internal map from resource names (declared in resource declaration XML) to ResourceRegistration
* objects. Used during initialization only.
+ *
+ * This is a one-to-one map.
*/
final protected Map<String, ResourceRegistration> mInternalResourceRegistrationMap;
/**
* Map from String keys to Class objects. For ParameterizedResources only, stores the
* implementation class corresponding to each resource name.
+ *
+ * This is a many to one map; many keys may refer to the same class
+ *
+ * key = aQualifiedContextName + the key name in an external resource binding
*/
final protected Map<String, Class<?>> mParameterizedResourceImplClassMap;
/**
- * Internal map from resource names (declared in resource declaration XML) to Class objects. Used
+ * Internal map from resource names (declared in resource declaration XML) to Class objects
+ * for parameterized Resource. These are potentially "customized" when referenced, by
+ * parameter strings (such as language, for a Dictionary resource). Used
* internally during resource initialization.
+ *
+ * key = external resource declared name.
*/
final protected Map<String, Class<?>> mInternalParameterizedResourceImplClassMap;
/**
- * Map from ParameterizedResourceKey to Resource objects. For
- * ParameterizedResources only, stores the DataResources that have already been encountered, and
+ * Map from ParameterizedResourceKey to Resource objects.
+ * For ParameterizedResources only, stores the DataResources that have already been encountered, and
* the Resources that have been instantiated therefrom.
*/
- final protected Map<List<Object>, Object> mParameterizedResourceInstanceMap;
+ final protected Map<List<Object>, Resource> mParameterizedResourceInstanceMap;
/**
* UIMA extension ClassLoader. ClassLoader is created if an extension classpath is specified at
@@ -158,7 +200,7 @@ public class ResourceManager_impl implem
mInternalResourceRegistrationMap = new ConcurrentHashMap<String, ResourceRegistration>();
mParameterizedResourceImplClassMap = new ConcurrentHashMap<String, Class<?>>();
mInternalParameterizedResourceImplClassMap = new ConcurrentHashMap<String, Class<?>>();
- mParameterizedResourceInstanceMap = new ConcurrentHashMap<List<Object>, Object>();
+ mParameterizedResourceInstanceMap = new ConcurrentHashMap<List<Object>, Resource>();
mRelativePathResolver = new RelativePathResolver_impl();
}
@@ -172,7 +214,7 @@ public class ResourceManager_impl implem
mInternalResourceRegistrationMap = new ConcurrentHashMap<String, ResourceRegistration>();
mParameterizedResourceImplClassMap = new ConcurrentHashMap<String, Class<?>>();
mInternalParameterizedResourceImplClassMap = new ConcurrentHashMap<String, Class<?>>();
- mParameterizedResourceInstanceMap = new ConcurrentHashMap<List<Object>, Object>();
+ mParameterizedResourceInstanceMap = new ConcurrentHashMap<List<Object>, Resource>();
mRelativePathResolver = new RelativePathResolver_impl(aClassLoader);
}
@@ -184,7 +226,7 @@ public class ResourceManager_impl implem
Map<String, ResourceRegistration> internalResourceRegistrationMap,
Map<String, Class<?>> parameterizedResourceImplClassMap,
Map<String, Class<?>> internalParameterizedResourceImplClassMap,
- Map<List<Object>, Object> parameterizedResourceInstanceMap) {
+ Map<List<Object>, Resource> parameterizedResourceInstanceMap) {
mResourceMap = resourceMap;
mInternalResourceRegistrationMap = internalResourceRegistrationMap;
mParameterizedResourceImplClassMap = parameterizedResourceImplClassMap;
@@ -231,6 +273,7 @@ public class ResourceManager_impl implem
/**
* @see org.apache.uima.resource.ResourceManager#setExtensionClassPath(java.lang.String, boolean)
*/
+ @Override
public synchronized void setExtensionClassPath(String classpath, boolean resolveResource)
throws MalformedURLException {
// create UIMA extension ClassLoader with the given classpath
@@ -246,6 +289,7 @@ public class ResourceManager_impl implem
* @see org.apache.uima.resource.ResourceManager#setExtensionClassPath(ClassLoader,java.lang.String,
* boolean)
*/
+ @Override
public synchronized void setExtensionClassPath(ClassLoader parent, String classpath, boolean resolveResource)
throws MalformedURLException {
// create UIMA extension ClassLoader with the given classpath
@@ -260,6 +304,7 @@ public class ResourceManager_impl implem
/**
* @see org.apache.uima.resource.ResourceManager#getExtensionClassLoader()
*/
+ @Override
public ClassLoader getExtensionClassLoader() {
return uimaCL;
}
@@ -267,6 +312,7 @@ public class ResourceManager_impl implem
/**
* @see org.apache.uima.resource.ResourceManager#getDataPath()
*/
+ @Override
public String getDataPath() {
return getRelativePathResolver().getDataPath();
}
@@ -274,6 +320,7 @@ public class ResourceManager_impl implem
/**
* @see org.apache.uima.resource.ResourceManager#setDataPath(String)
*/
+ @Override
public void setDataPath(String aPath) throws MalformedURLException {
getRelativePathResolver().setDataPath(aPath);
}
@@ -283,6 +330,7 @@ public class ResourceManager_impl implem
*
* @see org.apache.uima.resource.ResourceManager#resolveRelativePath(java.lang.String)
*/
+ @Override
public URL resolveRelativePath(String aRelativePath) throws MalformedURLException {
URL relativeUrl;
try {
@@ -293,10 +341,18 @@ public class ResourceManager_impl implem
return getRelativePathResolver().resolveRelativePath(relativeUrl);
}
+ private void checkDestroyed() {
+ if (isDestroyed.get()) {
+ throw new IllegalStateException("ResourceManager is destroyed");
+ }
+ }
+
/**
* @see org.apache.uima.resource.ResourceManager#getResource(String)
*/
+ @Override
public Object getResource(String aName) throws ResourceAccessException {
+ checkDestroyed();
Object r = mResourceMap.get(aName);
// if this is a ParameterizedDataResource, it is an error
if (r instanceof ParameterizedDataResource) {
@@ -309,12 +365,14 @@ public class ResourceManager_impl implem
/**
* @see org.apache.uima.resource.ResourceManager#getResource(java.lang.String, java.lang.String[])
*/
+ @Override
public Object getResource(String aName, String[] aParams) throws ResourceAccessException {
/* Multi-core design
* This may be called by user code sharing the same Resource Manager, and / or the same
* uima context object.
* Do double-checked idiom to avoid locking where resource is already available, loaded
*/
+ checkDestroyed();
Object r = mResourceMap.get(aName);
// if no resource found, return null
@@ -357,7 +415,7 @@ public class ResourceManager_impl implem
try {
SharedResourceObject sro = (SharedResourceObject) sharedResourceObjectClass.newInstance();
sro.load(dr);
- mParameterizedResourceInstanceMap.put(nameAndResource, sro);
+ mParameterizedResourceInstanceMap.put(nameAndResource, (Resource) sro);
return sro;
} catch (InstantiationException e) {
throw new ResourceAccessException(e);
@@ -378,6 +436,7 @@ public class ResourceManager_impl implem
/**
* @see org.apache.uima.resource.ResourceManager#getResourceClass(java.lang.String)
*/
+ @Override
@SuppressWarnings("unchecked")
public Class<? extends Resource> getResourceClass(String aName) {
Object r = mResourceMap.get(aName);
@@ -406,6 +465,7 @@ public class ResourceManager_impl implem
* @see org.apache.uima.resource.ResourceManager#getResourceAsStream(java.lang.String,
* java.lang.String[])
*/
+ @Override
public InputStream getResourceAsStream(String aKey, String[] aParams)
throws ResourceAccessException {
return getResourceAsStreamCommon(getResource(aKey, aParams));
@@ -416,11 +476,13 @@ public class ResourceManager_impl implem
*
* @see org.apache.uima.resource.ResourceManager#getResourceAsStream(java.lang.String)
*/
+ @Override
public InputStream getResourceAsStream(String aKey) throws ResourceAccessException {
return getResourceAsStreamCommon(getResource(aKey));
}
private InputStream getResourceAsStreamCommon(Object resource) throws ResourceAccessException {
+ checkDestroyed();
try {
if (resource != null && resource instanceof DataResource) {
return ((DataResource) resource).getInputStream();
@@ -446,6 +508,7 @@ public class ResourceManager_impl implem
* @see org.apache.uima.resource.ResourceManager#getResourceURL(java.lang.String,
* java.lang.String[])
*/
+ @Override
public URL getResourceURL(String aKey, String[] aParams) throws ResourceAccessException {
return getResourceAsStreamCommonUrl(getResource(aKey, aParams));
}
@@ -455,6 +518,7 @@ public class ResourceManager_impl implem
*
* @see org.apache.uima.resource.ResourceManager#getResourceURL(java.lang.String)
*/
+ @Override
public URL getResourceURL(String aKey) throws ResourceAccessException {
return getResourceAsStreamCommonUrl(getResource(aKey));
}
@@ -462,13 +526,20 @@ public class ResourceManager_impl implem
/*
* (non-Javadoc)
*
- * @see org.apache.uima.resource.ResourceManager#initializeExternalResources(org.apache.uima.resource.metadata.ResourceManagerConfiguration,
- * java.lang.String, java.util.Map)
+ * This method is called during Resource Initialization,
+ * - only for resources which are "local", that is, instances of ResourceCreationSpecifier
+ * - and therefore might have external resource declarations
+ *
+ * Compare with resolveAndValidateResourceDependencies, called for resource binding resolution.
+ *
+ * @see ResourceManager#initializeExternalResources(ResourceManagerConfiguration, String, Map<String, Object>)
*/
+ @Override
public synchronized void initializeExternalResources(ResourceManagerConfiguration aConfiguration,
String aQualifiedContextName, Map<String, Object> aAdditionalParams)
throws ResourceInitializationException {
// register resources
+ checkDestroyed();
ExternalResourceDescription[] resources = aConfiguration.getExternalResources();
for (int i = 0; i < resources.length; i++) {
String name = resources[i].getName();
@@ -518,14 +589,18 @@ public class ResourceManager_impl implem
/*
* (non-Javadoc)
*
- * @see org.apache.uima.resource.ResourceManager#resolveAndValidateResourceDependencies(org.apache.uima.resource.ExternalResourceDependency[],
- * java.lang.String)
+ * Called during resource initialization, when the resource has external resource bindings,
+ * to resolve those bindings
+ *
+ * @see ResourceManager#resolveAndValidateResourceDependencies(ExternalResourceDependency[], String)
*
* Multi-threaded. Partial avoidance of re-resolving, but if a resource fails to resolve, it will be
* reattempted on every call
*/
+ @Override
public synchronized void resolveAndValidateResourceDependencies(ExternalResourceDependency[] aDependencies,
String aQualifiedContextName) throws ResourceInitializationException {
+ checkDestroyed();
for (int i = 0; i < aDependencies.length; i++) {
// get resource
String qname = aQualifiedContextName + aDependencies[i].getKey();
@@ -558,19 +633,9 @@ public class ResourceManager_impl implem
} else {
// make sure resource exists and implements the correct interface
try {
- if (aDependencies[i].getInterfaceName() != null
- && aDependencies[i].getInterfaceName().length() > 0) {
- // get UIMA extension ClassLoader if available
- ClassLoader cl = getExtensionClassLoader();
- Class<?> theInterface = null;
-
- if (cl != null) {
- // use UIMA extension ClassLoader to load the class
- theInterface = cl.loadClass(aDependencies[i].getInterfaceName());
- } else {
- // use application ClassLoader to load the class
- theInterface = Class.forName(aDependencies[i].getInterfaceName());
- }
+ String name = aDependencies[i].getInterfaceName();
+ if (name != null && name.length() > 0) {
+ Class<?> theInterface = loadUserClass(name);
Class<? extends Resource> resourceClass = getResourceClass(qname);
if (!theInterface.isAssignableFrom(resourceClass)) {
@@ -603,7 +668,7 @@ public class ResourceManager_impl implem
boolean verificationMode = initParams.containsKey(AnalysisEngineImplBase.PARAM_VERIFICATION_MODE);
// create the initial resource using the resource factory
- Object r = UIMAFramework.produceResource(aResourceDescription.getResourceSpecifier(),
+ Resource r = UIMAFramework.produceResource(aResourceDescription.getResourceSpecifier(),
initParams);
// load implementation class (if any) and ensure that it implements
@@ -612,16 +677,7 @@ public class ResourceManager_impl implem
Class<?> implClass = null;
if (implementationName != null && implementationName.length() > 0) {
try {
- // get UIMA extension ClassLoader if available
- ClassLoader cl = getExtensionClassLoader();
-
- if (cl != null) {
- // use UIMA extension ClassLoader to load the class
- implClass = cl.loadClass(implementationName);
- } else {
- // use application ClassLoader to load the class
- implClass = Class.forName(implementationName);
- }
+ implClass = loadUserClass(implementationName);
} catch (ClassNotFoundException e) {
throw new ResourceInitializationException(ResourceInitializationException.CLASS_NOT_FOUND,
new Object[] { implementationName, aResourceDescription.getSourceUrlString() }, e);
@@ -643,7 +699,7 @@ public class ResourceManager_impl implem
if (!verificationMode) {
sro.load((DataResource) r);
}
- r = sro;
+ r = (Resource) sro;
} catch (InstantiationException e) {
throw new ResourceInitializationException(
ResourceInitializationException.COULD_NOT_INSTANTIATE, new Object[] {
@@ -683,6 +739,7 @@ public class ResourceManager_impl implem
*
* @see org.apache.uima.resource.ResourceManager#getCasManager()
*/
+ @Override
public CasManager getCasManager() {
//Optimization for case where mCasManager already created
// Some sync contention was observed - this makes it less. UIMA-4012
@@ -700,6 +757,7 @@ public class ResourceManager_impl implem
/* (non-Javadoc)
* @see org.apache.uima.resource.ResourceManager#setCasManager(org.apache.uima.resource.CasManager)
*/
+ @Override
public void setCasManager(CasManager aCasManager) {
synchronized(casManagerMonitor) {
if (mCasManager == null) {
@@ -717,21 +775,7 @@ public class ResourceManager_impl implem
return mRelativePathResolver;
}
- static protected class ResourceRegistration { // make protected https://issues.apache.org/jira/browse/UIMA-2102
- Object resource;
-
- ExternalResourceDescription description;
-
- String definingContext;
-
- public ResourceRegistration(Object resource, ExternalResourceDescription description,
- String definingContext) {
- this.resource = resource;
- this.description = description;
- this.definingContext = definingContext;
- }
- }
-
+ @Override
public Map<String, XMLizable> getImportCache() {
return importCache;
}
@@ -739,4 +783,57 @@ public class ResourceManager_impl implem
public Map<String, Set<String>> getImportUrlsCache() {
return importUrlsCache;
}
+
+ @Override
+ public Class<?> loadUserClass(String name) throws ClassNotFoundException {
+ ClassLoader cl = getExtensionClassLoader();
+ if (cl == null) {
+ cl = this.getClass().getClassLoader();
+ }
+ return Class.forName(name, true, cl);
+ }
+
+ public static Class<?> loadUserClass(String name, ResourceManager rm) throws ClassNotFoundException {
+ return (rm == null)
+ ? Class.forName(name, true, ResourceManager_impl.class.getClassLoader())
+ : rm.loadUserClass(name);
+ }
+
+ public static Class<?> loadUserClassOrThrow(String name, ResourceManager rm, ResourceSpecifier aSpecifier)
+ throws ResourceInitializationException {
+ try {
+ return (rm == null)
+ ? Class.forName(name, true, ResourceManager_impl.class.getClassLoader())
+ : rm.loadUserClass(name);
+ } catch (ClassNotFoundException e) {
+ throw new ResourceInitializationException(
+ ResourceInitializationException.CLASS_NOT_FOUND, new Object[] { name,
+ aSpecifier.getSourceUrlString() }, e);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.uima.resource.ResourceManager#destroy()
+ */
+ @Override
+ public void destroy() {
+ boolean alreadyDestroyed = isDestroyed.getAndSet(true);
+ if (alreadyDestroyed) {
+ return;
+ }
+
+ for (ResourceRegistration r : mInternalResourceRegistrationMap.values()) {
+ r.resource.destroy();
+ }
+
+ for (Resource r : mParameterizedResourceInstanceMap.values()) {
+ r.destroy();
+ }
+
+ // no destroy of caspool at this time
+
+ }
+
+
+
}