RFR: 8375580: Avoid using ArrayDeque in jdk.internal.loader.URLClassPath

Chen Liang liach at openjdk.org
Mon Jan 19 17:44:57 UTC 2026


On Sat, 17 Jan 2026 21:56:05 GMT, Eirik Bjørsnøs <eirbjo at openjdk.org> wrote:

> Please review this PR which proposes we replace `j.u.ArrayDeque` with `j.u.ArrayList` in `jdk.internal.loader.URLClassPath`.
> 
> The motivation for using a double-ended queue may have been that "original" search path URLs are added to the tail of the queue while any "loader discovered" class path URLs are inserted at the head such that they are processed first.
> 
> By splitting these two concerns and processing  loader discovered class path URLs separately from the original search path, we no longer need a double-ended queue. We can replace `ArrayDeque` with `ArrayList`.
> 
> Advantages:
> 
> * A "hello world" Java program no longer  loads `ArrayDeque`, `Deque` and `Queue` (`URLClassPath` is the only consumer of these classes during startup)
> * One data structure is simpler than two
> * We no longer need to manage search path URLs across two different collections 
> * Code and comments to dance around `ArrayDeque` calling into lambda too early is no longer a concern and can be removed
> * I think this PR leaves the code overall simpler and easier to follow.
> 
> Testing:
> 
> This PR introduces a new test to verify that URLs disovered via a multi-level tree paths discovered via `Class-Path` JAR attributes are found in the expected DFS order. The ordering aspect seems to lack existing coverage.

Looks much better and thanks for the test, but I still think `loaderPath` might be renamed to `expandedJars` or something similar to indicate the nature of those urls. (You can consider renaming `push` too)

The code looks good to me logically.

The rename is a net improvement for code readability. 👍

src/java.base/share/classes/jdk/internal/loader/URLClassPath.java line 107:

> 105: 
> 106:     /* A list of loader-discovered URLs, if any */
> 107:     private ArrayList<URL> loaderPath;

Document these three variables' accesses are guarded by monitor on `path`.

In addition, this is probably more accurately called `dfsUrls`, because they are paths waiting for expansion from a DFS.

src/java.base/share/classes/jdk/internal/loader/URLClassPath.java line 371:

> 369:      * Returns the next URL to process or null if finished
> 370:      */
> 371:     private URL nextURL() {

Document that this method must be called when holding a lock on `path`

src/java.base/share/classes/jdk/internal/loader/URLClassPath.java line 485:

> 483:             // Lazily create list
> 484:             if (loaderPath  == null) {
> 485:                 loaderPath = new ArrayList<>();

This will always be used if we are using `JarLoader`, which seems to be used in the majority of cases. I recommend initializing this dfs variable unconditionally.

src/java.base/share/classes/jdk/internal/loader/URLClassPath.java line 490:

> 488:             for (int i = urls.length - 1; i >= 0; --i) {
> 489:                 loaderPath.addLast(urls[i]);
> 490:             }

Should we do `dfsUrls.addAll(Arrays.asList(urls).reversed())` for simplicity?

src/java.base/share/classes/jdk/internal/loader/URLClassPath.java line 490:

> 488:     private void addExpandedPaths(URL[] urls) {
> 489:         synchronized (searchPath) {
> 490:             // Adding in reversed order since URLs are consumed tail-first

Suggestion:

            // Adding in reversed order since expandedPath is consumed tail-first

-------------

PR Review: https://git.openjdk.org/jdk/pull/29288#pullrequestreview-3676106618
Marked as reviewed by liach (Reviewer).

PR Review: https://git.openjdk.org/jdk/pull/29288#pullrequestreview-3679120128
PR Comment: https://git.openjdk.org/jdk/pull/29288#issuecomment-3769348993
PR Review Comment: https://git.openjdk.org/jdk/pull/29288#discussion_r2702193525
PR Review Comment: https://git.openjdk.org/jdk/pull/29288#discussion_r2702193246
PR Review Comment: https://git.openjdk.org/jdk/pull/29288#discussion_r2702220970
PR Review Comment: https://git.openjdk.org/jdk/pull/29288#discussion_r2702222377
PR Review Comment: https://git.openjdk.org/jdk/pull/29288#discussion_r2705527983


More information about the core-libs-dev mailing list