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

Reply via email to