[[aot]]
= Ahead-of-Time Processing

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 xref:reference:packaging/native-image/index.adoc[reference documentation].

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



[[aot.processing-applications]]
== Processing Applications

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"]
----
include::example$aot/pom.xml[tags=aot]
----

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 xref:run.adoc[run goal] for that reason.



[[aot.processing-applications.using-the-native-profile]]
=== 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 xref:build-image.adoc[build-image] generates a native image.
* Sensible defaults for the {url-native-build-tools-docs-maven-plugin}[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.

[WARNING]
====
The use of the raw classpath means that native image does not know about the generated `MANIFEST.MF`.
If you need to read the content of the manifest in a native image, for instance to get the implementation version of your application, configure the `classesDirectory` option to use the regular jar.
====

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"]
----
include::example$aot-native/pom.xml[tags=aot-native]
----

A single project can trigger the generation of a native image on the command-line using either xref:how-to:native-image/developing-your-first-application.adoc#howto.native-image.developing-your-first-application.buildpacks.maven[Cloud Native Buildpacks] or xref:how-to:native-image/developing-your-first-application.adoc#howto.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"]
----
include::example$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"]
----
include::example$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:

[source,shell]
----
$ 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::partial$goals/process-aot.adoc[leveloffset=+1]



[[aot.processing-tests]]
== Processing Tests

The AOT engine can be applied to JUnit 5 tests that use Spring's Test Context Framework.
Those tests are processed by the AOT engine and are then executed in a native image.

NOTE: Tests are not processed when the regular tests are skipped using the `maven.test.skip` property.

Just like <<aot.processing-applications.using-the-native-profile,for production code>>, the `spring-boot-starter-parent` defines a `nativeTest` profile that can be used to streamline the steps required to execute your tests in a native image.

The `nativeTest` profile configures the following:

* Execution of `process-test-aot` when the Spring Boot Maven Plugin is applied on a project.
* Execution of `test` when the {url-native-build-tools-docs-maven-plugin}[Native Build Tools Maven Plugin] is applied on a project.
The execution defines sensible defaults, 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 `nativeTest` profile, a module that represents an application should define two plugins, as shown in the following example:

[source,xml,indent=0,subs="verbatim,attributes"]
----
include::example$aot-native/pom.xml[tags=aot-native]
----

Once the above is in place for each module that needs this feature, you can build your multi-modules project and execute your tests in a native image in the relevant sub-modules, as shown in the following example:

[source,shell]
----
$ mvn test -PnativeTest
----

NOTE: As with application AOT processing, the `BeanFactory` is fully prepared at build-time.

include::partial$goals/process-test-aot.adoc[leveloffset=+1]
