Using AOTCaching with debug (JDWP)
ioi.lam at oracle.com
ioi.lam at oracle.com
Fri Jan 30 05:20:37 UTC 2026
Hi Charlie,
The exit problem you mentioned below has been fixed in JDK 26 since
https://bugs.openjdk.org/browse/JDK-8362561.
While the bug title is about the AllowArchivingWithJavaAgent flag, this
RFE also removed the "CDS dumping does not support native JVMTI agent" check
As of JDK 26, the handling of Java agents in various of CDS/AOT dumping
scenario:
JVMTI agents are allowed in the command line in all cases below.
1. Static CDS dump - JVMTI agent options are effectively ignored. The
agents are not loaded.
2. Dynamic CDS dump - JVMTI agents are executed as usual. Any classes
modified by the agents are excluded from the dynamic archive.
3. Dumping AOT config file (AOT training run) - JVMTI agents are
executed as usual. Any classes modified by the agents are excluded from
the AOT config file.
4. Dumping AOT cache file (AOT assembly phase) - JVMTI agent options are
effectively ignored. The agents are not loaded.
Thanks
- Ioi
On 1/27/26 9:15 AM, Charles Oliver Nutter wrote:
> FWIW I run into this with JRuby, because we have designed our app
> launcher to always enable as much CDS and AOT stuff as is appropriate
> for the host JVM. I'm not as concerned about AOT being disable during
> debugging, but the following error is pretty annoying when
> auto-dumping a CDS cache:
>
> ```
> [] jruby $ jruby --rmcache
> [] jruby $ jruby -J$JAVADEBUG -e 1
> Error occurred during CDS dumping
> CDS dumping does not support native JVMTI agent, name: jdwp
> [] jruby $ jruby -e 1
> [] jruby $ jruby -J$JAVADEBUG -e 1
> Listening for transport dt_socket at address: 5005
> ```
>
> Debugging works fine as long as I've already done a "clean" run that
> succesfully dumped my CDS archive.
>
> The relevant Java command line for the failed call above is as follows:
>
> ```
> java @/Users/headius/work/jruby/bin/.jruby.java_opts ...
> -XX:+AutoCreateSharedArchive
> -XX:SharedArchiveFile=/Users/headius/work/jruby/lib/jruby-java25+36-LTS.jsa
> -Xlog:cds=off -Xlog:cds+dynamic=off ...
>
> In this case I'm running JDK 25, but we have not fully utilized AOT
> features there yet.
>
> I'd prefer (and I think most folks would prefer) simply getting a
> warning that CDS dumping has been disabled, rather than a hard error
> that terminates execution.
>
> On Tue, Jan 27, 2026 at 8:35 AM Anthony Dahanne
> <anthony.dahanne at gmail.com> wrote:
>
> Hello Ioi,
> Thanks for your answer; I now understand why the gating of JVMTI
> when AOTClassLinking is enabled.
>
> After reading your answer, and reading
> https://openjdk.org/jeps/483 , can I sum up the situation by saying:
>
> -XX:+AOTClassLinking (>=Java 25)
> * enabled by default when you're training using -XX:AOTMode=create
> * ahead-of-time loading and linking enhances startup time even
> more than CDS (cf your benchmark in JEP 483 with HelloStream and
> Spring PetClinic)
> * can not be applied with JVMTI (Java debug), customized
> java.security.manager
>
> -XX:-AOTClassLinking (>=Java 25)
> * reverts back to "plain" CDS cache
>
> Thanks again!
>
>
> Le mar. 27 janv. 2026, à 02 h 27, <ioi.lam at oracle.com> a écrit :
>
> When JDWP is used, AOT is disabled by this check:
>
> https://github.com/openjdk/jdk/blob/cba7d88ca427984ebb27a1634aab10a62c9eede1/src/hotspot/share/cds/filemap.cpp#L1743-L1748
> <https://urldefense.com/v3/__https://github.com/openjdk/jdk/blob/cba7d88ca427984ebb27a1634aab10a62c9eede1/src/hotspot/share/cds/filemap.cpp*L1743-L1748__;Iw!!ACWV5N9M2RV99hQ!IsURfe7c-RqezNKbrQLApqjFXVQ9BtOXi8AdSZVm1KmL2BQCm13gNIewgGJZOAbER83KIab9omgwaVQ$>
>
> The reason we have this check is that when
> -XX:+AOTClassLinking is
> enabled (by default in AOT cache creation), some class
> initializers are
> executed in the AOT assembly phase, and are not executed in the
> production run.
>
> As a result, some breakpoints will not work.
>
> Here's an example. I have rebuilt the JVM to disable the above
> check:
>
>
> ===============================================================================
>
> Without AOT cache: you can break
> at java.lang.invoke.Invokers.<clinit>
>
> ===============================================================================
> $ jdb -launch -classpath HelloWorld.jar -R-XX:AOTMode=off
> -R-XX:AOTCache=hw.aot java.lang.invoke.Invokers
> Set uncaught java.lang.Throwable
> Set deferred uncaught java.lang.Throwable
> Initializing jdb ...
> >
> VM Started: No frames on the current call stack
>
> main[1] stop in java.lang.invoke.Invokers.<clinit>
> Deferring breakpoint java.lang.invoke.Invokers.<clinit>.
> It will be set after the class is loaded.
> main[1] cont
> > Set deferred breakpoint java.lang.invoke.Invokers.<clinit>
>
> Breakpoint hit: "thread=main",
> java.lang.invoke.Invokers.<clinit>(),
> line=47 bci=0
>
> main[1] where
> [1] java.lang.invoke.Invokers.<clinit> (Invokers.java:47)
> [2] java.lang.invoke.MethodHandleNatives.linkCallSiteImpl
> (MethodHandleNatives.java:263)
> [3] java.lang.invoke.MethodHandleNatives.linkCallSite
> (MethodHandleNatives.java:240)
> [4] java.util.ResourceBundle$Control.<clinit>
> (ResourceBundle.java:2,833)
> [5] java.util.ResourceBundle.getDefaultControl
> (ResourceBundle.java:1,508)
> [6] java.util.ResourceBundle.getDefaultControl
> (ResourceBundle.java:1,503)
> [7] java.util.ResourceBundle.getBundle
> (ResourceBundle.java:863)
> [8] sun.launcher.LauncherHelper$ResourceBundleHolder.<clinit>
> (LauncherHelper.java:124)
> [9] sun.launcher.LauncherHelper.getLocalizedMessage
> (LauncherHelper.java:532)
> [10] sun.launcher.LauncherHelper.abort
> (LauncherHelper.java:720)
> [11] sun.launcher.LauncherHelper.validateMainMethod
> (LauncherHelper.java:944)
> [12] sun.launcher.LauncherHelper.checkAndLoadMain
> (LauncherHelper.java:778)
> main[1] cont
> > Error: Main method not found in class
> java.lang.invoke.Invokers,
> please define the main method as:
> public static void main(String[] args)
> or a JavaFX application class must extend
> javafx.application.Application
>
> The application exited
>
> ===============================================================================
>
> With AOT cache: you cannot break
> at java.lang.invoke.Invokers.<clinit>
>
> ===============================================================================
>
>
> $ jdb -launch -classpath HelloWorld.jar -R-XX:AOTMode=on
> -R-XX:AOTCache=hw.aot java.lang.invoke.Invokers
> Set uncaught java.lang.Throwable
> Set deferred uncaught java.lang.Throwable
> Initializing jdb ...
> >
> VM Started: No frames on the current call stack
>
> main[1] stop in java.lang.invoke.Invokers.<clinit>
> Set breakpoint java.lang.invoke.Invokers.<clinit>
> main[1] cont
> > Error: Main method not found in class
> java.lang.invoke.Invokers,
> please define the main method as:
> public static void main(String[] args)
> or a JavaFX application class must extend
> javafx.application.Application
>
> The application exited
>
>
> On 1/26/26 9:39 PM, Anthony Dahanne wrote:
> > Hello all!
> > I'm trying to run an AOTCaching optimized app in debug mode;
> > unfortunately, it does not seem to be supported.
> >
> > Using a JDK 25.0.1, during the training run I have:
> >
> > ```
> > [creator] Temporary AOTConfiguration recorded:
> application.aot.config
> > [creator] Launching child process
> > /layers/paketo-buildpacks_bellsoft-liberica/jre/bin/java to
> assemble
> > AOT cache application.aot using configuration
> application.aot.config
> > [creator] Picked up JAVA_TOOL_OPTIONS:
> >
> -Djava.class.path=runner.jar:lib/spring-cloud-bindings-2.0.4.jar
> >
> -agentlib:jdwp=transport=dt_socket,server=y,address=*:8000,suspend=n
>
> > -XX:+AOTClassLinking -Dspring.context.exit=onRefresh
> > -XX:AOTCacheOutput=application.aot
> > -XX:AOTConfiguration=application.aot.config -XX:AOTMode=create
> > [creator] Reading AOTConfiguration
> application.aot.config and
> > writing AOTCache application.aot
> > [creator] [0.262s][warning][aot] Skipping
> >
> io/micrometer/core/instrument/config/InvalidConfigurationException:
>
> > Unlinked class not supported by AOTClassLinking
> > [creator] [0.262s][warning][aot] Skipping
> > org/springframework/web/servlet/view/freemarker/FreeMarkerView:
> > Unlinked class not supported by AOTClassLinking
> > [creator] [0.262s][warning][aot] Skipping
> > org/springframework/boot/logging/log4j2/Log4J2LoggingSystem:
> Unlinked
> > class not supported by AOTClassLinking
> > [creator] [0.263s][warning][aot] Skipping
> >
> org/springframework/core/ReactiveAdapterRegistry$ReactorAdapter:
> > Unlinked class not supported by AOTClassLinking
> > [creator] AOTCache creation is complete:
> application.aot
> > 56819712 bytes
> > [creator] Removed temporary AOT configuration file
> > application.aot.config
> > ```
> >
> > but at runtime, I have:
> > ```
> > Picked up JAVA_TOOL_OPTIONS:
> >
> -Djava.security.properties=/layers/paketo-buildpacks_bellsoft-liberica/java-security-properties/java-security.properties
>
> > -XX:+ExitOnOutOfMemoryError
> >
> -agentlib:jdwp=transport=dt_socket,server=y,address=*:8000,suspend=n
>
> > -XX:MaxDirectMemorySize=10M -Xmx14945375K
> -XX:MaxMetaspaceSize=78944K
> > -XX:ReservedCodeCacheSize=240M -Xss1M
> -XX:+UnlockDiagnosticVMOptions
> > -XX:NativeMemoryTracking=summary -XX:+PrintNMTStatistics
> > -XX:AOTCache=application.aot
> > -Dorg.springframework.cloud.bindings.boot.enable=true
> > [0.032s][error][aot] AOT cache has aot-linked classes. It
> cannot be
> > used with JDWP agent
> > [0.034s][error][aot] An error has occurred while processing
> the AOT
> > cache. Run with -Xlog:aot for details.
> > [0.034s][error][aot] Unable to map shared spaces
> > Listening for transport dt_socket at address: 8000
> > ```
> >
> > If I enable `-Xlog:aot` at runtime, I have:
> >
> > ```
> > Picked up JAVA_TOOL_OPTIONS: -Xlog:aot
> >
> -Djava.security.properties=/layers/paketo-buildpacks_bellsoft-liberica/java-security-properties/java-security.properties
>
> > -XX:+ExitOnOutOfMemoryError
> >
> -agentlib:jdwp=transport=dt_socket,server=y,address=*:8000,suspend=n
>
> > -XX:MaxDirectMemorySize=10M -Xmx15196043K
> -XX:MaxMetaspaceSize=78944K
> > -XX:ReservedCodeCacheSize=240M -Xss1M
> -XX:+UnlockDiagnosticVMOptions
> > -XX:NativeMemoryTracking=summary -XX:+PrintNMTStatistics
> > -XX:AOTCache=application.aot
> > -Dorg.springframework.cloud.bindings.boot.enable=true
> > [0.033s][info][aot] trying to map application.aot
> > [0.033s][info][aot] Opened AOT cache application.aot.
> > [0.033s][info][aot] The AOT cache was created with
> UseCompressedOops =
> > 1, UseCompressedClassPointers = 1, UseCompactObjectHeaders = 0
> > [0.033s][info][aot] Core region alignment: 65536
> > [0.033s][info][aot] ArchiveRelocationMode: 1
> > [0.033s][info][aot] ArchiveRelocationMode == 1: always map
> archive(s)
> > at an alternative address
> > [0.033s][info][aot] Try to map archive(s) at an alternative
> address
> > [0.033s][info][aot] Reserved archive_space_rs
> [0x0000003000000000 -
> > 0x0000003004000000] (67108864) bytes (includes protection zone)
> > [0.033s][info][aot] Reserved class_space_rs
> [0x0000003004000000 -
> > 0x0000003008000000] (67108864) bytes
> > [0.033s][info][aot] Mapped static region #0 at base
> > 0x0000003000010000 top 0x0000003001500000 (ReadWrite)
> > [0.033s][info][aot] Mapped static region #1 at base
> > 0x0000003001500000 top 0x0000003003200000 (ReadOnly)
> > [0.033s][info][aot] Mapped static region #2 at base
> > 0x0000ffff5c120000 top 0x0000ffff5c1e0000 (Bitmap)
> > [0.069s][info][aot] archived module property
> jdk.module.main: (null)
> > [0.069s][info][aot] archived module property
> jdk.module.addexports: (null)
> > [0.069s][info][aot] archived module property
> jdk.module.addmods: (null)
> > [0.069s][info][aot] archived module property
> > jdk.module.enable.native.access: (null)
> > [0.069s][info][aot] archived module property
> jdk.module.addopens: (null)
> > [0.069s][info][aot] archived module property
> jdk.module.addreads: (null)
> > [0.069s][info][aot] optimized module handling: enabled
> > [0.069s][info][aot] full module graph: enabled
> > [0.069s][error][aot] AOT cache has aot-linked classes. It
> cannot be
> > used with JDWP agent
> > [0.069s][info ][aot] Unmapping region #0 at base
> 0x0000003000010000
> > (ReadWrite)
> > [0.069s][info ][aot] Region #0 (ReadWrite) is in a reserved
> space, it
> > will be freed when the space is released
> > [0.069s][info ][aot] Unmapping region #1 at base
> 0x0000003001500000
> > (ReadOnly)
> > [0.069s][info ][aot] Region #1 (ReadOnly) is in a reserved
> space, it
> > will be freed when the space is released
> > [0.069s][info ][aot] Unmapping region #2 at base
> 0x0000ffff5c120000
> > (Bitmap)
> > [0.069s][error][aot] An error has occurred while processing
> the AOT
> > cache. Run with -Xlog:aot for details.
> > [0.069s][error][aot] Unable to map shared spaces
> > Listening for transport dt_socket at address: 8000
> > ```
> >
> > I have tried several variations using
> ` -XX:+AOTClassLinking` during
> > the training run, but that did not change a thing.
> >
> > Is it possible to use AOTCaching when debug is enabled?
> >
> > Thank you!
> >
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/leyden-dev/attachments/20260129/9be251b2/attachment.htm>
More information about the leyden-dev
mailing list