[crac] RFR: [CRaC] Support checkpointing with --patch-module by treating patch JARs as persistent

Radim Vansa rvansa at openjdk.org
Mon Aug 4 18:42:10 UTC 2025


On Thu, 10 Jul 2025 03:11:03 GMT, mazhen <duke at openjdk.org> wrote:

> #### Summary
> 
> This change enhances CRaC's checkpointing capabilities to correctly handle applications launched with the `--patch-module` option. Previously, using a JAR file with `--patch-module` would cause checkpointing to fail due to unmanaged file descriptors. This patch resolves the issue by treating these JARs as persistent resources, similar to how classpath JARs are handled.
> 
> #### Problem
> 
> When a JAR file is specified via `--patch-module`, it is opened by two distinct mechanisms within the JVM:
> 
> 1.  **Native `ClassLoader`**: The C++ `ClassLoader` implementation opens the JAR file to build its internal class path structures. This results in a file descriptor that is not managed by CRaC's Java-level resource tracking, leading to it being flagged as a "BAD: opened by application" file during `check_fds`.
> 2.  **Java `ModulePatcher`**: The Java-level `jdk.internal.module.ModulePatcher` also opens the same JAR to scan for packages and resources. While this could be made CRaC-aware, the native-level file descriptor remains an issue.
> 
> This dual-opening mechanism leads to `CheckpointOpenFileException` being thrown for both file descriptors during a checkpoint, preventing a successful image creation. The log output clearly illustrates this problem:
> 
> 
> $ jcmd 3403046 JDK.checkpoint
> 3403046:
> ...
> JVM: FD fd=4 type=regular path="/home/mazhen/works/patch-demo/legacy-patch.jar" BAD: opened by application
> JVM: FD fd=5 type=regular path="/home/mazhen/works/patch-demo/legacy-patch.jar" OK: claimed by java code
> ...
> An exception during a checkpoint operation:
> jdk.internal.crac.mirror.CheckpointException
>     Suppressed: jdk.internal.crac.mirror.impl.CheckpointOpenFileException: legacy-patch.jar
>         at java.base/jdk.internal.crac.JDKFileResource.lambda$beforeCheckpoint$0(JDKFileResource.java:90)
>         ...
>     Caused by: java.lang.Exception: This file descriptor was created by main at epoch:1752027938791 here
>         at java.base/jdk.internal.crac.JDKFdResource.<init>(JDKFdResource.java:40)
>         ...
>         at java.base/jdk.internal.module.ModulePatcher$JarResourceFinder.<init>(ModulePatcher.java:433)
>         ...
>     Suppressed: jdk.internal.crac.mirror.impl.CheckpointOpenFileException: FD fd=4 type=regular path=/home/mazhen/works/patch-demo/legacy-patch.jar
>         at java.base/jdk.internal.crac.mirror.Core.translateJVMExceptions(Core.java:115)
>         ...
> 
> 
> #### Solution
> 
> The fundamental assumption behind this solution is that JARs provided via `--patch-module` ...

Thank you for the contribution! The change looks good in general, could you add a JTReg test that demonstrates that this is working as expected, and make sure that the CI runs it?

Great work, let's just sort out the OCA and enable running the testsuite in your repo.

Btw. the test could work using just `simengine` (there's nothing engine-specific and that would let us run on other platforms than only Linux) but it's OK to keep this on a real engine (CRIU).

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

PR Review: https://git.openjdk.org/crac/pull/241#pullrequestreview-3016754271
Marked as reviewed by rvansa (Committer).

PR Review: https://git.openjdk.org/crac/pull/241#pullrequestreview-3032569774


More information about the crac-dev mailing list