Skip to content
This repository has been archived by the owner on Feb 23, 2023. It is now read-only.

Commit

Permalink
Improve reference documentation structure
Browse files Browse the repository at this point in the history
- Merge AOT and build setup documentation.
- Various updates and fixes.

Closes gh-1467
  • Loading branch information
sdeleuze committed Jan 24, 2022
1 parent 481267e commit 246f4fb
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 83 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
[[build-setup]]
== Build Setup
This section covers how to configure your build for <<build-setup-maven,Maven>> or <<build-setup-gradle,Gradle>>.
You'll also learn more about <<build-setup-modes,the types of sources generated and how they're used>>
[[aot]]
== AOT generation

[[build-setup-maven]]
=== Maven
This section covers AOT (Ahead Of Time) generation plugins, including how to configure your build for <<aot-build-setup-maven,Maven>> or <<aot-build-setup-gradle,Gradle>>.
You'll also learn more about <<aot-modes,AOT runtime modes>> and more details on the <<aot-engine, AOT engine>>.

[[aot-build-setup]]
=== Build setup

[[aot-build-setup-maven]]
==== Maven

The plugin should be declared in your `pom.xml` file:

Expand Down Expand Up @@ -57,12 +61,12 @@ Configuration can be performed if needed within the `<configuration>` element, f
</configuration>
----

See <<build-setup-configuration>> for a list of the configuration options available.
See <<aot-build-setup-configuration>> for a list of the configuration options available.



[[build-setup-gradle]]
=== Gradle
[[aot-build-setup-gradle]]
==== Gradle

You can configure the Gradle Spring AOT plugin by declaring first the plugin repositories in your `settings.gradle(.kts)` file:

Expand Down Expand Up @@ -168,12 +172,12 @@ springAot {

NOTE: The non-idomatic `property.set(...)` syntax in the Gradle Kotlin DSL is due to https://github.com/gradle/gradle/issues/9268[gradle#9268], feel free to vote for this issue.

See <<build-setup-configuration>> for more details on the configuration options.
See <<aot-build-setup-configuration>> for more details on the configuration options.



[[build-setup-configuration]]
=== AOT Configuration
[[aot-build-setup-configuration]]
==== AOT configuration

The Spring AOT plugins allow you to express opinions about the source generation process.
Here are all the options available:
Expand All @@ -198,7 +202,7 @@ Here are all the options available:

* `applicationClass` allows to specify an application class (typically annotated with `@SpringBootApplication`), useful when multiple ones are present.

==== Debugging the source generation
=== Debugging the source generation

The Spring AOT plugins spawns a new process to perform the source generation.
To remote debug this process, you can set a debug System property on the command line; then, the source generation process launches with a listener accepting a remote debugger on port `8000` for Maven or `5005` for Gradle.
Expand Down Expand Up @@ -237,8 +241,8 @@ $ ./gradlew generateAot -Dorg.gradle.debug=true --no-daemon
----


[[build-setup-modes]]
=== AOT Modes
[[aot-modes]]
=== AOT runtime modes

The generated sources are automatically used by the native image compilation, but are not used by default when running your application with a JVM.
This means that running the application or its tests from the IDE or the command line will not involve those classes.
Expand Down Expand Up @@ -293,3 +297,58 @@ tasks.getByName<BootRun>("bootRun") {
systemProperty("springAot", "true")
}
----


[[aot-engine]]
=== AOT engine

Spring AOT inspects an application at build-time and generates an optimized version of it.
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 <<native-hints,reflection configuration>> that GraalVM needs to initialize the context in a native image.

The engine goes through the following phases:

. Prepare the underlying `BeanFactory` so that the relevant bean definitions are available.
This typically includes bean definitions model parsing (such as `@Configuration`-annotated classes) as well as any additional post-processing of the bean factory.
. Code generation based on the prepared `BeanFactory`.
Each bean definition is handled one by one and the necessary code to instantiate the bean and its necessary runtime semantics (such as primary flag) is generated.
. Additional processing of the bean factory used to optimize the runtime.

[[aot-bean-factory-preparation]]
==== BeanFactory Preparation
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.

While certain properties like passwords or url can be changed once the application has been prepared, properties that affect, typically, auto-configurations should be set at build-time.

[NOTE]
====
Conditions on the runtime environment, such as enabling features based on your chosen cloud platform, will no longer run at runtime.
====

A profile is a special sort of condition so these are also evaluated at build-time.
It is recommended to avoid the use of profiles as processing them at build-time does not allow you to enable or disable them at runtime anyway.
If you want to keep using them, they should be enabled at build-time, for instance by adding the `spring.profiles.active` property in `application.properties`.

Low-level framework callbacks, such as `BeanDefinitionRegistryPostProcessor` are invoked at build-time to create any additional bean definitions.
To prevent such a callback to be invoked at runtime again, it is not registered as bean, unless it does not have an `infrastructure` role.

[[aot-code-generation]]
==== Code Generation
Based on a bean name and a merged `RootBeanDefinition`, the engine identifies a suitable `BeanRegistrationWriter` that is responsible to write the necessary code to instantiate the bean at runtime.

It is not expected that projects have to define their own writers, but this could happen for corner-cases.
Writers are identified via implementations of `BeanRegistrationWriterSupplier`, registered in `META-INF/spring.factories`.
Suppliers are ordered with a first-win approach, and a {github-tree}/spring-aot/src/main/java/org/springframework/aot/context/bootstrap/generator/bean/DefaultBeanRegistrationWriterSupplier.java[default implementation] with lowest precedence that handles most use cases is provided.

NOTE: Explicit care is required if a bean requires privileged access in more than one package.
This happens typically if the bean use `protected` access and extends from another class in a different package that does the same.
As a rule of thumb, make sure that each custom bean of yours can be instantiated in a test in a usable form.

[[aot-additional-processing]]
==== Additional Processing
Additional processing of the `BeanFactory` currently only scans for `@EventListener`-annotated methods, but future versions may provide additional implementations.

More core to GraalVM support is the generation of an optimized set of native configuration based on the actual beans of the application, as covered by the next section.
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ This can be useful for various use cases:
* Keep the regular JVM pipeline and turn the JVM Spring Boot application to native on the CI/CD platform.
* Keep an architecture neutral deployment artifact, as `native-image` https://github.com/oracle/graal/issues/407[does not support cross-compilation].

WARNING: A mandatory pre-requisite is to use <<spring-aot>> Maven or Gradle upstream to build the Spring Boot executable JAR.
WARNING: A mandatory pre-requisite is to use <<aot>> Maven or Gradle upstream to build the Spring Boot executable JAR.

=== With Buildpacks

Spring Boot applications usually use {buildpacks}[Buildpacks] via the Maven (`mvn spring-boot:build-image`), or Gradle (`gradle bootBuildImage`) integration.
You can also use directly {buildpacks-docs}/tools/pack/[the `pack` CLI] to turn a Spring Boot executable JAR built with <<spring-aot>> into an optimized container image.
You can also use directly {buildpacks-docs}/tools/pack/[the `pack` CLI] to turn a Spring Boot executable JAR built with <<aot>> into an optimized container image.

First, make sure that a Docker daemon is available, either https://hub.docker.com/search?type=edition&offering=community[locally] or {buildpacks-docs}/app-developer-guide/build-a-windows-app/#using-remote-docker-hosts[remotely].
You also need to {buildpacks-docs}/tools/pack/[Install `pack`].
Expand All @@ -29,7 +29,7 @@ NOTE: This does not require a local `native-image` installation.

=== With `native-image`

Another option is to turn a Spring Boot executable JAR built with <<spring-aot>> into a native executable using the GraalVM `native-image` compiler.
Another option is to turn a Spring Boot executable JAR built with <<aot>> into a native executable using the GraalVM `native-image` compiler.
For this to work, you need to <<getting-started-native-image-system-requirements,Install native-image>>.

Assuming a Spring Boot executable JAR built as `my-app-0.0.1-SNAPSHOT.jar` in the `target` directory:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ It is fine to use reflection in a native world but it is most optimal to do it i
* In the static block/fields of a class initialized at build-time.
* In an AOT transformation run as a Spring AOT build plugin.

NOTE: More guidelines will be provided here as <<spring-aot>> matures.
NOTE: More guidelines will be provided here as <<aot>> matures.

[[how-to-contribute-new-hints]]
=== Contributing new hints
Expand Down
18 changes: 7 additions & 11 deletions spring-native-docs/src/main/asciidoc/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -41,21 +41,19 @@ Spring Native is composed of the following modules:
* `spring-native-configuration`: configuration hints for Spring classes used by Spring AOT plugins, including various Spring Boot auto-configurations.
* `spring-native-docs`: reference guide, in asciidoc format.
* `spring-native-tools`: tools used for reviewing image building configuration and output.
* `spring-aot`: AOT transformation infrastructure common to Maven and Gradle plugins.
* `spring-aot-test`: Test-specific AOT transformation infrastructure.
* `spring-aot-gradle-plugin`: Gradle plugin that invokes AOT transformations.
* `spring-aot-maven-plugin`: Maven plugin that invokes AOT transformations.
* `spring-aot`: AOT generation infrastructure common to Maven and Gradle plugins.
* `spring-aot-test`: Test-specific AOT generation infrastructure.
* `spring-aot-gradle-plugin`: Gradle plugin that invokes AOT generation.
* `spring-aot-maven-plugin`: Maven plugin that invokes AOT generation.
* `samples`: contains various samples that demonstrate features usage and are used as integration tests.

[[getting-started]]
== Getting Started

NOTE: Applications using Spring Native should be compiled with either Java 11 or Java 17.
== Getting started

There are two main ways to build a Spring Boot native application:

* Using <<getting-started-buildpacks, Spring Boot Buildpacks support>> to generate a lightweight container containing a native executable.
* Using <<getting-started-native-image, the GraalVM native image Maven plugin support>> to generate a native executable.
* Using <<getting-started-native-build-tools, the Native Build Tools>> to generate a native executable.

TIP: The easiest way to start a new native Spring Boot project is to go to https://start.spring.io, add the "Spring Native" dependency and generate the project.

Expand All @@ -65,12 +63,10 @@ include::getting-started-native-build-tools.adoc[]

include::support.adoc[]

include::spring-aot.adoc[]
include::aot.adoc[]

include::native-hints.adoc[]

include::build-setup.adoc[]

include::samples.adoc[]

include::native-image-options.adoc[]
Expand Down
52 changes: 0 additions & 52 deletions spring-native-docs/src/main/asciidoc/spring-aot.adoc

This file was deleted.

2 changes: 1 addition & 1 deletion spring-native-docs/src/main/asciidoc/troubleshooting.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Error: Classes that should be initialized at run time got initialized during ima
----

You have probably tried to compile a Spring Boot application to native without the `spring-native` dependency and Spring AOT plugin.
See related <<getting-started-native-image>> and <<getting-started-buildpacks>> documentation.
See related <<getting-started-native-build-tools>> and <<getting-started-buildpacks>> documentation.

==== WARNING: Could not register reflection metadata

Expand Down

0 comments on commit 246f4fb

Please sign in to comment.