[UIMA-6232] Reduce overhead of createTypeSystemDescription() and friends
* Update branch for merging into master
Merge branch 'master' into feature/UIMA-6232-Reduce-overhead-of-createTypeSystemDescription-and-friends
* master: (124 commits)
[maven-release-plugin] prepare for next development iteration
[maven-release-plugin] prepare release uimafit-3.1.0
[maven-release-plugin] prepare for next development iteration
[maven-release-plugin] prepare release uimafit-3.1.0
[NO JIRA] Adjust UIMA version in the NOTICE file of the binary distribution
[maven-release-plugin] prepare for next development iteration
[maven-release-plugin] prepare release uimafit-3.1.0
[NO JIRA] Update documentation to changed API in ExternalResourceFactory and removed a spurious character
[NO JIRA] Adjusted comparison version for API change report
[NO JIRA] Updated README file for release.
[NO JIRA] Updated README file for release.
[UIMA-6214] Method signature class in ExternalResourceFactory
Update an Eclipse metadata file.
[UIMA-5847] Remove UV3 bug workarounds in FSCollectionFactory
[UIMA-6216] Upgrade to UIMA Core 3.1.1
[NO JIRA] Fix NOTICE file
No issue. Make japicmp pick up the right post-analysis file.
No issue. Set version to 3.1.0-SNAPSHOT
[UIMA-6181]b Fix complaints about maven-plugin-plugin in Eclipse
[No Issue] Minor improvement of unit test illustrating error when binding resources to aggregates with nested dependent AEs.
...
# Conflicts:
# uimafit-core/src/main/java/org/apache/uima/fit/factory/FsIndexFactory.java
# uimafit-core/src/main/java/org/apache/uima/fit/factory/TypePrioritiesFactory.java
# uimafit-core/src/main/java/org/apache/uima/fit/factory/TypeSystemDescriptionFactory.java
diff --git a/uimafit-core/src/main/java/org/apache/uima/fit/factory/FsIndexFactory.java b/uimafit-core/src/main/java/org/apache/uima/fit/factory/FsIndexFactory.java
index 0b32eb1..a8fa976 100644
--- a/uimafit-core/src/main/java/org/apache/uima/fit/factory/FsIndexFactory.java
+++ b/uimafit-core/src/main/java/org/apache/uima/fit/factory/FsIndexFactory.java
@@ -6,9 +6,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -26,6 +26,7 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
+import java.util.WeakHashMap;
import org.apache.uima.fit.descriptor.FsIndex;
import org.apache.uima.fit.descriptor.FsIndexKey;
@@ -43,6 +44,7 @@
import org.apache.uima.util.XMLInputSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.util.ClassUtils;
/**
*/
@@ -64,6 +66,17 @@
private static final Object SCAN_LOCK = new Object();
+ private static final Object CREATE_LOCK = new Object();
+
+ private static WeakHashMap<ClassLoader, String[]> fsIndexLocationsByClassloader;
+
+ private static WeakHashMap<ClassLoader, FsIndexCollection> fsIndexCollectionsByClassloader;
+
+ static {
+ fsIndexLocationsByClassloader = new WeakHashMap<>();
+ fsIndexCollectionsByClassloader = new WeakHashMap<>();
+ }
+
private FsIndexFactory() {
// Factory class
}
@@ -71,13 +84,13 @@
/**
* Create index configuration data for a given class definition using reflection and the
* configuration parameter annotation.
- *
+ *
* @param componentClass
* the class to analyze
* @return the index collection
*/
public static FsIndexCollection createFsIndexCollection(Class<?> componentClass) {
- List<FsIndex> anFsIndexList = new ArrayList<FsIndex>();
+ List<FsIndex> anFsIndexList = new ArrayList<>();
// Check FsIndexCollection annotation
org.apache.uima.fit.descriptor.FsIndexCollection anIndexCollection = getInheritableAnnotation(
@@ -91,10 +104,10 @@
componentClass);
if (anFsIndex != null) {
if (anIndexCollection != null) {
- throw new IllegalStateException("Class [" + componentClass.getName() + "] must not "
- + "declare "
- + org.apache.uima.fit.descriptor.FsIndexCollection.class.getSimpleName() + " and "
- + FsIndex.class.getSimpleName() + " at the same time.");
+ throw new IllegalStateException(
+ "Class [" + componentClass.getName() + "] must not " + "declare "
+ + org.apache.uima.fit.descriptor.FsIndexCollection.class.getSimpleName()
+ + " and " + FsIndex.class.getSimpleName() + " at the same time.");
}
anFsIndexList.add(anFsIndex);
@@ -105,7 +118,7 @@
// Process collected FsIndex annotations
for (FsIndex anIdx : anFsIndexList) {
// Collect index keys
- List<FsIndexKeyDescription> keys = new ArrayList<FsIndexKeyDescription>();
+ List<FsIndexKeyDescription> keys = new ArrayList<>();
for (FsIndexKey anIndexKey : anIdx.keys()) {
keys.add(createFsIndexKeyDescription(anIndexKey.featureName(), anIndexKey.comparator()));
}
@@ -161,7 +174,7 @@
/**
* Create a index collection from a set of descriptions.
- *
+ *
* @param descriptions
* the index descriptions
* @return the index collection
@@ -188,7 +201,8 @@
* the index comparator
* @return the index key description
*/
- public static FsIndexKeyDescription createFsIndexKeyDescription(String featureName, int comparator) {
+ public static FsIndexKeyDescription createFsIndexKeyDescription(String featureName,
+ int comparator) {
FsIndexKeyDescription_impl key = new FsIndexKeyDescription_impl();
key.setFeatureName(featureName);
key.setComparator(comparator);
@@ -196,17 +210,15 @@
return key;
}
- private static String[] indexDescriptorLocations;
-
/**
* Creates a {@link FsIndexCollection} from descriptor names.
- *
+ *
* @param descriptorNames
* The fully qualified, Java-style, dotted descriptor names.
* @return a {@link FsIndexCollection} that includes the indexes from all of the specified files.
*/
public static FsIndexCollection createFsIndexCollection(String... descriptorNames) {
- List<Import> imports = new ArrayList<Import>();
+ List<Import> imports = new ArrayList<>();
for (String descriptorName : descriptorNames) {
Import imp = new Import_impl();
imp.setName(descriptorName);
@@ -221,13 +233,13 @@
/**
* Creates a {@link FsIndexCollection} from a descriptor file
- *
+ *
* @param descriptorURIs
* The descriptor file paths.
* @return A {@link FsIndexCollection} that includes the indexes from all of the specified files.
*/
public static FsIndexCollection createTypeSystemDescriptionFromPath(String... descriptorURIs) {
- List<Import> imports = new ArrayList<Import>();
+ List<Import> imports = new ArrayList<>();
for (String descriptorURI : descriptorURIs) {
Import imp = new Import_impl();
imp.setLocation(descriptorURI);
@@ -244,45 +256,58 @@
* Creates a {@link FsIndexCollection} from all index descriptions that can be found via the
* pattern specified in the system property {@code org.apache.uima.fit.fsindex.import_pattern} or
* via the {@code META-INF/org.apache.uima.fit/fsindexes.txt} files in the classpath.
- *
+ *
* @return the auto-scanned indexes.
* @throws ResourceInitializationException
* if the index collection could not be assembled
*/
public static FsIndexCollection createFsIndexCollection() throws ResourceInitializationException {
- List<FsIndexDescription> fsIndexList = new ArrayList<FsIndexDescription>();
- for (String location : scanIndexDescriptors()) {
- try {
- XMLInputSource xmlInput = new XMLInputSource(location);
- FsIndexCollection fsIdxCol = getXMLParser().parseFsIndexCollection(xmlInput);
- fsIdxCol.resolveImports();
- fsIndexList.addAll(asList(fsIdxCol.getFsIndexes()));
- LOG.debug("Detected index at [{}]", location);
- } catch (IOException e) {
- throw new ResourceInitializationException(e);
- } catch (InvalidXMLException e) {
- LOG.warn("[{}] is not a index descriptor file. Ignoring.", location, e);
+ ClassLoader cl = ClassUtils.getDefaultClassLoader();
+ FsIndexCollection aggFsIdxCol = fsIndexCollectionsByClassloader.get(cl);
+ if (aggFsIdxCol == null) {
+ synchronized (CREATE_LOCK) {
+ List<FsIndexDescription> fsIndexList = new ArrayList<>();
+ for (String location : scanIndexDescriptors()) {
+ try {
+ XMLInputSource xmlInput = new XMLInputSource(location);
+ FsIndexCollection fsIdxCol = getXMLParser().parseFsIndexCollection(xmlInput);
+ fsIdxCol.resolveImports();
+ fsIndexList.addAll(asList(fsIdxCol.getFsIndexes()));
+ LOG.debug("Detected index at [{}]", location);
+ } catch (IOException e) {
+ throw new ResourceInitializationException(e);
+ } catch (InvalidXMLException e) {
+ LOG.warn("[{}] is not a index descriptor file. Ignoring.", location, e);
+ }
+ }
+
+ aggFsIdxCol = createFsIndexCollection(
+ fsIndexList.toArray(new FsIndexDescription[fsIndexList.size()]));
+ fsIndexCollectionsByClassloader.put(cl, aggFsIdxCol);
}
}
- return createFsIndexCollection(fsIndexList.toArray(new FsIndexDescription[fsIndexList.size()]));
+ return (FsIndexCollection) aggFsIdxCol.clone();
}
/**
* Get all currently accessible index descriptor locations. A scan is actually only performed on
* the first call and the locations are cached. To force a re-scan use
* {@link #forceIndexDescriptorsScan()}.
- *
+ *
* @return an array of locations.
* @throws ResourceInitializationException
* if the locations could not be resolved.
*/
public static String[] scanIndexDescriptors() throws ResourceInitializationException {
synchronized (SCAN_LOCK) {
- if (indexDescriptorLocations == null) {
- indexDescriptorLocations = scanDescriptors(MetaDataType.FS_INDEX);
+ ClassLoader cl = ClassUtils.getDefaultClassLoader();
+ String[] indexLocations = fsIndexLocationsByClassloader.get(cl);
+ if (indexLocations == null) {
+ indexLocations = scanDescriptors(MetaDataType.FS_INDEX);
+ fsIndexLocationsByClassloader.put(cl, indexLocations);
}
- return indexDescriptorLocations;
+ return indexLocations;
}
}
@@ -291,6 +316,9 @@
* all auto-import locations.
*/
public static void forceIndexDescriptorsScan() {
- indexDescriptorLocations = null;
+ synchronized (SCAN_LOCK) {
+ fsIndexLocationsByClassloader.clear();
+ fsIndexCollectionsByClassloader.clear();
+ }
}
}
diff --git a/uimafit-core/src/main/java/org/apache/uima/fit/factory/TypePrioritiesFactory.java b/uimafit-core/src/main/java/org/apache/uima/fit/factory/TypePrioritiesFactory.java
index f75abf7..2073441 100644
--- a/uimafit-core/src/main/java/org/apache/uima/fit/factory/TypePrioritiesFactory.java
+++ b/uimafit-core/src/main/java/org/apache/uima/fit/factory/TypePrioritiesFactory.java
@@ -6,9 +6,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -25,6 +25,7 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
+import java.util.WeakHashMap;
import org.apache.uima.fit.internal.MetaDataType;
import org.apache.uima.fit.internal.ResourceManagerFactory;
@@ -39,13 +40,23 @@
import org.apache.uima.util.XMLInputSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.util.ClassUtils;
public final class TypePrioritiesFactory {
private static final Logger LOG = LoggerFactory.getLogger(TypePrioritiesFactory.class);
private static final Object SCAN_LOCK = new Object();
- private static String[] typePriorityDescriptorLocations;
+ private static final Object CREATE_LOCK = new Object();
+
+ private static WeakHashMap<ClassLoader, String[]> typePrioritesLocationsByClassloader;
+
+ private static WeakHashMap<ClassLoader, TypePriorities> typePrioritiesByClassloader;
+
+ static {
+ typePrioritesLocationsByClassloader = new WeakHashMap<>();
+ typePrioritiesByClassloader = new WeakHashMap<>();
+ }
private TypePrioritiesFactory() {
// This class is not meant to be instantiated
@@ -53,7 +64,7 @@
/**
* Create a TypePriorities given a sequence of ordered type classes
- *
+ *
* @param prioritizedTypes
* a sequence of ordered type classes
* @return type priorities created from the ordered JCas classes
@@ -77,8 +88,8 @@
}
/**
- * Create a TypePriorities given a sequence of ordered type names
- *
+ * Create a {@link TypePriorities} given a sequence of ordered type names
+ *
* @param prioritizedTypeNames
* a sequence of ordered type names
* @return type priorities created from the ordered type names
@@ -97,49 +108,58 @@
* the pattern specified in the system property
* {@code org.apache.uima.fit.typepriorities.import_pattern} or via the
* {@code META-INF/org.apache.uima.fit/typepriorities.txt} files in the classpath.
- *
+ *
* @return the auto-scanned type priorities.
* @throws ResourceInitializationException
* if the collected type priorities cannot be merged.
*/
public static TypePriorities createTypePriorities() throws ResourceInitializationException {
- List<TypePriorities> typePrioritiesList = new ArrayList<TypePriorities>();
- for (String location : scanTypePrioritiesDescriptors()) {
- try {
- XMLInputSource xmlInput = new XMLInputSource(location);
- TypePriorities typePriorities = getXMLParser().parseTypePriorities(xmlInput);
- typePriorities.resolveImports();
- typePrioritiesList.add(typePriorities);
- LOG.debug("Detected type priorities at [{}]", location);
- } catch (IOException e) {
- throw new ResourceInitializationException(e);
- } catch (InvalidXMLException e) {
- LOG.warn("[{}] is not a type priorities descriptor file. Ignoring.", location, e);
+ ClassLoader cl = ClassUtils.getDefaultClassLoader();
+ TypePriorities aggTypePriorities = typePrioritiesByClassloader.get(cl);
+ if (aggTypePriorities == null) {
+ synchronized (CREATE_LOCK) {
+ List<TypePriorities> typePrioritiesList = new ArrayList<>();
+ for (String location : scanTypePrioritiesDescriptors()) {
+ try {
+ XMLInputSource xmlInput = new XMLInputSource(location);
+ TypePriorities typePriorities = getXMLParser().parseTypePriorities(xmlInput);
+ typePriorities.resolveImports();
+ typePrioritiesList.add(typePriorities);
+ LOG.debug("Detected type priorities at [{}]", location);
+ } catch (IOException e) {
+ throw new ResourceInitializationException(e);
+ } catch (InvalidXMLException e) {
+ LOG.warn("[{}] is not a type priorities descriptor file. Ignoring.", location, e);
+ }
+ }
+
+ ResourceManager resMgr = ResourceManagerFactory.newResourceManager();
+ aggTypePriorities = CasCreationUtils.mergeTypePriorities(typePrioritiesList, resMgr);
+ typePrioritiesByClassloader.put(cl, aggTypePriorities);
}
}
- ResourceManager resMgr = ResourceManagerFactory.newResourceManager();
- TypePriorities aggTypePriorities = CasCreationUtils.mergeTypePriorities(typePrioritiesList,
- resMgr);
-
- return aggTypePriorities;
+ return (TypePriorities) aggTypePriorities.clone();
}
/**
* Get all currently accessible type priorities descriptor locations. A scan is actually only
* performed on the first call and the locations are cached. To force a re-scan use
* {@link #forceTypePrioritiesDescriptorsScan()}.
- *
+ *
* @return an array of locations.
* @throws ResourceInitializationException
* if the locations could not be resolved.
*/
public static String[] scanTypePrioritiesDescriptors() throws ResourceInitializationException {
synchronized (SCAN_LOCK) {
- if (typePriorityDescriptorLocations == null) {
- typePriorityDescriptorLocations = scanDescriptors(MetaDataType.TYPE_PRIORITIES);
+ ClassLoader cl = ClassUtils.getDefaultClassLoader();
+ String[] typePrioritesLocations = typePrioritesLocationsByClassloader.get(cl);
+ if (typePrioritesLocations == null) {
+ typePrioritesLocations = scanDescriptors(MetaDataType.TYPE_PRIORITIES);
+ typePrioritesLocationsByClassloader.put(cl, typePrioritesLocations);
}
- return typePriorityDescriptorLocations;
+ return typePrioritesLocations;
}
}
@@ -148,6 +168,9 @@
* {@link #scanTypePrioritiesDescriptors()} will rescan all auto-import locations.
*/
public static void forceTypePrioritiesDescriptorsScan() {
- typePriorityDescriptorLocations = null;
+ synchronized (SCAN_LOCK) {
+ typePrioritesLocationsByClassloader.clear();
+ typePrioritiesByClassloader.clear();
+ }
}
}
diff --git a/uimafit-core/src/main/java/org/apache/uima/fit/factory/TypeSystemDescriptionFactory.java b/uimafit-core/src/main/java/org/apache/uima/fit/factory/TypeSystemDescriptionFactory.java
index a0a2f98..dc05a40 100644
--- a/uimafit-core/src/main/java/org/apache/uima/fit/factory/TypeSystemDescriptionFactory.java
+++ b/uimafit-core/src/main/java/org/apache/uima/fit/factory/TypeSystemDescriptionFactory.java
@@ -6,9 +6,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -25,6 +25,7 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
+import java.util.WeakHashMap;
import org.apache.uima.fit.internal.MetaDataType;
import org.apache.uima.fit.internal.ResourceManagerFactory;
@@ -38,13 +39,23 @@
import org.apache.uima.util.XMLInputSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.util.ClassUtils;
public final class TypeSystemDescriptionFactory {
private static final Logger LOG = LoggerFactory.getLogger(TypeSystemDescriptionFactory.class);
private static final Object SCAN_LOCK = new Object();
- private static String[] typeDescriptorLocations;
+ private static final Object CREATE_LOCK = new Object();
+
+ private static WeakHashMap<ClassLoader, String[]> typeDescriptorLocationsByClassloader;
+
+ private static WeakHashMap<ClassLoader, TypeSystemDescription> typeDescriptorByClassloader;
+
+ static {
+ typeDescriptorLocationsByClassloader = new WeakHashMap<>();
+ typeDescriptorByClassloader = new WeakHashMap<>();
+ }
private TypeSystemDescriptionFactory() {
// This class is not meant to be instantiated
@@ -52,14 +63,14 @@
/**
* Creates a TypeSystemDescription from descriptor names.
- *
+ *
* @param descriptorNames
* The fully qualified, Java-style, dotted descriptor names.
* @return A TypeSystemDescription that includes the types from all of the specified files.
*/
public static TypeSystemDescription createTypeSystemDescription(String... descriptorNames) {
TypeSystemDescription typeSystem = new TypeSystemDescription_impl();
- List<Import> imports = new ArrayList<Import>();
+ List<Import> imports = new ArrayList<>();
for (String descriptorName : descriptorNames) {
Import imp = new Import_impl();
imp.setName(descriptorName);
@@ -71,15 +82,16 @@
}
/**
- * Creates a TypeSystemDescription from a descriptor file
- *
+ * Creates a {@link TypeSystemDescription} from a descriptor file
+ *
* @param descriptorURIs
* The descriptor file paths.
* @return A TypeSystemDescription that includes the types from all of the specified files.
*/
- public static TypeSystemDescription createTypeSystemDescriptionFromPath(String... descriptorURIs) {
+ public static TypeSystemDescription createTypeSystemDescriptionFromPath(
+ String... descriptorURIs) {
TypeSystemDescription typeSystem = new TypeSystemDescription_impl();
- List<Import> imports = new ArrayList<Import>();
+ List<Import> imports = new ArrayList<>();
for (String descriptorURI : descriptorURIs) {
Import imp = new Import_impl();
imp.setLocation(descriptorURI);
@@ -94,43 +106,54 @@
* Creates a {@link TypeSystemDescription} from all type descriptions that can be found via the
* default import pattern or via the {@code META-INF/org.apache.uima.fit/types.txt} files in the
* classpath.
- *
+ *
* @return the auto-scanned type system.
* @throws ResourceInitializationException
* if the collected type system descriptions cannot be merged.
*/
public static TypeSystemDescription createTypeSystemDescription()
throws ResourceInitializationException {
- List<TypeSystemDescription> tsdList = new ArrayList<TypeSystemDescription>();
- for (String location : scanTypeDescriptors()) {
- try {
- XMLInputSource xmlInputType1 = new XMLInputSource(location);
- tsdList.add(getXMLParser().parseTypeSystemDescription(xmlInputType1));
- LOG.debug("Detected type system at [{}]", location);
- } catch (IOException e) {
- throw new ResourceInitializationException(e);
- } catch (InvalidXMLException e) {
- LOG.warn("[{}] is not a type file. Ignoring.", location, e);
+ ClassLoader cl = ClassUtils.getDefaultClassLoader();
+ TypeSystemDescription tsd = typeDescriptorByClassloader.get(cl);
+ if (tsd == null) {
+ synchronized (CREATE_LOCK) {
+ List<TypeSystemDescription> tsdList = new ArrayList<>();
+ for (String location : scanTypeDescriptors()) {
+ try {
+ XMLInputSource xmlInputType1 = new XMLInputSource(location);
+ tsdList.add(getXMLParser().parseTypeSystemDescription(xmlInputType1));
+ LOG.debug("Detected type system at [{}]", location);
+ } catch (IOException e) {
+ throw new ResourceInitializationException(e);
+ } catch (InvalidXMLException e) {
+ LOG.warn("[{}] is not a type file. Ignoring.", location, e);
+ }
+ }
+
+ ResourceManager resMgr = ResourceManagerFactory.newResourceManager();
+ tsd = mergeTypeSystems(tsdList, resMgr);
+ typeDescriptorByClassloader.put(cl, tsd);
}
}
-
- ResourceManager resMgr = ResourceManagerFactory.newResourceManager();
- return mergeTypeSystems(tsdList, resMgr);
+ return (TypeSystemDescription) tsd.clone();
}
/**
* Get all currently accessible type system descriptor locations. A scan is actually only
* performed on the first call and the locations are cached. To force a re-scan use
* {@link #forceTypeDescriptorsScan()}.
- *
+ *
* @return an array of locations.
* @throws ResourceInitializationException
* if the locations could not be resolved.
*/
public static String[] scanTypeDescriptors() throws ResourceInitializationException {
synchronized (SCAN_LOCK) {
+ ClassLoader cl = ClassUtils.getDefaultClassLoader();
+ String[] typeDescriptorLocations = typeDescriptorLocationsByClassloader.get(cl);
if (typeDescriptorLocations == null) {
typeDescriptorLocations = scanDescriptors(MetaDataType.TYPE_SYSTEM);
+ typeDescriptorLocationsByClassloader.put(cl, typeDescriptorLocations);
}
return typeDescriptorLocations;
}
@@ -141,6 +164,9 @@
* all auto-import locations.
*/
public static void forceTypeDescriptorsScan() {
- typeDescriptorLocations = null;
+ synchronized (SCAN_LOCK) {
+ typeDescriptorLocationsByClassloader.clear();
+ typeDescriptorByClassloader.clear();
+ }
}
}
diff --git a/uimafit-core/src/main/java/org/apache/uima/fit/internal/MetaDataUtil.java b/uimafit-core/src/main/java/org/apache/uima/fit/internal/MetaDataUtil.java
index 73528a1..6b13c56 100644
--- a/uimafit-core/src/main/java/org/apache/uima/fit/internal/MetaDataUtil.java
+++ b/uimafit-core/src/main/java/org/apache/uima/fit/internal/MetaDataUtil.java
@@ -6,9 +6,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -45,7 +45,7 @@
/**
* Scan patterns from manifest files and from the specified system property.
- *
+ *
* @param aType
* the type of metadata to scan for
* @return array or all patterns found.
@@ -54,7 +54,7 @@
*/
public static String[] scanImportsAndManifests(MetaDataType aType)
throws ResourceInitializationException {
- ArrayList<String> patterns = new ArrayList<String>();
+ ArrayList<String> patterns = new ArrayList<>();
// Scan auto-import locations
for (String property : getImportProperties(aType)) {
@@ -80,7 +80,7 @@
/**
* Resolve a list of patterns to a set of URLs.
- *
+ *
* @param patterns
* the patterns to resolve
* @return an array of locations.
@@ -88,11 +88,11 @@
* if the locations could not be resolved.
*/
public static String[] resolve(String... patterns) throws ResourceInitializationException {
- Set<String> locations = new HashSet<String>();
+ Set<String> locations = new HashSet<>();
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
try {
// Scan auto-import locations. Using a set to avoid scanning a pattern twice.
- for (String pattern : new TreeSet<String>(Arrays.asList(patterns))) {
+ for (String pattern : new TreeSet<>(Arrays.asList(patterns))) {
String p = pattern.trim();
if (p.length() == 0) {
continue;
@@ -109,13 +109,13 @@
/**
* Get manifest locations for the specified type.
- *
+ *
* @param aType
* the type of metadata to scan for
* @return the manifest locations for this kind of metadata to scan
*/
public static String[] getManifestLocations(MetaDataType aType) {
- List<String> locations = new ArrayList<String>();
+ List<String> locations = new ArrayList<>();
switch (aType) {
case FS_INDEX:
locations.add("classpath*:META-INF/org.apache.uima.fit/fsindexes.txt");
@@ -125,7 +125,7 @@
break;
case TYPE_PRIORITIES:
locations.add("classpath*:META-INF/org.apache.uima.fit/typepriorities.txt");
- break;
+ break;
}
return locations.toArray(new String[locations.size()]);
@@ -134,13 +134,13 @@
/**
* Get system properties indicating which locations to scan for descriptions of the given type. A
* list of locations may be given separated by ";".
- *
+ *
* @param aType
* the type of metadata to scan for
* @return the locations for this kind of metadata to scan
*/
public static String[] getImportProperties(MetaDataType aType) {
- List<String> locations = new ArrayList<String>();
+ List<String> locations = new ArrayList<>();
switch (aType) {
case FS_INDEX:
locations.add("org.apache.uima.fit.fsindex.import_pattern");
@@ -150,18 +150,18 @@
break;
case TYPE_PRIORITIES:
locations.add("org.apache.uima.fit.typepriorities.import_pattern");
- break;
+ break;
}
return locations.toArray(new String[locations.size()]);
}
-
+
/**
* Get all currently accessible descriptor locations for the given type.
- *
+ *
* @param aType
* the type of metadata to scan for
- * @return an array of locations.
+ * @return an array of locations.
* @throws ResourceInitializationException
* if the locations could not be resolved.
*/
diff --git a/uimafit-maven-plugin/src/main/java/org/apache/uima/fit/maven/GenerateDescriptorsMojo.java b/uimafit-maven-plugin/src/main/java/org/apache/uima/fit/maven/GenerateDescriptorsMojo.java
index 797eae8..8cda479 100644
--- a/uimafit-maven-plugin/src/main/java/org/apache/uima/fit/maven/GenerateDescriptorsMojo.java
+++ b/uimafit-maven-plugin/src/main/java/org/apache/uima/fit/maven/GenerateDescriptorsMojo.java
@@ -6,9 +6,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -23,6 +23,7 @@
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Modifier;
+
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.maven.plugin.AbstractMojo;
@@ -66,7 +67,7 @@
*/
@Parameter(defaultValue = "${project.build.directory}/classes", required = true)
private File outputDirectory;
-
+
/**
* Skip generation of META-INF/org.apache.uima.fit/components.txt
*/
@@ -97,7 +98,7 @@
outputDirectory.mkdirs();
buildContext.refresh(outputDirectory);
}
-
+
// Get the compiled classes from this project
String[] files = FileUtils.getFilesFromExtension(project.getBuild().getOutputDirectory(),
new String[] { "class" });
@@ -112,14 +113,19 @@
String base = file.substring(0, file.length() - 6);
String clazzPath = base.substring(project.getBuild().getOutputDirectory().length() + 1);
String clazzName = clazzPath.replace(File.separator, ".");
+
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
try {
Class clazz = componentLoader.loadClass(clazzName);
-
+
+ // Make the componentLoader available to uimaFIT e.g. to resolve imports
+ Thread.currentThread().setContextClassLoader(componentLoader);
+
// Do not generate descriptors for abstract classes, they cannot be instantiated.
if (Modifier.isAbstract(clazz.getModifiers())) {
continue;
}
-
+
ResourceCreationSpecifier desc = null;
ProcessingResourceMetaData metadata = null;
switch (Util.getType(componentLoader, clazz)) {
@@ -151,7 +157,7 @@
out.getParentFile().mkdirs();
toXML(desc, out.getPath());
countGenerated++;
-
+
// Remember component
componentsManifest.append("classpath*:").append(clazzPath + ".xml").append('\n');
}
@@ -163,12 +169,14 @@
getLog().warn("Cannot analyze class [" + clazzName + "]", e);
} catch (ResourceInitializationException e) {
getLog().warn("Cannot generate descriptor for [" + clazzName + "]", e);
+ } finally {
+ Thread.currentThread().setContextClassLoader(classLoader);
}
}
-
+
getLog().info(
"Generated " + countGenerated + " descriptor" + (countGenerated != 1 ? "s." : "."));
-
+
// Write META-INF/org.apache.uima.fit/components.txt unless skipped and unless there are no
// components
if (!skipComponentsManifest && componentsManifest.length() > 0) {
@@ -185,15 +193,9 @@
private void embedTypeSystems(ProcessingResourceMetaData metadata)
throws ResourceInitializationException {
- ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
- Thread.currentThread().setContextClassLoader(componentLoader);
- try {
- TypeSystemDescriptionFactory.forceTypeDescriptorsScan();
- TypeSystemDescription tsDesc = TypeSystemDescriptionFactory.createTypeSystemDescription();
- metadata.setTypeSystem(tsDesc);
- } finally {
- Thread.currentThread().setContextClassLoader(classLoader);
- }
+ TypeSystemDescriptionFactory.forceTypeDescriptorsScan();
+ TypeSystemDescription tsDesc = TypeSystemDescriptionFactory.createTypeSystemDescription();
+ metadata.setTypeSystem(tsDesc);
}
/**