From 05468def546986cbf5a30b85aec92627bc0daffd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Nicoll?= Date: Tue, 30 Jul 2024 10:45:02 +0200 Subject: [PATCH] Tolerate module-info with AOT processing This commit updates the Maven Plugin to tolerate projects that are using the module path on the JVM and targeting native images with AOT. Previously, the plugin compiled AOT sources directly to target/classes and the presence of a module-info there is enough to trigger a compilation on the module path. With this change we now compile in a separate directory that contains the generated AOT classes (typically CGLIB proxies). These are copied to target/classes once compilation completes already. The integration test also uses our parent, rather than relying on what Maven provides. That's because older Maven versions provide a default compiler plugin version that did not handle the module path correctly. Closes gh-33383 --- .../springframework/boot/maven/AotTests.java | 13 +++++- .../intTest/projects/aot-module-info/pom.xml | 46 +++++++++++++++++++ .../src/main/java/module-info.java | 4 ++ .../main/java/org/test/SampleApplication.java | 29 ++++++++++++ .../boot/maven/ProcessAotMojo.java | 4 +- .../boot/maven/ProcessTestAotMojo.java | 4 +- 6 files changed, 94 insertions(+), 6 deletions(-) create mode 100644 spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/aot-module-info/pom.xml create mode 100644 spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/aot-module-info/src/main/java/module-info.java create mode 100644 spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/aot-module-info/src/main/java/org/test/SampleApplication.java diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/AotTests.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/AotTests.java index f205215898..d354523eb9 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/AotTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/AotTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -133,7 +133,7 @@ class AotTests { } @TestTemplate - void whenAotRunsSourcesAreCompiled(MavenBuild mavenBuild) { + void whenAotRunsSourcesAreCompiledAndMovedToTargetClasses(MavenBuild mavenBuild) { mavenBuild.project("aot").goals("package").execute((project) -> { Path classesDirectory = project.toPath().resolve("target/classes"); assertThat(collectRelativePaths(classesDirectory)) @@ -141,6 +141,15 @@ class AotTests { }); } + @TestTemplate + void whenAotRunsWithModuleInfoSourcesAreCompiledAndMovedToTargetClass(MavenBuild mavenBuild) { + mavenBuild.project("aot-module-info").goals("package").execute((project) -> { + Path classesDirectory = project.toPath().resolve("target/classes"); + assertThat(collectRelativePaths(classesDirectory)) + .contains(Path.of("org", "test", "SampleApplication__ApplicationContextInitializer.class")); + }); + } + @TestTemplate void whenAotRunsResourcesAreCopiedToTargetClasses(MavenBuild mavenBuild) { mavenBuild.project("aot-jdk-proxy").goals("package").execute((project) -> { diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/aot-module-info/pom.xml b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/aot-module-info/pom.xml new file mode 100644 index 0000000000..34bcf5d8d2 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/aot-module-info/pom.xml @@ -0,0 +1,46 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + @project.version@ + + + org.springframework.boot.maven.it + aot-module-info + 0.0.1.BUILD-SNAPSHOT + + UTF-8 + @java.version@ + @java.version@ + + + + + @project.groupId@ + @project.artifactId@ + + + + process-aot + + + + repackage + + true + + + + + + + + + org.springframework.boot + spring-boot + + + diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/aot-module-info/src/main/java/module-info.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/aot-module-info/src/main/java/module-info.java new file mode 100644 index 0000000000..c3640e6fa0 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/aot-module-info/src/main/java/module-info.java @@ -0,0 +1,4 @@ +module sampleApp { + requires spring.context; + requires spring.boot; +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/aot-module-info/src/main/java/org/test/SampleApplication.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/aot-module-info/src/main/java/org/test/SampleApplication.java new file mode 100644 index 0000000000..7e1f8bf7c6 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/aot-module-info/src/main/java/org/test/SampleApplication.java @@ -0,0 +1,29 @@ +/* + * Copyright 2012-2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.test; + +import org.springframework.boot.SpringApplication; +import org.springframework.context.annotation.Configuration; + +@Configuration(proxyBeanMethods = false) +public class SampleApplication { + + public static void main(String[] args) { + SpringApplication.run(SampleApplication.class, args); + } + +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/ProcessAotMojo.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/ProcessAotMojo.java index 9f75cf1e5a..ef16eea0ae 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/ProcessAotMojo.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/ProcessAotMojo.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -96,7 +96,7 @@ public class ProcessAotMojo extends AbstractAotMojo { : SpringBootApplicationClassFinder.findSingleClass(this.classesDirectory); URL[] classPath = getClassPath(); generateAotAssets(classPath, AOT_PROCESSOR_CLASS_NAME, getAotArguments(applicationClass)); - compileSourceFiles(classPath, this.generatedSources, this.classesDirectory); + compileSourceFiles(classPath, this.generatedSources, this.generatedClasses); copyAll(this.generatedResources.toPath(), this.classesDirectory.toPath()); copyAll(this.generatedClasses.toPath(), this.classesDirectory.toPath()); } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/ProcessTestAotMojo.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/ProcessTestAotMojo.java index 399e4561b4..efc0ba4f92 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/ProcessTestAotMojo.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/ProcessTestAotMojo.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -125,7 +125,7 @@ public class ProcessTestAotMojo extends AbstractAotMojo { return; } generateAotAssets(getClassPath(true), AOT_PROCESSOR_CLASS_NAME, getAotArguments()); - compileSourceFiles(getClassPath(false), this.generatedSources, this.testClassesDirectory); + compileSourceFiles(getClassPath(false), this.generatedSources, this.generatedTestClasses); copyAll(this.generatedResources.toPath().resolve("META-INF/native-image"), this.testClassesDirectory.toPath().resolve("META-INF/native-image")); copyAll(this.generatedTestClasses.toPath(), this.testClassesDirectory.toPath());