[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:12 UTC 2025


On Wed, 16 Jul 2025 07:06:29 GMT, Timofei Pushkin <tpushkin 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...
>
> Small comments from me, nothing functionally important

@TimPushkin I wonder if we should make `simengine` the default in `CracBuilder`; that way we can encourage everyone to test everywhere and use CRIU only when the test is really specific to any of its behaviour (which it shouldn't be for the most part - everything `Resource`-related is applicable to all engines).

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

PR Comment: https://git.openjdk.org/crac/pull/241#issuecomment-3088514822


More information about the crac-dev mailing list