Skip to content

Commit 05468de

Browse files
committed
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
1 parent 47465f6 commit 05468de

File tree

6 files changed

+94
-6
lines changed

6 files changed

+94
-6
lines changed

spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/AotTests.java

+11-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 the original author or authors.
2+
* Copyright 2012-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -133,14 +133,23 @@ void whenAotRunsWithInvalidCompilerArgumentsCompileFails(MavenBuild mavenBuild)
133133
}
134134

135135
@TestTemplate
136-
void whenAotRunsSourcesAreCompiled(MavenBuild mavenBuild) {
136+
void whenAotRunsSourcesAreCompiledAndMovedToTargetClasses(MavenBuild mavenBuild) {
137137
mavenBuild.project("aot").goals("package").execute((project) -> {
138138
Path classesDirectory = project.toPath().resolve("target/classes");
139139
assertThat(collectRelativePaths(classesDirectory))
140140
.contains(Path.of("org", "test", "SampleApplication__ApplicationContextInitializer.class"));
141141
});
142142
}
143143

144+
@TestTemplate
145+
void whenAotRunsWithModuleInfoSourcesAreCompiledAndMovedToTargetClass(MavenBuild mavenBuild) {
146+
mavenBuild.project("aot-module-info").goals("package").execute((project) -> {
147+
Path classesDirectory = project.toPath().resolve("target/classes");
148+
assertThat(collectRelativePaths(classesDirectory))
149+
.contains(Path.of("org", "test", "SampleApplication__ApplicationContextInitializer.class"));
150+
});
151+
}
152+
144153
@TestTemplate
145154
void whenAotRunsResourcesAreCopiedToTargetClasses(MavenBuild mavenBuild) {
146155
mavenBuild.project("aot-jdk-proxy").goals("package").execute((project) -> {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
<parent> <!-- required to use a recent compiler plugin with old Maven versions -->
6+
<groupId>org.springframework.boot</groupId>
7+
<artifactId>spring-boot-starter-parent</artifactId>
8+
<version>@project.version@</version>
9+
<relativePath/>
10+
</parent>
11+
<groupId>org.springframework.boot.maven.it</groupId>
12+
<artifactId>aot-module-info</artifactId>
13+
<version>0.0.1.BUILD-SNAPSHOT</version>
14+
<properties>
15+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
16+
<maven.compiler.source>@java.version@</maven.compiler.source>
17+
<maven.compiler.target>@java.version@</maven.compiler.target>
18+
</properties>
19+
<build>
20+
<plugins>
21+
<plugin>
22+
<groupId>@project.groupId@</groupId>
23+
<artifactId>@project.artifactId@</artifactId>
24+
<executions>
25+
<execution>
26+
<goals>
27+
<goal>process-aot</goal>
28+
</goals>
29+
</execution>
30+
<execution>
31+
<id>repackage</id>
32+
<configuration>
33+
<skip>true</skip>
34+
</configuration>
35+
</execution>
36+
</executions>
37+
</plugin>
38+
</plugins>
39+
</build>
40+
<dependencies>
41+
<dependency>
42+
<groupId>org.springframework.boot</groupId>
43+
<artifactId>spring-boot</artifactId>
44+
</dependency>
45+
</dependencies>
46+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module sampleApp {
2+
requires spring.context;
3+
requires spring.boot;
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright 2012-2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.test;
18+
19+
import org.springframework.boot.SpringApplication;
20+
import org.springframework.context.annotation.Configuration;
21+
22+
@Configuration(proxyBeanMethods = false)
23+
public class SampleApplication {
24+
25+
public static void main(String[] args) {
26+
SpringApplication.run(SampleApplication.class, args);
27+
}
28+
29+
}

spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/ProcessAotMojo.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 the original author or authors.
2+
* Copyright 2012-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -96,7 +96,7 @@ protected void executeAot() throws Exception {
9696
: SpringBootApplicationClassFinder.findSingleClass(this.classesDirectory);
9797
URL[] classPath = getClassPath();
9898
generateAotAssets(classPath, AOT_PROCESSOR_CLASS_NAME, getAotArguments(applicationClass));
99-
compileSourceFiles(classPath, this.generatedSources, this.classesDirectory);
99+
compileSourceFiles(classPath, this.generatedSources, this.generatedClasses);
100100
copyAll(this.generatedResources.toPath(), this.classesDirectory.toPath());
101101
copyAll(this.generatedClasses.toPath(), this.classesDirectory.toPath());
102102
}

spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/ProcessTestAotMojo.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 the original author or authors.
2+
* Copyright 2012-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -125,7 +125,7 @@ protected void executeAot() throws Exception {
125125
return;
126126
}
127127
generateAotAssets(getClassPath(true), AOT_PROCESSOR_CLASS_NAME, getAotArguments());
128-
compileSourceFiles(getClassPath(false), this.generatedSources, this.testClassesDirectory);
128+
compileSourceFiles(getClassPath(false), this.generatedSources, this.generatedTestClasses);
129129
copyAll(this.generatedResources.toPath().resolve("META-INF/native-image"),
130130
this.testClassesDirectory.toPath().resolve("META-INF/native-image"));
131131
copyAll(this.generatedTestClasses.toPath(), this.testClassesDirectory.toPath());

0 commit comments

Comments
 (0)