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

garydgregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-lang.git


The following commit(s) were added to refs/heads/master by this push:
     new e985f2eec [LANG-1838] Fix resource paths for unnamed packages (#1824)
e985f2eec is described below

commit e985f2eec421adac19fbf070734cee0a1348d61f
Author: Aryan R. Ganjoo <[email protected]>
AuthorDate: Sun Oct 18 00:34:10 2026 +0530

    [LANG-1838] Fix resource paths for unnamed packages (#1824)
    
    Return the unprefixed resource name for an empty Package name, and handle 
Java 8 unnamed-package classes whose getPackage() is null. Add focused 
regressions for class and Package overloads while retaining named-package and 
null behavior.
    
    AI-Assisted-by: OpenAI Codex
---
 .../org/apache/commons/lang3/ClassPathUtils.java   | 14 +++++---
 src/test/java/ClassPathUtilsDefaultPackage.java    | 25 +++++++++++++
 .../apache/commons/lang3/ClassPathUtilsTest.java   | 42 ++++++++++++++++++++++
 3 files changed, 77 insertions(+), 4 deletions(-)

diff --git a/src/main/java/org/apache/commons/lang3/ClassPathUtils.java 
b/src/main/java/org/apache/commons/lang3/ClassPathUtils.java
index 52b452b62..6fff8732d 100644
--- a/src/main/java/org/apache/commons/lang3/ClassPathUtils.java
+++ b/src/main/java/org/apache/commons/lang3/ClassPathUtils.java
@@ -73,7 +73,9 @@ public static String pathToPackage(final String path) {
     public static String toFullyQualifiedName(final Class<?> context, final 
String resourceName) {
         Objects.requireNonNull(context, "context");
         Objects.requireNonNull(resourceName, "resourceName");
-        return toFullyQualifiedName(context.getPackage(), resourceName);
+        final Package contextPackage = context.getPackage();
+        return contextPackage == null && !context.isArray() && 
!context.isPrimitive() && context.getName().indexOf('.') < 0
+                ? resourceName : 
toFullyQualifiedName(Objects.requireNonNull(contextPackage, "context"), 
resourceName);
     }
 
     /**
@@ -95,7 +97,8 @@ public static String toFullyQualifiedName(final Class<?> 
context, final String r
     public static String toFullyQualifiedName(final Package context, final 
String resourceName) {
         Objects.requireNonNull(context, "context");
         Objects.requireNonNull(resourceName, "resourceName");
-        return context.getName() + "." + resourceName;
+        final String packageName = context.getName();
+        return packageName.isEmpty() ? resourceName : packageName + "." + 
resourceName;
     }
 
     /**
@@ -117,7 +120,9 @@ public static String toFullyQualifiedName(final Package 
context, final String re
     public static String toFullyQualifiedPath(final Class<?> context, final 
String resourceName) {
         Objects.requireNonNull(context, "context");
         Objects.requireNonNull(resourceName, "resourceName");
-        return toFullyQualifiedPath(context.getPackage(), resourceName);
+        final Package contextPackage = context.getPackage();
+        return contextPackage == null && !context.isArray() && 
!context.isPrimitive() && context.getName().indexOf('.') < 0
+                ? resourceName : 
toFullyQualifiedPath(Objects.requireNonNull(contextPackage, "context"), 
resourceName);
     }
 
     /**
@@ -139,7 +144,8 @@ public static String toFullyQualifiedPath(final Class<?> 
context, final String r
     public static String toFullyQualifiedPath(final Package context, final 
String resourceName) {
         Objects.requireNonNull(context, "context");
         Objects.requireNonNull(resourceName, "resourceName");
-        return packageToPath(context.getName()) + "/" + resourceName;
+        final String packageName = context.getName();
+        return packageName.isEmpty() ? resourceName : 
packageToPath(packageName) + "/" + resourceName;
     }
 
     /**
diff --git a/src/test/java/ClassPathUtilsDefaultPackage.java 
b/src/test/java/ClassPathUtilsDefaultPackage.java
new file mode 100644
index 000000000..ce18f143d
--- /dev/null
+++ b/src/test/java/ClassPathUtilsDefaultPackage.java
@@ -0,0 +1,25 @@
+/*
+ * 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
+ *
+ *      https://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.
+ */
+
+/**
+ * A class in the unnamed package for {@code ClassPathUtilsTest}.
+ */
+public final class ClassPathUtilsDefaultPackage {
+
+    private ClassPathUtilsDefaultPackage() {
+    }
+}
diff --git a/src/test/java/org/apache/commons/lang3/ClassPathUtilsTest.java 
b/src/test/java/org/apache/commons/lang3/ClassPathUtilsTest.java
index 50759d365..8dc62acd0 100644
--- a/src/test/java/org/apache/commons/lang3/ClassPathUtilsTest.java
+++ b/src/test/java/org/apache/commons/lang3/ClassPathUtilsTest.java
@@ -31,6 +31,14 @@
  */
 class ClassPathUtilsTest extends AbstractLangTest {
 
+    private static Package unnamedPackage() {
+        return new ClassLoader() {
+            Package defineUnnamedPackage() {
+                return definePackage("", null, null, null, null, null, null, 
null);
+            }
+        }.defineUnnamedPackage();
+    }
+
     @Test
     void testConstructor() {
         assertNotNull(new ClassPathUtils());
@@ -60,6 +68,12 @@ void testToFullyQualifiedNameClassNull() {
         assertNullPointerException(() -> 
ClassPathUtils.toFullyQualifiedName(ClassPathUtils.class, null));
     }
 
+    @Test
+    void testToFullyQualifiedNameArrayAndPrimitiveClass() {
+        assertNullPointerException(() -> 
ClassPathUtils.toFullyQualifiedName(String[].class, "Test.properties"));
+        assertNullPointerException(() -> 
ClassPathUtils.toFullyQualifiedName(int.class, "Test.properties"));
+    }
+
     @Test
     void testToFullyQualifiedNameClassString() {
         final String expected = "org.apache.commons.lang3.Test.properties";
@@ -94,6 +108,17 @@ void testToFullyQualifiedNamePackageString() {
         assertEquals(expected, actual);
     }
 
+    @Test
+    void testToFullyQualifiedNameUnnamedPackage() {
+        assertEquals("Test.properties", 
ClassPathUtils.toFullyQualifiedName(unnamedPackage(), "Test.properties"));
+    }
+
+    @Test
+    void testToFullyQualifiedNameUnnamedPackageClass() throws 
ClassNotFoundException {
+        assertEquals("Test.properties", ClassPathUtils.toFullyQualifiedName(
+                Class.forName("ClassPathUtilsDefaultPackage"), 
"Test.properties"));
+    }
+
     @Test
     void testToFullyQualifiedPathClass() {
         final String expected = "org/apache/commons/lang3/Test.properties";
@@ -107,6 +132,12 @@ void testToFullyQualifiedPathClassNull() {
         assertNullPointerException(() -> 
ClassPathUtils.toFullyQualifiedPath(ClassPathUtils.class, null));
     }
 
+    @Test
+    void testToFullyQualifiedPathArrayAndPrimitiveClass() {
+        assertNullPointerException(() -> 
ClassPathUtils.toFullyQualifiedPath(String[].class, "Test.properties"));
+        assertNullPointerException(() -> 
ClassPathUtils.toFullyQualifiedPath(int.class, "Test.properties"));
+    }
+
     @Test
     void testToFullyQualifiedPathClassNullString() {
         assertNullPointerException(
@@ -132,4 +163,15 @@ void testToFullyQualifiedPathPackageNullString() {
         assertNullPointerException(
                 () -> ClassPathUtils.toFullyQualifiedPath((Package) null, 
"Test.properties"));
     }
+
+    @Test
+    void testToFullyQualifiedPathUnnamedPackage() {
+        assertEquals("Test.properties", 
ClassPathUtils.toFullyQualifiedPath(unnamedPackage(), "Test.properties"));
+    }
+
+    @Test
+    void testToFullyQualifiedPathUnnamedPackageClass() throws 
ClassNotFoundException {
+        assertEquals("Test.properties", ClassPathUtils.toFullyQualifiedPath(
+                Class.forName("ClassPathUtilsDefaultPackage"), 
"Test.properties"));
+    }
 }

Reply via email to