-
Bug
-
Resolution: Unresolved
-
P3
-
None
-
8, 17
-
generic
-
generic
A DESCRIPTION OF THE PROBLEM :
## Problem Description
In `URLClassPath.getLoader(int)`, when processing JAR files with `META-INF/INDEX.LIST`, dependent JARs are pre-populated into the `lmap` with `null` values during `JarLoader.ensureOpen()`. Later, when `getLoader(int)` encounters these URLs, it skips creating actual Loaders because `lmap.containsKey()` returns `true`, but the value is `null`. This results in resources from these JARs being permanently unavailable.
## Root Cause
1. `JarLoader.ensureOpen()` pre-populates `lmap` with `null` for dependent JARs from INDEX.LIST
2. `URLClassPath.getLoader(int)` only checks `lmap.containsKey()` without verifying the actual value
3. JARs with `null` values in `lmap` are skipped and never added to the `loaders` list
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
## Reproduction Steps
1. **Development Environment**:
- JDK-17.0.16+8
- Apache Maven 3.9.1
2. **Create Maven Project**:
- Create a Maven project named "ResourcesProject"
- Ensure the dependency `org.springframework:spring-context:6.1.13` is included
- Configure `maven-jar-plugin` in `pom.xml` to include `<index>true</index>`
3. **Additional Configuration**:
- Configure `maven-jar-plugin` with `<classpathPrefix>lib</classpathPrefix>`
4. **Test Code**:
```java
public class ResourcesLoadTest {
public static void main(String[] args) {
ClassLoader cl = ResourcesLoadTest.class.getClassLoader();
String resourceName = "META-INF/spring.schemas";
Enumeration<URL> urls = null;
try {
urls = cl.getResources(resourceName);
} catch (IOException e) {
throw new RuntimeException(e);
}
int count = 0;
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
System.out.println(url);
count++;
}
System.out.println("Total: " + count);
assert count >= 3;
}
}
```
5. **Deployment and Execution**:
- Compile and package the Maven project
- Deploy to a Linux system
- Ensure `ResourcesProject.jar` is the first item in the classpath
- Execute with command: `java -ea -cp "ResourcesProject.jar:lib/*" ResourcesLoadTest`
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
- **Expected Result**: `AssertionError` will be thrown because the actual count of loaded resources is less than 3
ACTUAL -
jar:file:/home/liuyan1001/ResourcesProject/lib/spring-context-6.1.13.jar!/META-INF/spring.schemas
Total: 1
Exception in thread "main" java.lang.AssertionError
at com.ubitrans.ResourcesProject.ResourcesLoadTest.main(ResourcesLoadTest.java:24)
---------- BEGIN SOURCE ----------
public class ResourcesLoadTest {
public static void main(String[] args) {
ClassLoader cl = ResourcesLoadTest.class.getClassLoader();
String resourceName = "META-INF/spring.schemas";
Enumeration<URL> urls = null;
try {
urls = cl.getResources(resourceName);
} catch (IOException e) {
throw new RuntimeException(e);
}
int count = 0;
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
System.out.println(url);
count++;
}
System.out.println("Total: " + count);
assert count >= 3;
}
}
---------- END SOURCE ----------
## Problem Description
In `URLClassPath.getLoader(int)`, when processing JAR files with `META-INF/INDEX.LIST`, dependent JARs are pre-populated into the `lmap` with `null` values during `JarLoader.ensureOpen()`. Later, when `getLoader(int)` encounters these URLs, it skips creating actual Loaders because `lmap.containsKey()` returns `true`, but the value is `null`. This results in resources from these JARs being permanently unavailable.
## Root Cause
1. `JarLoader.ensureOpen()` pre-populates `lmap` with `null` for dependent JARs from INDEX.LIST
2. `URLClassPath.getLoader(int)` only checks `lmap.containsKey()` without verifying the actual value
3. JARs with `null` values in `lmap` are skipped and never added to the `loaders` list
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
## Reproduction Steps
1. **Development Environment**:
- JDK-17.0.16+8
- Apache Maven 3.9.1
2. **Create Maven Project**:
- Create a Maven project named "ResourcesProject"
- Ensure the dependency `org.springframework:spring-context:6.1.13` is included
- Configure `maven-jar-plugin` in `pom.xml` to include `<index>true</index>`
3. **Additional Configuration**:
- Configure `maven-jar-plugin` with `<classpathPrefix>lib</classpathPrefix>`
4. **Test Code**:
```java
public class ResourcesLoadTest {
public static void main(String[] args) {
ClassLoader cl = ResourcesLoadTest.class.getClassLoader();
String resourceName = "META-INF/spring.schemas";
Enumeration<URL> urls = null;
try {
urls = cl.getResources(resourceName);
} catch (IOException e) {
throw new RuntimeException(e);
}
int count = 0;
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
System.out.println(url);
count++;
}
System.out.println("Total: " + count);
assert count >= 3;
}
}
```
5. **Deployment and Execution**:
- Compile and package the Maven project
- Deploy to a Linux system
- Ensure `ResourcesProject.jar` is the first item in the classpath
- Execute with command: `java -ea -cp "ResourcesProject.jar:lib/*" ResourcesLoadTest`
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
- **Expected Result**: `AssertionError` will be thrown because the actual count of loaded resources is less than 3
ACTUAL -
jar:file:/home/liuyan1001/ResourcesProject/lib/spring-context-6.1.13.jar!/META-INF/spring.schemas
Total: 1
Exception in thread "main" java.lang.AssertionError
at com.ubitrans.ResourcesProject.ResourcesLoadTest.main(ResourcesLoadTest.java:24)
---------- BEGIN SOURCE ----------
public class ResourcesLoadTest {
public static void main(String[] args) {
ClassLoader cl = ResourcesLoadTest.class.getClassLoader();
String resourceName = "META-INF/spring.schemas";
Enumeration<URL> urls = null;
try {
urls = cl.getResources(resourceName);
} catch (IOException e) {
throw new RuntimeException(e);
}
int count = 0;
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
System.out.println(url);
count++;
}
System.out.println("Total: " + count);
assert count >= 3;
}
}
---------- END SOURCE ----------
- relates to
-
JDK-8273473 Disable JAR index support
-
- Closed
-
-
JDK-8305597 Remove JAR Index
-
- Closed
-