When used with the `--system` option to target a different modularized JDK, 
`JavacTask` keeps both `lib/jrt-fs.jar` and `lib/modules` open even after it 
completes.

The `lib/jrt-fs.jar` file remains open because the host-side 
`JrtFileSystemProvider` creates a `URLClassLoader` to load the target 
platform's `JrtFileSystemProvider` from `lib/jrt-fs.jar` when creating a 
`JrtFileSystem`. This `URLClassLoader` is never closed, causing the file to 
remain open.

The `lib/modules` file remains open because `BasicImageReader` uses a 
memory-mapped file whose mapping persists until the associated buffer is 
garbage-collected.

To ensure that `lib/jrt-fs.jar` is properly closed, the proposed solution is to 
make the client responsible for closing the file system's class loader when 
"java.home" is passed in the `env` argument to `FileSystems.newFileSystem(...)`.
This approach (currently implemented in the `Locations` class) is simple and 
works reliably even with older target platform versions. (An alternative 
approach would be to automatically close the `URLClassLoader` when the 
`JrtFileSystem` is closed. However, this solution has two significant 
drawbacks. First, it does not work with older target platform versions because 
it requires modifications to the target platform's `JrtFileSystem` 
implementation. Second, it is not reliable. A user may obtain a reference to 
the provider that created a `JrtFileSystem` instance, close that instance, and 
then use the same provider to create another `JrtFileSystem`. In that case, the 
provider's `URLClassLoader` may have already been closed automatically, 
preventing the creation of the new file system instance).

To ensure that `lib/modules` is properly closed, the proposed solution is to 
modify `BasicImageReader` so that it uses memory-mapped I/O only for the 
current runtime and falls back to regular file I/O when accessing a different 
target system. (An alternative solution would be to explicitly unmap the 
memory-mapped file when the reader is closed. On JDK 22 and later, the Foreign 
Function & Memory API could be used for that purpose. However, in that case, 
`lib/jrt-fs.jar` could no longer be compiled to run on JDK 8). Note that 
neither of these solutions work for older target platform versions, as both 
require changes to the target platform's `BasicImageReader` implementation.


---------
- [x] I confirm that I make this contribution in accordance with the [OpenJDK 
Interim AI Policy](https://openjdk.org/legal/ai).

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

Commit messages:
 - 8357249: Compiler task keeps --system files open

Changes: https://git.openjdk.org/jdk/pull/31417/files
  Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=31417&range=00
  Issue: https://bugs.openjdk.org/browse/JDK-8357249
  Stats: 158 lines in 3 files changed: 138 ins; 9 del; 11 mod
  Patch: https://git.openjdk.org/jdk/pull/31417.diff
  Fetch: git fetch https://git.openjdk.org/jdk.git pull/31417/head:pull/31417

PR: https://git.openjdk.org/jdk/pull/31417

Reply via email to