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

felixybw pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gluten.git


The following commit(s) were added to refs/heads/main by this push:
     new ed93689677 [GLUTEN-XXXX][CORE] Fix URL-encoded paths in ResourceUtil 
causing JAR loading failures (#11672)
ed93689677 is described below

commit ed93689677a4f2b872f5c150ac00b4686a4d2e86
Author: Chungmin Lee <[email protected]>
AuthorDate: Thu Apr 9 17:44:24 2026 -0700

    [GLUTEN-XXXX][CORE] Fix URL-encoded paths in ResourceUtil causing JAR 
loading failures (#11672)
    
    Fix URL-encoded path handling in ResourceUtil.getResources() by using 
URL.toURI() and URI for proper path decoding instead of URL.getPath().
---
 .../java/org/apache/gluten/utils/ResourceUtil.java | 43 +++++++++++++---------
 .../org/apache/gluten/util/ResourceUtilTest.java   | 13 +++++++
 2 files changed, 39 insertions(+), 17 deletions(-)

diff --git 
a/gluten-core/src/main/java/org/apache/gluten/utils/ResourceUtil.java 
b/gluten-core/src/main/java/org/apache/gluten/utils/ResourceUtil.java
index 80cc1fc9dd..d1a8279320 100644
--- a/gluten-core/src/main/java/org/apache/gluten/utils/ResourceUtil.java
+++ b/gluten-core/src/main/java/org/apache/gluten/utils/ResourceUtil.java
@@ -24,6 +24,8 @@ import org.slf4j.LoggerFactory;
 
 import java.io.File;
 import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
 import java.net.URL;
 import java.util.*;
 import java.util.regex.Matcher;
@@ -73,26 +75,33 @@ public class ResourceUtil {
     final String protocol = containerUrl.getProtocol();
     switch (protocol) {
       case "file":
-        final File fileContainer = new File(containerUrl.getPath());
-        Preconditions.checkState(
-            fileContainer.exists() && fileContainer.isDirectory(),
-            "Specified file container " + containerUrl + " is not a directory 
or not a file");
-        getResourcesFromDirectory(fileContainer, fileContainer, pattern, 
buffer);
+        try {
+          final File fileContainer = new File(containerUrl.toURI());
+          Preconditions.checkState(
+              fileContainer.exists() && fileContainer.isDirectory(),
+              "Specified file container " + containerUrl + " is not a 
directory or not a file");
+          getResourcesFromDirectory(fileContainer, fileContainer, pattern, 
buffer);
+        } catch (URISyntaxException e) {
+          throw new GlutenException(e);
+        }
         break;
       case "jar":
-        final String jarContainerPath = containerUrl.getPath();
-        final Pattern jarContainerPattern = 
Pattern.compile("file:([^!]+)!/(.+)");
-        final Matcher m = jarContainerPattern.matcher(jarContainerPath);
-        if (!m.matches()) {
-          throw new GlutenException("Illegal Jar container URL: " + 
containerUrl);
+        try {
+          final String jarContainerPath = containerUrl.getPath();
+          final Pattern jarContainerPattern = 
Pattern.compile("file:([^!]+)!/(.+)");
+          final Matcher m = jarContainerPattern.matcher(jarContainerPath);
+          if (!m.matches()) {
+            throw new GlutenException("Illegal Jar container URL: " + 
containerUrl);
+          }
+          final File jarFile = new File(new URI("file://" + m.group(1)));
+          Preconditions.checkState(
+              jarFile.exists() && jarFile.isFile(),
+              "Specified Jar container " + containerUrl + " is not a Jar 
file");
+          final String dir = m.group(2);
+          getResourcesFromJarFile(jarFile, dir, pattern, buffer);
+        } catch (URISyntaxException e) {
+          throw new GlutenException(e);
         }
-        final String jarPath = m.group(1);
-        final File jarFile = new File(jarPath);
-        Preconditions.checkState(
-            jarFile.exists() && jarFile.isFile(),
-            "Specified Jar container " + containerUrl + " is not a Jar file");
-        final String dir = m.group(2);
-        getResourcesFromJarFile(jarFile, dir, pattern, buffer);
         break;
       default:
         throw new GlutenException("Unrecognizable resource protocol: " + 
protocol);
diff --git 
a/gluten-core/src/test/java/org/apache/gluten/util/ResourceUtilTest.java 
b/gluten-core/src/test/java/org/apache/gluten/util/ResourceUtilTest.java
index 570e5a6e4d..c28ec2fafd 100644
--- a/gluten-core/src/test/java/org/apache/gluten/util/ResourceUtilTest.java
+++ b/gluten-core/src/test/java/org/apache/gluten/util/ResourceUtilTest.java
@@ -21,6 +21,7 @@ import org.apache.gluten.utils.ResourceUtil;
 import org.junit.Assert;
 import org.junit.Test;
 
+import java.net.URI;
 import java.util.List;
 import java.util.regex.Pattern;
 
@@ -43,4 +44,16 @@ public class ResourceUtilTest {
     Assert.assertEquals(1, classes.size());
     Assert.assertEquals("apache/spark/SparkContext.class", classes.get(0));
   }
+
+  /** Verifies URI correctly decodes percent-encoded paths and preserves '+' 
characters. */
+  @Test
+  public void testUriDecodesPercentEncodedPaths() throws Exception {
+    // %40 should decode to @
+    URI uri1 = new URI("file:///path/user%40domain/file.jar");
+    Assert.assertEquals("/path/user@domain/file.jar", uri1.getPath());
+
+    // + should be preserved (not converted to space like URLDecoder does)
+    URI uri2 = new URI("file:///path/file+name.jar");
+    Assert.assertEquals("/path/file+name.jar", uri2.getPath());
+  }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to