Skip to content

Commit

Permalink
Migrate maven-plugin to Antora
Browse files Browse the repository at this point in the history
  • Loading branch information
philwebb committed Mar 20, 2024
1 parent 18a2b2e commit 8ee20c8
Show file tree
Hide file tree
Showing 73 changed files with 334 additions and 315 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
plugins {
id "org.asciidoctor.jvm.convert"
id "org.antora"
id "org.springframework.boot.conventions"
id "org.springframework.boot.maven-plugin"
id "org.springframework.boot.optional-dependencies"
Expand All @@ -9,12 +9,10 @@ description = "Spring Boot Maven Plugin"

configurations {
dependenciesBom
documentation
antoraContent
}

dependencies {
asciidoctorExtensions("io.spring.asciidoctor:spring-asciidoctor-extensions-section-ids")

compileOnly("org.apache.maven.plugin-tools:maven-plugin-annotations")
compileOnly("org.sonatype.plexus:plexus-build-api")
compileOnly("org.apache.maven:maven-core") {
Expand All @@ -37,6 +35,21 @@ dependencies {
implementation("org.springframework:spring-core")
implementation("org.springframework:spring-context")

testImplementation("org.apache.maven:maven-core") {
exclude(group: "javax.annotation", module: "javax.annotation-api")
exclude(group: "javax.inject", module: "javax.inject")
}
testImplementation("org.apache.maven.shared:maven-common-artifact-filters") {
exclude(group: "javax.annotation", module: "javax.annotation-api")
exclude(group: "javax.enterprise", module: "cdi-api")
exclude(group: "javax.inject", module: "javax.inject")
}
testImplementation("org.assertj:assertj-core")
testImplementation("org.junit.jupiter:junit-jupiter")
testImplementation("org.mockito:mockito-core")
testImplementation("org.mockito:mockito-junit-jupiter")
testImplementation("org.springframework:spring-core")

intTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-buildpack-platform"))
intTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-loader-tools"))
intTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support"))
Expand All @@ -61,21 +74,6 @@ dependencies {

runtimeOnly("org.sonatype.plexus:plexus-build-api")

testImplementation("org.apache.maven:maven-core") {
exclude(group: "javax.annotation", module: "javax.annotation-api")
exclude(group: "javax.inject", module: "javax.inject")
}
testImplementation("org.apache.maven.shared:maven-common-artifact-filters") {
exclude(group: "javax.annotation", module: "javax.annotation-api")
exclude(group: "javax.enterprise", module: "cdi-api")
exclude(group: "javax.inject", module: "javax.inject")
}
testImplementation("org.assertj:assertj-core")
testImplementation("org.junit.jupiter:junit-jupiter")
testImplementation("org.mockito:mockito-core")
testImplementation("org.mockito:mockito-junit-jupiter")
testImplementation("org.springframework:spring-core")

versionProperties(project(path: ":spring-boot-project:spring-boot-dependencies", configuration: "effectiveBom"))
}

Expand All @@ -84,12 +82,6 @@ ext {
xsdVersion = versionElements[0] + "." + versionElements[1]
}

syncDocumentationSourceForAsciidoctor {
from(documentPluginGoals) {
into "asciidoc/goals"
}
}

sourceSets {
main {
output.dir("${buildDir}/generated/resources/xsd", builtBy: "xsdResources")
Expand All @@ -99,30 +91,6 @@ sourceSets {
}
}

tasks.withType(org.asciidoctor.gradle.jvm.AbstractAsciidoctorTask) {
doFirst {
attributes "spring-boot-xsd-version" : project.ext.xsdVersion
}
}

asciidoctor {
sources {
include "index.adoc"
}
}

task asciidoctorPdf(type: org.asciidoctor.gradle.jvm.AsciidoctorTask) {
sources {
include "index.adoc"
}
}

syncDocumentationSourceForAsciidoctorPdf {
from(documentPluginGoals) {
into "asciidoc/goals"
}
}

javadoc {
options {
author = true
Expand All @@ -136,21 +104,6 @@ javadoc {
}
}

task zip(type: Zip) {
dependsOn asciidoctor, asciidoctorPdf
duplicatesStrategy "fail"
from(asciidoctorPdf.outputDir) {
into "reference/pdf"
rename "index.pdf", "${project.name}-reference.pdf"
}
from(asciidoctor.outputDir) {
into "reference/htmlsingle"
}
from(javadoc) {
into "api"
}
}

task xsdResources(type: Sync) {
from "src/main/xsd/layers-${project.ext.xsdVersion}.xsd"
into "${buildDir}/generated/resources/xsd/org/springframework/boot/maven"
Expand All @@ -161,10 +114,6 @@ prepareMavenBinaries {
versions "3.9.0", "3.8.5", "3.6.3"
}

artifacts {
"documentation" zip
}

tasks.named("documentPluginGoals") {
goalSections = [
"build-image": "build-image",
Expand All @@ -180,3 +129,43 @@ tasks.named("documentPluginGoals") {
"test-run": "run"
]
}

def antoraMavenPluginLocalAggregateContent = tasks.register("antoraMavenPluginLocalAggregateContent", Zip) {
destinationDirectory = layout.buildDirectory.dir('generated/docs/antora-content')
archiveClassifier = "maven-plugin-local-aggregate-content"
from(tasks.getByName("generateAntoraYml")) {
into "modules"
}
}

def antoraMavenPluginAggregateContent = tasks.register("antoraMavenPluginAggregateContent", Zip) {
destinationDirectory = layout.buildDirectory.dir('generated/docs/antora-content')
archiveClassifier = "maven-plugin-aggregate-content"
from(documentPluginGoals) {
into "modules/maven-plugin/partials/goals"
}
}

def antoraMavenPluginCatalogContent = tasks.register("antoraMavenPluginCatalogContent", Zip) {
destinationDirectory = layout.buildDirectory.dir('generated/docs/antora-content')
archiveClassifier = "maven-plugin-catalog-content"
from(javadoc) {
into "api/java"
}
}

tasks.named("generateAntoraPlaybook") {
xrefStubs = ["appendix:.*", "api:.*", "reference:.*"]
alwaysInclude = [name: "maven-plugin", classifier: "local-aggregate-content"]
dependsOn antoraMavenPluginLocalAggregateContent
}


tasks.named("antora") {
inputs.files(antoraMavenPluginLocalAggregateContent, antoraMavenPluginAggregateContent, antoraMavenPluginCatalogContent)
}

artifacts {
antoraContent antoraMavenPluginAggregateContent
antoraContent antoraMavenPluginCatalogContent
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
name: spring-boot
ext:
zip_contents_collector:
include:
- name: maven-plugin
classifier: aggregate-content
- name: maven-plugin
classifier: catalog-content
module: maven-plugin
destination: content-catalog
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include::maven-plugin:partial$nav-maven-plugin.adoc[]
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<layers xmlns="http://www.springframework.org/schema/boot/layers"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/boot/layers
https://www.springframework.org/schema/boot/layers/layers-{spring-boot-xsd-version}.xsd">
{url-spring-boot-layers-xsd}">
<application>
<into layer="spring-boot-loader">
<include>org/springframework/boot/loader/**</include>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<layers xmlns="http://www.springframework.org/schema/boot/layers"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/boot/layers
https://www.springframework.org/schema/boot/layers/layers-{spring-boot-xsd-version}.xsd">
{url-spring-boot-layers-xsd}">
<application>
<into layer="spring-boot-loader">
<include>org/springframework/boot/loader/**</include>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>{gradle-project-version}</version>
<version>{version-spring-boot}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>{gradle-project-version}</version>
<version>{version-spring-boot}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,93 +4,97 @@
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].
NOTE: For an overview of GraalVM Native Images support in Spring Boot, check the xref:reference: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",tabsize=4]
[source,xml,indent=0,subs="verbatim,attributes"]
----
include::../maven/aot/pom.xml[tags=aot]
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 <<run,run goal>> for that reason.
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 <<build-image,build-image>> generates a native image.
* Sensible defaults for the {nbt-reference}[Native Build Tools Maven Plugin], in particular:
* 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.

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]
[source,xml,indent=0,subs="verbatim,attributes"]
----
include::../maven/aot-native/pom.xml[tags=aot-native]
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 {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].
A single project can trigger the generation of a native image on the command-line using either xref:reference:native-image/developing-your-first-application.adoc#native-image.developing-your-first-application.buildpacks.maven[Cloud Native Buildpacks] or xref:reference:native-image/developing-your-first-application.adoc#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]
[source,xml,indent=0,subs="verbatim,attributes"]
----
include::../maven/aot-native-profile-buildpacks/pom.xml[tags=profile]
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",tabsize=4]
[source,xml,indent=0,subs="verbatim,attributes"]
----
include::../maven/aot-native-profile-nbt/pom.xml[tags=profile]
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:

[indent=0]
[source,shell]
----
$ mvn package -Pnative
$ 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]


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


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

The AOT engine can be applied to JUnit 5 tests that use Spring's Test Context Framework.
Suitable tests are processed by the AOT engine in order to generate `ApplicationContextInitialzer` code.
Suitable tests are processed by the AOT engine in order to generate `ApplicationContextInitializer` code.

To configure your application to use this feature, add an execution for the `process-test-aot` goal, as shown in the following example:

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

TIP: If you are using `spring-boot-starter-parent`, this execution is automatically configured if you enable the `nativeTest` profile.

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

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

0 comments on commit 8ee20c8

Please sign in to comment.