diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-parent/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-parent/build.gradle index cabb693020..6abae77abc 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-parent/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-parent/build.gradle @@ -232,42 +232,44 @@ publishing.publications.withType(MavenPublication) { profile { delegate.id("native") build { - plugins { - plugin { - delegate.groupId('org.springframework.boot') - delegate.artifactId('spring-boot-maven-plugin') - configuration { - image { - delegate.builder("paketobuildpacks/builder:tiny"); - env { - delegate.BP_NATIVE_IMAGE("true") + pluginManagement { + plugins { + plugin { + delegate.groupId('org.springframework.boot') + delegate.artifactId('spring-boot-maven-plugin') + configuration { + image { + delegate.builder("paketobuildpacks/builder:tiny"); + env { + delegate.BP_NATIVE_IMAGE("true") + } + } + } + executions { + execution { + delegate.id('process-aot') + goals { + delegate.goal('process-aot') + } } } } - executions { - execution { - delegate.id('process-aot') - goals { - delegate.goal('process-aot') + plugin { + delegate.groupId('org.graalvm.buildtools') + delegate.artifactId('native-maven-plugin') + configuration { + delegate.classesDirectory('${project.build.outputDirectory}') + metadataRepository { + delegate.enabled('true') } + delegate.requiredVersion('22.3') } - } - } - plugin { - delegate.groupId('org.graalvm.buildtools') - delegate.artifactId('native-maven-plugin') - configuration { - delegate.classesDirectory('${project.build.outputDirectory}') - metadataRepository { - delegate.enabled('true') - } - delegate.requiredVersion('22.3') - } - executions { - execution { - delegate.id('add-reachability-metadata') - goals { - delegate.goal('add-reachability-metadata') + executions { + execution { + delegate.id('add-reachability-metadata') + goals { + delegate.goal('add-reachability-metadata') + } } } } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/docs/asciidoc/aot.adoc b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/docs/asciidoc/aot.adoc index e9ec813692..feb59d4216 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/docs/asciidoc/aot.adoc +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/docs/asciidoc/aot.adoc @@ -1,17 +1,16 @@ [[aot]] = Ahead-of-Time Processing -Spring AOT is a process that analyzes your code at build-time in order to generate an optimized version of it. -It is most often used to help generate GraalVM native images. + +Spring AOT is a process that analyzes your application at build-time and generate an optimized version of it. +It is a mandatory step to run a Spring `ApplicationContext` in a native image. + +NOTE: For an overview of GraalVM Native Images support in Spring Boot, check the {spring-boot-reference}/#native-image[reference documentation]. The Spring Boot Maven plugin offers goals that can be used to perform AOT processing on both application and test code. == Processing Applications -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. -Additional post-processing of the factory is possible using callbacks. -For instance, these are used to generate the necessary reflection configuration that GraalVM needs to initialize the context in a native image. - To configure your application to use this feature, add an execution for the `process-aot` goal, as shown in the following example: [source,xml,indent=0,subs="verbatim,attributes",tabsize=4] @@ -19,13 +18,62 @@ To configure your application to use this feature, add an execution for the `pro include::../maven/aot/pom.xml[tags=aot] ---- -TIP: If you are using `spring-boot-starter-parent`, this execution is automatically configured if you enable the `native` profile. - As the `BeanFactory` is fully prepared at build-time, conditions are also evaluated. This has an important difference compared to what a regular Spring Boot application does at runtime. 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. The `process-aot` goal shares a number of properties with the <> for that reason. + + +=== Using the Native Profile +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. + +The `native` profile configures the following: + +* Execution of `process-aot` when the Spring Boot Maven Plugin is applied on a project. +* Suitable settings so that <> generates a native image. +* Sensible defaults for the {nbt-reference}[Native Build Tools Maven Plugin], in particular: +** Making sure the plugin uses the raw classpath, and not the main jar file as it does not understand our repackaged jar format. +** Validate that a suitable GraalVM version is available. +** Download third-party reachability metadata. + +To benefit from the `native` profile, a module that represents an application should define two plugins, as shown in the following example: + +[source,xml,indent=0,subs="verbatim,attributes",tabsize=4] +---- +include::../maven/aot-native/pom.xml[tags=aot-native] +---- + +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]. + +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. + +To bind Cloud Native Buildpacks during the `package` phase, add the following to the root POM of your multi-modules project: + +[source,xml,indent=0,subs="verbatim,attributes",tabsize=4] +---- +include::../maven/aot-native-profile-buildpacks/pom.xml[tags=profile] +---- + +The example below does the same for Native Build Tools: + +[source,xml,indent=0,subs="verbatim,attributes",tabsize=4] +---- +include::../maven/aot-native-profile-nbt/pom.xml[tags=profile] +---- + +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: + +[indent=0] +---- + $ mvn package -Pnative +---- + +NOTE: A "relevant" sub-module is a module that represents a Spring Boot application. +Such module must define the Native Build Tools and Spring Boot plugins as described above. + + + include::goals/process-aot.adoc[leveloffset=+1] diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/docs/asciidoc/index.adoc b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/docs/asciidoc/index.adoc index 3cff6030a6..aa65458eaa 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/docs/asciidoc/index.adoc +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/docs/asciidoc/index.adoc @@ -13,6 +13,7 @@ v{gradle-project-version} :docinfo: shared,private :attribute-missing: warn :buildpacks-reference: https://buildpacks.io/docs +:nbt-reference: https://graalvm.github.io/native-build-tools/latest/maven-plugin.html :spring-boot-docs: https://docs.spring.io/spring-boot/docs/{gradle-project-version} :spring-boot-api: {spring-boot-docs}/api/org/springframework/boot :spring-boot-reference: {spring-boot-docs}/reference/htmlsingle diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/docs/maven/aot-native-profile-buildpacks/pom.xml b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/docs/maven/aot-native-profile-buildpacks/pom.xml new file mode 100644 index 0000000000..05682587d7 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/docs/maven/aot-native-profile-buildpacks/pom.xml @@ -0,0 +1,33 @@ + + + 4.0.0 + aot-native-profile-buildpacks + + + + native + + + + + org.springframework.boot + spring-boot-maven-plugin + + + build-image + + build-image-no-fork + + + + + + + + + + + + + + diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/docs/maven/aot-native-profile-nbt/pom.xml b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/docs/maven/aot-native-profile-nbt/pom.xml new file mode 100644 index 0000000000..030e9314a8 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/docs/maven/aot-native-profile-nbt/pom.xml @@ -0,0 +1,33 @@ + + + 4.0.0 + aot-native-nbt + + + + native + + + + + org.graalvm.buildtools + native-maven-plugin + + + build-image + + compile-no-fork + + + + + + + + + + + + + + diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/docs/maven/aot-native/pom.xml b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/docs/maven/aot-native/pom.xml new file mode 100644 index 0000000000..05a1b5acab --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/docs/maven/aot-native/pom.xml @@ -0,0 +1,21 @@ + + + 4.0.0 + aot-native + + + + + org.graalvm.buildtools + native-maven-plugin + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + +