This is an automated email from the ASF dual-hosted git repository.

rec pushed a commit to branch 
bugfix/315-ThreadContextClassLoader-ignored-by-ResourceManager-when-extension-classloader-is-set
in repository https://gitbox.apache.org/repos/asf/uima-uimaj.git

commit 0ebf16d4ca38998271300bf5c1b6b1aa29e84932
Author: Richard Eckart de Castilho <r...@apache.org>
AuthorDate: Thu Jun 29 10:36:43 2023 +0200

    Issue #315: ThreadContextClassLoader ignored by ResourceManager when 
extension classloader is set
    
    - Consider TCCL when looking for class
    - Improved exception where we hook up the suppressed exceptions from all 
the classloaders that failed and where the error message includes the 
classloaders as well
    - Deprecated two methods that are no longer used or should no longer be 
used because they would only take a single classloader into account instead of 
trying multiple
---
 .../org/apache/uima/internal/util/Class_TCCL.java  | 54 +++++++++++++++++++++-
 1 file changed, 52 insertions(+), 2 deletions(-)

diff --git 
a/uimaj-core/src/main/java/org/apache/uima/internal/util/Class_TCCL.java 
b/uimaj-core/src/main/java/org/apache/uima/internal/util/Class_TCCL.java
index e07010710..42355681f 100644
--- a/uimaj-core/src/main/java/org/apache/uima/internal/util/Class_TCCL.java
+++ b/uimaj-core/src/main/java/org/apache/uima/internal/util/Class_TCCL.java
@@ -19,7 +19,11 @@
 
 package org.apache.uima.internal.util;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
 
 import org.apache.uima.resource.Resource;
 import org.apache.uima.resource.ResourceManager;
@@ -52,11 +56,49 @@ public class Class_TCCL {
 
   static public <T> Class<T> forName(String className, ResourceManager rm, 
boolean resolve)
           throws ClassNotFoundException {
+    List<ClassLoader> clsTried = new ArrayList<>();
+    List<ClassNotFoundException> suppressedExceptions = new ArrayList<>();
+    
+    // Try extension classloader
+    if (rm != null) {
+      ClassLoader excl = rm.getExtensionClassLoader();
+      
+      if (excl != null) {
+        try {
+          return (Class<T>) Class.forName(className, resolve, excl);
+        }
+        catch (ClassNotFoundException e) {
+          clsTried.add(excl);
+          suppressedExceptions.add(e);
+        }
+      }
+    }
+    
+    // Try TCCL
+    ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+    if (tccl != null) {
+      try {
+        return (Class<T>) Class.forName(className, resolve, tccl);
+      }
+      catch (ClassNotFoundException e) {
+        clsTried.add(tccl);
+        suppressedExceptions.add(e);
+      }
+    }
+    
     try {
-      return (Class<T>) Class.forName(className, resolve, get_cl(rm));
-    } catch (ClassNotFoundException x) { //
       return (Class<T>) Class.forName(className, resolve, 
Class_TCCL.class.getClassLoader());
     }
+    catch (ClassNotFoundException e) {
+      clsTried.add(tccl);
+      suppressedExceptions.add(e);
+    }
+    
+    ClassNotFoundException e = new ClassNotFoundException(
+            "Class [" + className + "] not found in any of the accessible 
classloaders "
+                    + 
clsTried.stream().map(Objects::toString).collect(Collectors.joining(", ")));
+    suppressedExceptions.forEach(e::addSuppressed);
+    throw e;
   }
 
   static public <T> Class<T> forName(String className, Map<String, Object> 
additionalParams)
@@ -67,6 +109,10 @@ public class Class_TCCL {
     return forName(className, rm);
   }
 
+  /**
+   * @deprecated Method should not be used and will be removed in a future 
version.
+   */
+  @Deprecated
   static public ClassLoader get_cl(ResourceManager rm) {
 
     ClassLoader cl = (rm == null) ? null : rm.getExtensionClassLoader();
@@ -78,6 +124,10 @@ public class Class_TCCL {
     return cl;
   }
 
+  /**
+   * @deprecated Method should not be used and will be removed in a future 
version. 
+   */
+  @Deprecated
   static public ClassLoader get_parent_cl() {
     ClassLoader cl = Thread.currentThread().getContextClassLoader();
     return (cl == null) ? Class_TCCL.class.getClassLoader() : cl;

Reply via email to