Skip to content

Commit

Permalink
Merge pull request #401 from apache/bugfix/385-Allow-import-of-type-s…
Browse files Browse the repository at this point in the history
…ystems-published-through-SPI

Issue #385: Allow import of type systems published through SPI
  • Loading branch information
reckart authored Oct 10, 2024
2 parents 9d5b6e4 + 18dbf96 commit e333ce0
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,17 @@
package org.apache.uima.fit.internal;

import org.apache.uima.UimaContext;
import org.apache.uima.UimaContextAdmin;
import org.apache.uima.UimaContextHolder;
import org.apache.uima.resource.ResourceManager;
import org.springframework.util.ClassUtils;

/**
* INTERNAL API - Helper functions to obtain a suitable classloader.
*
* @deprecated Use {@link org.apache.uima.internal.util.ClassLoaderUtils} instead.
* @forRemoval 4.0.0
*/
@Deprecated(since = "3.6.0")
public final class ClassLoaderUtils {
private ClassLoaderUtils() {
// No instances
Expand All @@ -45,23 +48,7 @@ private ClassLoaderUtils() {
* @return a classloader or {@code null} if no suitable classloader could be found.
*/
public static ClassLoader findClassloader() {
ClassLoader uimaThreadContextClassLoader = getExtensionClassloader(
UimaContextHolder.getContext());
if (uimaThreadContextClassLoader != null) {
return uimaThreadContextClassLoader;
}

ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
if (contextClassLoader != null) {
return contextClassLoader;
}

ClassLoader uimaFITClassLoader = ClassLoaderUtils.class.getClassLoader();
if (uimaFITClassLoader != null) {
return uimaFITClassLoader;
}

return ClassUtils.getDefaultClassLoader();
return org.apache.uima.internal.util.ClassLoaderUtils.findClassLoader();
}

/**
Expand All @@ -74,12 +61,7 @@ public static ClassLoader findClassloader() {
* @return a classloader or {@code null} if no suitable classloader could be found.
*/
public static ClassLoader findClassloader(ResourceManager aResMgr) {
ClassLoader resourceManagerExtensionClassloader = getExtensionClassloader(aResMgr);
if (resourceManagerExtensionClassloader != null) {
return resourceManagerExtensionClassloader;
}

return findClassloader();
return org.apache.uima.internal.util.ClassLoaderUtils.findClassLoader(aResMgr);
}

/**
Expand All @@ -93,32 +75,6 @@ public static ClassLoader findClassloader(ResourceManager aResMgr) {
* @return a classloader or {@code null} if no suitable classloader could be found.
*/
public static ClassLoader findClassloader(UimaContext aContext) {
ClassLoader uimaContextExtensionClassloader = getExtensionClassloader(aContext);
if (uimaContextExtensionClassloader != null) {
return uimaContextExtensionClassloader;
}

return findClassloader((ResourceManager) null);
}

private static ClassLoader getExtensionClassloader(UimaContext aContext) {
if (aContext instanceof UimaContextAdmin) {
return getExtensionClassloader(((UimaContextAdmin) aContext).getResourceManager());
}

return null;
}

private static ClassLoader getExtensionClassloader(ResourceManager aResMgr) {
if (aResMgr == null) {
return null;
}

ClassLoader cl = aResMgr.getExtensionClassLoader();
if (cl != null) {
return aResMgr.getExtensionClassLoader();
}

return null;
return org.apache.uima.internal.util.ClassLoaderUtils.findClassLoader(aContext);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* 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
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.uima.internal.util;

import org.apache.uima.UIMAFramework;
import org.apache.uima.UimaContext;
import org.apache.uima.UimaContextAdmin;
import org.apache.uima.UimaContextHolder;
import org.apache.uima.resource.ResourceManager;

/**
* INTERNAL API - Helper functions to obtain a suitable class loader.
*/
public final class ClassLoaderUtils {
private ClassLoaderUtils() {
// No instances
}

/**
* Looks up a suitable class loader in the following order:
*
* <ol>
* <li>The {@link UimaContext} in the {@link UimaContextHolder} of the current thread(if any)</li>
* <li>The current thread-context class loader (if any)</li>
* <li>The class loader through which uimaFIT (i.e. this class) was loaded.</li>
* <li>For backwards compatibility then delegates to {@link #getDefaultClassLoader()}</li>
* </ol>
*
* @return a class loader or {@code null} if no suitable class loader could be found.
*/
public static ClassLoader findClassLoader() {
var uimaThreadContextClassLoader = getExtensionClassLoader(UimaContextHolder.getContext());
if (uimaThreadContextClassLoader != null) {
return uimaThreadContextClassLoader;
}

var contextClassLoader = Thread.currentThread().getContextClassLoader();
if (contextClassLoader != null) {
return contextClassLoader;
}

var uimaFITClassLoader = ClassLoaderUtils.class.getClassLoader();
if (uimaFITClassLoader != null) {
return uimaFITClassLoader;
}

return getDefaultClassLoader();
}

/**
* Looks up a suitable class loader in the following order:
*
* <ol>
* <li>The extension class loader of the given {@link ResourceManager}</li>
* <li>See {@link #findClassLoader()}</li>
* </ol>
*
* @return a class loader or {@code null} if no suitable class loader could be found.
*/
public static ClassLoader findClassLoader(ResourceManager aResMgr) {
var resourceManagerExtensionClassloader = getExtensionClassLoader(aResMgr);
if (resourceManagerExtensionClassloader != null) {
return resourceManagerExtensionClassloader;
}

return findClassLoader();
}

/**
* Looks up a suitable class loader in the following order:
*
* <ol>
* <li>The extension class loader of the {@link ResourceManager} associated with the given
* {@link UimaContext} (if any)</li>
* <li>See {@link #findClassLoader(ResourceManager)}</li>
* </ol>
*
* @return a class loader or {@code null} if no suitable class loader could be found.
*/
public static ClassLoader findClassLoader(UimaContext aContext) {
var uimaContextExtensionClassloader = getExtensionClassLoader(aContext);
if (uimaContextExtensionClassloader != null) {
return uimaContextExtensionClassloader;
}

return findClassLoader((ResourceManager) null);
}

private static ClassLoader getExtensionClassLoader(UimaContext aContext) {
if (aContext instanceof UimaContextAdmin) {
return getExtensionClassLoader(((UimaContextAdmin) aContext).getResourceManager());
}

return null;
}

private static ClassLoader getExtensionClassLoader(ResourceManager aResMgr) {
if (aResMgr == null) {
return null;
}

var cl = aResMgr.getExtensionClassLoader();
if (cl != null) {
return cl;
}

return null;
}

private static ClassLoader getDefaultClassLoader() {
ClassLoader cl;
try {
cl = Thread.currentThread().getContextClassLoader();
if (cl != null) {
return cl;
}
} catch (Throwable ex) {
// Fall-through
}

try {
cl = UIMAFramework.class.getClassLoader();
if (cl != null) {
return cl;
}
} catch (Throwable ex) {
// Fall-through
}

try {
cl = ClassLoader.getSystemClassLoader();
if (cl != null) {
return cl;
}
} catch (Throwable ex) {
// Fall-through
}

return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
//@formatter:off
/**
* Utilities supporting a unified approach to loading classes,
* incorporating the resource manager's classloader if available,
* incorporating the resource manager's class loader if available,
* and making use of the Thread Context Class Loader (TCCL)
*
* For backwards compatibility, if a class is not found using the
Expand Down Expand Up @@ -108,7 +108,7 @@ public static <T> Class<T> forName(String className, Map<String, Object> additio

/**
* @deprecated Method should not be used because if an extension classloader is set, the thread
* context classloader. It will be ignored and will be removed in a future version.
* context classloader will be ignored. It will be removed in a future version.
* @forRemoval 4.0.0
*/
@Deprecated(since = "3.5.0")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.util.ServiceLoader;

import org.apache.uima.UIMAFramework;
import org.apache.uima.internal.util.ClassLoaderUtils;
import org.apache.uima.resource.ResourceManager;
import org.apache.uima.resource.metadata.Import;
import org.apache.uima.spi.TypeSystemProvider;
Expand Down Expand Up @@ -130,7 +131,8 @@ private URL findResouceUrlByName(ResourceManager aResourceManager, String name)

// If that fails, try loading through the SPIs
if (url == null) {
var providers = ServiceLoader.load(TypeSystemProvider.class);
var cl = ClassLoaderUtils.findClassLoader(aResourceManager);
var providers = ServiceLoader.load(TypeSystemProvider.class, cl);
for (var provider : providers) {
var maybeTypeSystemUrl = provider.findResourceUrl(name);
if (maybeTypeSystemUrl.isPresent()) {
Expand Down

0 comments on commit e333ce0

Please sign in to comment.