Using AOTCaching with debug (JDWP)

Anthony Dahanne anthony.dahanne at gmail.com
Tue Jan 27 14:34:57 UTC 2026


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
>
> 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/20260127/6bd0b5d2/attachment.htm>


More information about the leyden-dev mailing list