Skip to content

runtimeClasspath and testRuntimeClasspath exclusions are not applied to processAotClasspath and processTestAotClasspath - #51383

Open
gregjotau wants to merge 1 commit into
spring-projects:mainfrom
gregjotau:aot-runtime-classpath-exclusions
Open

runtimeClasspath and testRuntimeClasspath exclusions are not applied to processAotClasspath and processTestAotClasspath#51383
gregjotau wants to merge 1 commit into
spring-projects:mainfrom
gregjotau:aot-runtime-classpath-exclusions

Conversation

@gregjotau

Copy link
Copy Markdown

processAotClasspath and processTestAotClasspath are assembled from the parent configurations of their respective runtime classpaths so that development-only dependencies can be omitted. As a result, exclusion rules declared directly on runtimeClasspath or testRuntimeClasspath are currently lost.

This can make AOT processing evaluate classpath conditions differently from the packaged application. For example, excluding aspectjweaver from runtimeClasspath still exposes it to AOT processing, which selects AnnotationAwareAspectJAutoProxyCreator; the AOT-processed application then fails at runtime because AspectJ is correctly absent.

Copy the direct runtime classpath exclusion rules immediately before resolving the AOT processing classpath. Doing this lazily honors exclusions configured after the AOT plugin is applied. Integration tests cover both application and test AOT classpaths on the supported Gradle versions.

Verified with:

./gradlew :build-plugin:spring-boot-gradle-plugin:check

Signed-off-by: GT <gregjotau@gmail.com>
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Aug 15, 2026
@wilkinsona wilkinsona changed the title Honor runtime classpath exclusions during AOT processing runtimeClasspath and testRuntimeClasspath exclusions are not applied to processAotClasspath and processTestAotClasspath Aug 26, 2026
@wilkinsona wilkinsona added type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged labels Aug 26, 2026
@wilkinsona wilkinsona added this to the 4.0.x milestone Aug 26, 2026
@gregjotau

gregjotau commented Aug 30, 2026

Copy link
Copy Markdown
Author

End-to-end validation against Spring Boot 4.2.0-M1 in our application (231 Spring Data JPA repositories) confirms this is not limited to the synthetic integration test.

The application excludes aspectjweaver, spring-aspects, and tomcat-embed-websocket from runtimeClasspath, while all three remained visible on processAotClasspath.

  • With the unmodified AOT classpath, AOT selected AnnotationAwareAspectJAutoProxyCreator; the packaged AOT application failed with NoClassDefFoundError: org/aspectj/lang/annotation/Pointcut.
  • After mirroring only the AspectJ exclusions, AOT selected TomcatWebSocketConfiguration; the packaged application then failed with NoClassDefFoundError: org/apache/tomcat/websocket/server/WsSci.
  • Mirroring all runtime exclusions to processAotClasspath made the clean build pass and the AOT-processed application start successfully on a random port; an HTTP request returned 302.

Five interleaved fresh-process pairs using the same Boot 4.2.0-M1 executable jar:

  • normal startup mean: 16.535 s
  • AOT startup mean: 10.635 s
  • mean paired saving: 5.900 s (35.7%)
  • all 5 pairs favored AOT; paired 95% CI for the saving: 3.30–8.50 s

This provides a full-application reproducer for the classpath mismatch fixed by this PR and shows that the mismatch currently blocks a substantial JVM AOT startup improvement.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: bug A general bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants