This is an automated email from the ASF dual-hosted git repository. rec pushed a commit to branch feature/226-Provide-SPI-interfaces-to-locate-descriptors-and-JCas-classes in repository https://gitbox.apache.org/repos/asf/uima-uimaj.git
commit 1571bdd6c5a8329a7d4061c46dfb707fae3438db Author: Richard Eckart de Castilho <[email protected]> AuthorDate: Mon Aug 29 15:56:24 2022 +0200 Issue #226: Provide SPI interfaces to locate descriptors and JCas classes - When obtaining a MH for a lookup through a custom classloader, make sure it is a UIMAClassLoader because otherwise the MHLC magic cannot work and the JCas classes get loaded through the wrong classloader - in particular applies to SPIs in an OSGI environment --- .../org/apache/uima/cas/impl/FSClassRegistry.java | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSClassRegistry.java b/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSClassRegistry.java index b0142d3e6..36999e48d 100644 --- a/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSClassRegistry.java +++ b/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSClassRegistry.java @@ -34,6 +34,7 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Parameter; +import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -198,6 +199,8 @@ public abstract class FSClassRegistry { // abstract to prevent instantiating; th private static final WeakIdentityMap<ClassLoader, StackTraceElement[]> cl_to_type2JCasStacks; private static final WeakIdentityMap<ClassLoader, Map<String, Class<? extends TOP>>> cl_to_spiJCas = WeakIdentityMap .newHashMap(); + private static final WeakIdentityMap<ClassLoader, UIMAClassLoader> cl_to_uimaCl = WeakIdentityMap + .newHashMap(); // private static final Map<ClassLoader, Map<String, JCasClassInfo>> cl_4pears_to_type2JCas = // Collections.synchronizedMap(new IdentityHashMap<>()); // identity: key is classloader @@ -1749,10 +1752,27 @@ public abstract class FSClassRegistry { // abstract to prevent instantiating; th } } + private static final URL[] NO_URLS = new URL[0]; + static Lookup getLookup(ClassLoader cl) { Lookup lookup = null; try { - Class<?> clazz = Class.forName(UIMAClassLoader.MHLC, true, cl); + // The UIMAClassLoader has special handling for the MHLC, so we must make sure that the CL + // we are using is actually a UIMAClassLoader, otherwise the MHCL will look up in the wrong + // CL. This is in particular an issue for classes loaded through the SPI mechanism. + UIMAClassLoader ucl; + if (!(cl instanceof UIMAClassLoader)) { + ucl = cl_to_uimaCl.get(cl); + if (ucl == null ) { + ucl = new UIMAClassLoader(NO_URLS, cl); + cl_to_uimaCl.put(cl, ucl); + } + } + else { + ucl = (UIMAClassLoader) cl; + } + + Class<?> clazz = Class.forName(UIMAClassLoader.MHLC, true, ucl); Method m = clazz.getMethod("getMethodHandlesLookup"); lookup = (Lookup) m.invoke(null); } catch (ClassNotFoundException | NoSuchMethodException | SecurityException
