Skip to content

Commit 75b7463

Browse files
committed
Make sure the 'native' profile can be used in a multi-modules project
This commit updates the 'native' profile so that it provides plugin management for the plugins involved in building a native image, rather than forcing their executions. This commit also update the Maven Plugin reference guide to describe what the native profile does, and how it can be used in various scenarios. Closes gh-33184
1 parent 29ee5d2 commit 75b7463

File tree

6 files changed

+176
-38
lines changed

6 files changed

+176
-38
lines changed

spring-boot-project/spring-boot-starters/spring-boot-starter-parent/build.gradle

+32-30
Original file line numberDiff line numberDiff line change
@@ -232,42 +232,44 @@ publishing.publications.withType(MavenPublication) {
232232
profile {
233233
delegate.id("native")
234234
build {
235-
plugins {
236-
plugin {
237-
delegate.groupId('org.springframework.boot')
238-
delegate.artifactId('spring-boot-maven-plugin')
239-
configuration {
240-
image {
241-
delegate.builder("paketobuildpacks/builder:tiny");
242-
env {
243-
delegate.BP_NATIVE_IMAGE("true")
235+
pluginManagement {
236+
plugins {
237+
plugin {
238+
delegate.groupId('org.springframework.boot')
239+
delegate.artifactId('spring-boot-maven-plugin')
240+
configuration {
241+
image {
242+
delegate.builder("paketobuildpacks/builder:tiny");
243+
env {
244+
delegate.BP_NATIVE_IMAGE("true")
245+
}
244246
}
245247
}
246-
}
247-
executions {
248-
execution {
249-
delegate.id('process-aot')
250-
goals {
251-
delegate.goal('process-aot')
248+
executions {
249+
execution {
250+
delegate.id('process-aot')
251+
goals {
252+
delegate.goal('process-aot')
253+
}
252254
}
253255
}
254256
}
255-
}
256-
plugin {
257-
delegate.groupId('org.graalvm.buildtools')
258-
delegate.artifactId('native-maven-plugin')
259-
configuration {
260-
delegate.classesDirectory('${project.build.outputDirectory}')
261-
metadataRepository {
262-
delegate.enabled('true')
257+
plugin {
258+
delegate.groupId('org.graalvm.buildtools')
259+
delegate.artifactId('native-maven-plugin')
260+
configuration {
261+
delegate.classesDirectory('${project.build.outputDirectory}')
262+
metadataRepository {
263+
delegate.enabled('true')
264+
}
265+
delegate.requiredVersion('22.3')
263266
}
264-
delegate.requiredVersion('22.3')
265-
}
266-
executions {
267-
execution {
268-
delegate.id('add-reachability-metadata')
269-
goals {
270-
delegate.goal('add-reachability-metadata')
267+
executions {
268+
execution {
269+
delegate.id('add-reachability-metadata')
270+
goals {
271+
delegate.goal('add-reachability-metadata')
272+
}
271273
}
272274
}
273275
}

spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/docs/asciidoc/aot.adoc

+56-8
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,79 @@
11
[[aot]]
22
= Ahead-of-Time Processing
3-
Spring AOT is a process that analyzes your code at build-time in order to generate an optimized version of it.
4-
It is most often used to help generate GraalVM native images.
3+
4+
Spring AOT is a process that analyzes your application at build-time and generate an optimized version of it.
5+
It is a mandatory step to run a Spring `ApplicationContext` in a native image.
6+
7+
NOTE: For an overview of GraalVM Native Images support in Spring Boot, check the {spring-boot-reference}/#native-image[reference documentation].
58

69
The Spring Boot Maven plugin offers goals that can be used to perform AOT processing on both application and test code.
710

811

912

1013
== Processing Applications
11-
Based on your `@SpringBootApplication`-annotated main class, the AOT engine generates a persistent view of the beans that are going to be contributed at runtime in a way that bean instantiation is as straightforward as possible.
12-
Additional post-processing of the factory is possible using callbacks.
13-
For instance, these are used to generate the necessary reflection configuration that GraalVM needs to initialize the context in a native image.
14-
1514
To configure your application to use this feature, add an execution for the `process-aot` goal, as shown in the following example:
1615

1716
[source,xml,indent=0,subs="verbatim,attributes",tabsize=4]
1817
----
1918
include::../maven/aot/pom.xml[tags=aot]
2019
----
2120

22-
TIP: If you are using `spring-boot-starter-parent`, this execution is automatically configured if you enable the `native` profile.
23-
2421
As the `BeanFactory` is fully prepared at build-time, conditions are also evaluated.
2522
This has an important difference compared to what a regular Spring Boot application does at runtime.
2623
For instance, if you want to opt-in or opt-out for certain features, you need to configure the environment used at build time to do so.
2724
The `process-aot` goal shares a number of properties with the <<run,run goal>> for that reason.
2825

26+
27+
28+
=== Using the Native Profile
29+
If you use `spring-boot-starter-parent` as the `parent` of your project, a `native` profile can be used to streamline the steps required to build a native image.
30+
31+
The `native` profile configures the following:
32+
33+
* Execution of `process-aot` when the Spring Boot Maven Plugin is applied on a project.
34+
* Suitable settings so that <<build-image,build-image>> generates a native image.
35+
* Sensible defaults for the {nbt-reference}[Native Build Tools Maven Plugin], in particular:
36+
** Making sure the plugin uses the raw classpath, and not the main jar file as it does not understand our repackaged jar format.
37+
** Validate that a suitable GraalVM version is available.
38+
** Download third-party reachability metadata.
39+
40+
To benefit from the `native` profile, a module that represents an application should define two plugins, as shown in the following example:
41+
42+
[source,xml,indent=0,subs="verbatim,attributes",tabsize=4]
43+
----
44+
include::../maven/aot-native/pom.xml[tags=aot-native]
45+
----
46+
47+
A single project can trigger the generation of a native image on the command-line using either {spring-boot-reference}/#native-image.developing-your-first-application.buildpacks.maven[Cloud Native Buildpacks] or {spring-boot-reference}/#native-image.developing-your-first-application.native-build-tools.maven[Native Image Build Tools].
48+
49+
To use the `native` profile with a multi-modules project, you can create a customization of the `native` profile so that it invokes your preferred technique.
50+
51+
To bind Cloud Native Buildpacks during the `package` phase, add the following to the root POM of your multi-modules project:
52+
53+
[source,xml,indent=0,subs="verbatim,attributes",tabsize=4]
54+
----
55+
include::../maven/aot-native-profile-buildpacks/pom.xml[tags=profile]
56+
----
57+
58+
The example below does the same for Native Build Tools:
59+
60+
[source,xml,indent=0,subs="verbatim,attributes",tabsize=4]
61+
----
62+
include::../maven/aot-native-profile-nbt/pom.xml[tags=profile]
63+
----
64+
65+
Once the above is in place, you can build your multi-modules project and generate a native image in the relevant sub-modules, as shown in the following example:
66+
67+
[indent=0]
68+
----
69+
$ mvn package -Pnative
70+
----
71+
72+
NOTE: A "relevant" sub-module is a module that represents a Spring Boot application.
73+
Such module must define the Native Build Tools and Spring Boot plugins as described above.
74+
75+
76+
2977
include::goals/process-aot.adoc[leveloffset=+1]
3078

3179

spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/docs/asciidoc/index.adoc

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ v{gradle-project-version}
1313
:docinfo: shared,private
1414
:attribute-missing: warn
1515
:buildpacks-reference: https://buildpacks.io/docs
16+
:nbt-reference: https://graalvm.github.io/native-build-tools/latest/maven-plugin.html
1617
:spring-boot-docs: https://docs.spring.io/spring-boot/docs/{gradle-project-version}
1718
:spring-boot-api: {spring-boot-docs}/api/org/springframework/boot
1819
:spring-boot-reference: {spring-boot-docs}/reference/htmlsingle
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project>
3+
<modelVersion>4.0.0</modelVersion>
4+
<artifactId>aot-native-profile-buildpacks</artifactId>
5+
<profiles>
6+
<!-- tag::profile[] -->
7+
<profile>
8+
<id>native</id>
9+
<build>
10+
<pluginManagement>
11+
<plugins>
12+
<plugin>
13+
<groupId>org.springframework.boot</groupId>
14+
<artifactId>spring-boot-maven-plugin</artifactId>
15+
<executions>
16+
<execution>
17+
<id>build-image</id>
18+
<goals>
19+
<goal>build-image-no-fork</goal>
20+
</goals>
21+
</execution>
22+
</executions>
23+
</plugin>
24+
</plugins>
25+
</pluginManagement>
26+
</build>
27+
</profile>
28+
<!-- end::profile[] -->
29+
</profiles>
30+
31+
</project>
32+
33+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project>
3+
<modelVersion>4.0.0</modelVersion>
4+
<artifactId>aot-native-nbt</artifactId>
5+
<profiles>
6+
<!-- tag::profile[] -->
7+
<profile>
8+
<id>native</id>
9+
<build>
10+
<pluginManagement>
11+
<plugins>
12+
<plugin>
13+
<groupId>org.graalvm.buildtools</groupId>
14+
<artifactId>native-maven-plugin</artifactId>
15+
<executions>
16+
<execution>
17+
<id>build-image</id>
18+
<goals>
19+
<goal>compile-no-fork</goal>
20+
</goals>
21+
</execution>
22+
</executions>
23+
</plugin>
24+
</plugins>
25+
</pluginManagement>
26+
</build>
27+
</profile>
28+
<!-- end::profile[] -->
29+
</profiles>
30+
31+
</project>
32+
33+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project>
3+
<modelVersion>4.0.0</modelVersion>
4+
<artifactId>aot-native</artifactId>
5+
<build>
6+
<plugins>
7+
<!-- tag::aot-native[] -->
8+
<plugin>
9+
<groupId>org.graalvm.buildtools</groupId>
10+
<artifactId>native-maven-plugin</artifactId>
11+
</plugin>
12+
<plugin>
13+
<groupId>org.springframework.boot</groupId>
14+
<artifactId>spring-boot-maven-plugin</artifactId>
15+
</plugin>
16+
<!-- end::aot-native[] -->
17+
</plugins>
18+
</build>
19+
</project>
20+
21+

0 commit comments

Comments
 (0)