From 253cbad49db093dcbb35f3d8635973c5090f3f8a Mon Sep 17 00:00:00 2001 From: Spring Builds Date: Thu, 20 Apr 2023 08:26:47 +0000 Subject: [PATCH 001/163] Next development version (v2.7.12-SNAPSHOT) --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index a089e810eea3..8cf2e99d1688 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -version=2.7.11-SNAPSHOT +version=2.7.12-SNAPSHOT org.gradle.caching=true org.gradle.parallel=true From 573aec7d3a569ca8d832042a7dc611b9654370e5 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Thu, 20 Apr 2023 14:22:04 +0200 Subject: [PATCH 002/163] Upgrade CI to Docker 23.0.4 Closes gh-35075 --- ci/images/get-docker-url.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/images/get-docker-url.sh b/ci/images/get-docker-url.sh index 1461fe814c3c..547adf2f5013 100755 --- a/ci/images/get-docker-url.sh +++ b/ci/images/get-docker-url.sh @@ -1,5 +1,5 @@ #!/bin/bash set -e -version="23.0.3" +version="23.0.4" echo "https://download.docker.com/linux/static/stable/x86_64/docker-$version.tgz"; From 59ac9295facd37896a8222a85a5e36711b8f4394 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Thu, 20 Apr 2023 14:24:32 +0200 Subject: [PATCH 003/163] Upgrade Java 8 version in CI image and .sdkmanrc Closes gh-35074 --- .sdkmanrc | 2 +- ci/images/get-jdk-url.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.sdkmanrc b/.sdkmanrc index 67983ac1f83a..efa0e43ec434 100644 --- a/.sdkmanrc +++ b/.sdkmanrc @@ -1,3 +1,3 @@ # Enable auto-env through the sdkman_auto_env config # Add key=value pairs of SDKs to use below -java=8.0.362-librca +java=8.0.372-librca diff --git a/ci/images/get-jdk-url.sh b/ci/images/get-jdk-url.sh index 60b50def3505..d78c882535b7 100755 --- a/ci/images/get-jdk-url.sh +++ b/ci/images/get-jdk-url.sh @@ -3,7 +3,7 @@ set -e case "$1" in java8) - echo "https://github.com/bell-sw/Liberica/releases/download/8u362+9/bellsoft-jdk8u362+9-linux-amd64.tar.gz" + echo "https://github.com/bell-sw/Liberica/releases/download/8u372+7/bellsoft-jdk8u372+7-linux-amd64.tar.gz" ;; java11) echo "https://github.com/bell-sw/Liberica/releases/download/11.0.18+10/bellsoft-jdk11.0.18+10-linux-amd64.tar.gz" From 8195700c968f92929a80edc4965178419e7292b0 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Thu, 20 Apr 2023 14:25:56 +0200 Subject: [PATCH 004/163] Upgrade Java 11 version in CI image Closes gh-35076 --- ci/images/get-jdk-url.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/images/get-jdk-url.sh b/ci/images/get-jdk-url.sh index d78c882535b7..a488ea31b56a 100755 --- a/ci/images/get-jdk-url.sh +++ b/ci/images/get-jdk-url.sh @@ -6,7 +6,7 @@ case "$1" in echo "https://github.com/bell-sw/Liberica/releases/download/8u372+7/bellsoft-jdk8u372+7-linux-amd64.tar.gz" ;; java11) - echo "https://github.com/bell-sw/Liberica/releases/download/11.0.18+10/bellsoft-jdk11.0.18+10-linux-amd64.tar.gz" + echo "https://github.com/bell-sw/Liberica/releases/download/11.0.19+7/bellsoft-jdk11.0.19+7-linux-amd64.tar.gz" ;; java17) echo "https://github.com/bell-sw/Liberica/releases/download/17.0.6+10/bellsoft-jdk17.0.6+10-linux-amd64.tar.gz" From b6705b7f45a0ebbff1ca6b0517aee0dc3ffbaae2 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Thu, 20 Apr 2023 14:26:36 +0200 Subject: [PATCH 005/163] Upgrade Java 17 version in CI image Closes gh-35079 --- ci/images/get-jdk-url.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/images/get-jdk-url.sh b/ci/images/get-jdk-url.sh index a488ea31b56a..3871e396bef7 100755 --- a/ci/images/get-jdk-url.sh +++ b/ci/images/get-jdk-url.sh @@ -9,7 +9,7 @@ case "$1" in echo "https://github.com/bell-sw/Liberica/releases/download/11.0.19+7/bellsoft-jdk11.0.19+7-linux-amd64.tar.gz" ;; java17) - echo "https://github.com/bell-sw/Liberica/releases/download/17.0.6+10/bellsoft-jdk17.0.6+10-linux-amd64.tar.gz" + echo "https://github.com/bell-sw/Liberica/releases/download/17.0.7+7/bellsoft-jdk17.0.7+7-linux-amd64.tar.gz" ;; java20) echo "https://github.com/bell-sw/Liberica/releases/download/20+37/bellsoft-jdk20+37-linux-amd64.tar.gz" From 81ade5d3b579c89c87e6c2d0d0f7b5ec7ed702bd Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Thu, 20 Apr 2023 14:27:39 +0200 Subject: [PATCH 006/163] Upgrade Java 20 version in CI image Closes gh-35073 --- ci/images/get-jdk-url.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/images/get-jdk-url.sh b/ci/images/get-jdk-url.sh index 3871e396bef7..0c030b44371e 100755 --- a/ci/images/get-jdk-url.sh +++ b/ci/images/get-jdk-url.sh @@ -12,7 +12,7 @@ case "$1" in echo "https://github.com/bell-sw/Liberica/releases/download/17.0.7+7/bellsoft-jdk17.0.7+7-linux-amd64.tar.gz" ;; java20) - echo "https://github.com/bell-sw/Liberica/releases/download/20+37/bellsoft-jdk20+37-linux-amd64.tar.gz" + echo "https://github.com/bell-sw/Liberica/releases/download/20.0.1+10/bellsoft-jdk20.0.1+10-linux-amd64.tar.gz" ;; *) echo $"Unknown java version" From f4db73ead942af3e5a398f460bdccb622193a7ce Mon Sep 17 00:00:00 2001 From: Ivan Dimitrov Date: Fri, 17 Mar 2023 09:12:11 +0200 Subject: [PATCH 007/163] Harmonize references to application.yaml files in reference docs See gh-34628 --- .../src/docs/asciidoc/application-properties.adoc | 2 +- .../src/docs/asciidoc/configuration-metadata.adoc | 2 +- .../src/docs/asciidoc/features/external-config.adoc | 12 ++++++------ .../src/docs/asciidoc/features/profiles.adoc | 2 +- .../src/docs/asciidoc/howto/build.adoc | 4 ++-- .../asciidoc/howto/properties-and-configuration.adoc | 6 +++--- .../src/docs/asciidoc/howto/webserver.adoc | 4 ++-- .../src/docs/asciidoc/io/hazelcast.adoc | 2 +- 8 files changed, 17 insertions(+), 17 deletions(-) diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/application-properties.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/application-properties.adoc index 74adc6cc4152..03f81f56fc64 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/application-properties.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/application-properties.adoc @@ -5,7 +5,7 @@ include::attributes.adoc[] -Various properties can be specified inside your `application.properties` file, inside your `application.yml` file, or as command line switches. +Various properties can be specified inside your `application.properties` file, inside your `application.yaml` file, or as command line switches. This appendix provides a list of common Spring Boot properties and references to the underlying classes that consume them. TIP: Spring Boot provides various conversion mechanism with advanced value formatting, make sure to review <>. diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/configuration-metadata.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/configuration-metadata.adoc index 5a5fb7b43544..193fd065b504 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/configuration-metadata.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/configuration-metadata.adoc @@ -6,7 +6,7 @@ include::attributes.adoc[] Spring Boot jars include metadata files that provide details of all supported configuration properties. -The files are designed to let IDE developers offer contextual help and "`code completion`" as users are working with `application.properties` or `application.yml` files. +The files are designed to let IDE developers offer contextual help and "`code completion`" as users are working with `application.properties` or `application.yaml` files. The majority of the metadata file is generated automatically at compile time by processing all items annotated with `@ConfigurationProperties`. However, it is possible to <> for corner cases or more advanced use cases. diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/external-config.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/external-config.adoc index ac88cd5d4542..6d8f23bdab53 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/external-config.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/external-config.adoc @@ -35,7 +35,7 @@ Config data files are considered in the following order: . <> outside of your packaged jar (`application-\{profile}.properties` and YAML variants). NOTE: It is recommended to stick with one format for your entire application. -If you have configuration files with both `.properties` and `.yml` format in the same location, `.properties` takes precedence. +If you have configuration files with both `.properties` and YAML format in the same location, `.properties` takes precedence. To provide a concrete example, suppose you develop a `@Component` that uses a `name` property, as shown in the following example: @@ -220,7 +220,7 @@ You cannot use a wildcard in a `classpath:` location. [[features.external-config.files.profile-specific]] ==== Profile Specific Files As well as `application` property files, Spring Boot will also attempt to load profile-specific files using the naming convention `application-\{profile}`. -For example, if your application activates a profile named `prod` and uses YAML files, then both `application.yml` and `application-prod.yml` will be considered. +For example, if your application activates a profile named `prod` and uses YAML files, then both `application.yaml` and `application-prod.yaml` will be considered. Profile-specific properties are loaded from the same locations as standard `application.properties`, with profile-specific files always overriding the non-specific ones. If several profiles are specified, a last-wins strategy applies. @@ -441,7 +441,7 @@ For example, if a secret named `db.password` is mounted at location `/run/secret [[features.external-config.files.property-placeholders]] ==== Property Placeholders -The values in `application.properties` and `application.yml` are filtered through the existing `Environment` when they are used, so you can refer back to previously defined values (for example, from System properties or environment variables). +The values in `application.properties` and `application.yaml` are filtered through the existing `Environment` when they are used, so you can refer back to previously defined values (for example, from System properties or environment variables). The standard `$\{name}` property-placeholder syntax can be used anywhere within a value. Property placeholders can also specify a default value using a `:` to separate the default value from the property name, for example `${name:default}`. @@ -476,7 +476,7 @@ Spring Boot allows you to split a single physical file into multiple logical doc Documents are processed in order, from top to bottom. Later documents can override the properties defined in earlier ones. -For `application.yml` files, the standard YAML multi-document syntax is used. +For `application.yaml` files, the standard YAML multi-document syntax is used. Three consecutive hyphens represent the end of one document, and the start of the next. For example, the following file has two logical documents: @@ -834,13 +834,13 @@ With the preceding code, the following properties names can all be used: | Property | Note | `my.main-project.person.first-name` -| Kebab case, which is recommended for use in `.properties` and `.yml` files. +| Kebab case, which is recommended for use in `.properties` and YAML files. | `my.main-project.person.firstName` | Standard camel case syntax. | `my.main-project.person.first_name` -| Underscore notation, which is an alternative format for use in `.properties` and `.yml` files. +| Underscore notation, which is an alternative format for use in `.properties` and YAML files. | `MY_MAINPROJECT_PERSON_FIRSTNAME` | Upper case format, which is recommended when using system environment variables. diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/profiles.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/profiles.adoc index cea00d60231f..f00af692b1ca 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/profiles.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/profiles.adoc @@ -115,5 +115,5 @@ It is also possible to activate profiles by using Spring's `ConfigurableEnvironm [[features.profiles.profile-specific-configuration-files]] === Profile-specific Configuration Files -Profile-specific variants of both `application.properties` (or `application.yml`) and files referenced through `@ConfigurationProperties` are considered as files and loaded. +Profile-specific variants of both `application.properties` (or `application.yaml`) and files referenced through `@ConfigurationProperties` are considered as files and loaded. See "<>" for details. diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto/build.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto/build.adoc index b4dc9b030c4a..c176b8534b25 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto/build.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto/build.adoc @@ -212,7 +212,7 @@ For example, to indicate that JRuby should be flagged for unpacking by using the [[howto.build.create-a-nonexecutable-jar]] === Create a Non-executable JAR with Exclusions Often, if you have an executable and a non-executable jar as two separate build products, the executable version has additional configuration files that are not needed in a library jar. -For example, the `application.yml` configuration file might be excluded from the non-executable JAR. +For example, the `application.yaml` configuration file might be excluded from the non-executable JAR. In Maven, the executable jar must be the main artifact and you can add a classified jar for the library, as follows: @@ -236,7 +236,7 @@ In Maven, the executable jar must be the main artifact and you can add a classif lib - application.yml + application.yaml diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto/properties-and-configuration.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto/properties-and-configuration.adoc index 5e3e45622be6..208b3504a2f5 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto/properties-and-configuration.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto/properties-and-configuration.adoc @@ -146,7 +146,7 @@ You can also provide the following System properties (or environment variables) A separate `Environment` property source is set up for this document and it can be overridden by system properties, environment variables, or the command line. No matter what you set in the environment, Spring Boot always loads `application.properties` as described above. -By default, if YAML is used, then files with the '`.yml`' extension are also added to the list. +By default, if YAML is used, then files with the '`.yaml`' and '`.yml`' extension are also added to the list. TIP: If you want detailed information about the files that are being loaded you can <> of `org.springframework.boot.context.config` to `trace`. @@ -187,7 +187,7 @@ YAML is a superset of JSON and, as such, is a convenient syntax for storing exte port: 9000 ---- -Create a file called `application.yml` and put it in the root of your classpath. +Create a file called `application.yaml` and put it in the root of your classpath. Then add `snakeyaml` to your dependencies (Maven coordinates `org.yaml:snakeyaml`, already included if you use the `spring-boot-starter`). A YAML file is parsed to a Java `Map` (like a JSON object), and Spring Boot flattens the map so that it is one level deep and has period-separated keys, as many people are used to with `Properties` files in Java. @@ -287,7 +287,7 @@ Later values override earlier values. [[howto.properties-and-configuration.discover-build-in-options-for-external-properties]] === Discover Built-in Options for External Properties -Spring Boot binds external properties from `application.properties` (or `.yml` files and other places) into an application at runtime. +Spring Boot binds external properties from `application.properties` (or YAML files and other places) into an application at runtime. There is not (and technically cannot be) an exhaustive list of all supported properties in a single location, because contributions can come from additional jar files on your classpath. A running application with the Actuator features has a `configprops` endpoint that shows all the bound and bindable properties available through `@ConfigurationProperties`. diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto/webserver.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto/webserver.adoc index 9843d9de1d48..11f53e384ddb 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto/webserver.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto/webserver.adoc @@ -182,7 +182,7 @@ You can configure this behavior by setting the configprop:server.compression.mim [[howto.webserver.configure-ssl]] === Configure SSL -SSL can be configured declaratively by setting the various `+server.ssl.*+` properties, typically in `application.properties` or `application.yml`. +SSL can be configured declaratively by setting the various `+server.ssl.*+` properties, typically in `application.properties` or `application.yaml`. The following example shows setting SSL properties using a Java KeyStore file: [source,yaml,indent=0,subs="verbatim",configprops,configblocks] @@ -280,7 +280,7 @@ As of Undertow 1.4.0+, both `h2` and `h2c` are supported on JDK 8 without any ad [[howto.webserver.configure]] === Configure the Web Server -Generally, you should first consider using one of the many available configuration keys and customize your web server by adding new entries in your `application.properties` or `application.yml` file. +Generally, you should first consider using one of the many available configuration keys and customize your web server by adding new entries in your `application.properties` or `application.yaml` file. See "`<>`"). The `server.{asterisk}` namespace is quite useful here, and it includes namespaces like `server.tomcat.{asterisk}`, `server.jetty.{asterisk}` and others, for server-specific features. See the list of <>. diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/io/hazelcast.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/io/hazelcast.adoc index baee78ae1178..8b346c9f9f99 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/io/hazelcast.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/io/hazelcast.adoc @@ -26,7 +26,7 @@ You could also specify the Hazelcast configuration file to use through configura config: "classpath:config/my-hazelcast.xml" ---- -Otherwise, Spring Boot tries to find the Hazelcast configuration from the default locations: `hazelcast.xml` in the working directory or at the root of the classpath, or a `.yaml`/`.yml` counterpart in the same locations. +Otherwise, Spring Boot tries to find the Hazelcast configuration from the default locations: `hazelcast.xml` in the working directory or at the root of the classpath, or a YAML counterpart in the same locations. We also check if the `hazelcast.config` system property is set. See the https://docs.hazelcast.org/docs/latest/manual/html-single/[Hazelcast documentation] for more details. From 90952a2dd9a42d15aa9705b86c0416c3b69bc421 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Mon, 24 Apr 2023 14:44:04 +0100 Subject: [PATCH 008/163] Do not turn a null Flyway-specific password into an empty string It prevents using PGPASS for authentication with Postgres. Fixes gh-35110 --- .../boot/autoconfigure/flyway/FlywayProperties.java | 4 ++-- .../autoconfigure/flyway/FlywayAutoConfigurationTests.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayProperties.java index 9c8663e32e60..46edd4f81849 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -601,7 +601,7 @@ public void setUser(String user) { } public String getPassword() { - return (this.password != null) ? this.password : ""; + return this.password; } public void setPassword(String password) { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfigurationTests.java index f6cd5f2f14c9..e53ef5277a50 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfigurationTests.java @@ -154,7 +154,7 @@ void createDataSourceDoesNotFallbackToEmbeddedProperties() { DataSource dataSource = context.getBean(Flyway.class).getConfiguration().getDataSource(); assertThat(dataSource).isNotNull(); assertThat(dataSource).hasFieldOrPropertyWithValue("username", null); - assertThat(dataSource).hasFieldOrPropertyWithValue("password", ""); + assertThat(dataSource).hasFieldOrPropertyWithValue("password", null); }); } From 963542e7fc36ab5ac642ed40f158b108feb71d2a Mon Sep 17 00:00:00 2001 From: Scott Frederick Date: Mon, 24 Apr 2023 16:18:56 -0500 Subject: [PATCH 009/163] Adapt Paketo system tests to changes in the Tomcat buildpack Closes gh-35148 --- .../boot/image/paketo/PaketoBuilderTests.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/spring-boot-system-tests/spring-boot-image-tests/src/systemTest/java/org/springframework/boot/image/paketo/PaketoBuilderTests.java b/spring-boot-system-tests/spring-boot-image-tests/src/systemTest/java/org/springframework/boot/image/paketo/PaketoBuilderTests.java index 86ce995ded65..14131fce1c07 100644 --- a/spring-boot-system-tests/spring-boot-image-tests/src/systemTest/java/org/springframework/boot/image/paketo/PaketoBuilderTests.java +++ b/spring-boot-system-tests/spring-boot-image-tests/src/systemTest/java/org/springframework/boot/image/paketo/PaketoBuilderTests.java @@ -21,7 +21,6 @@ import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.function.Consumer; @@ -276,10 +275,16 @@ void plainWarApp() throws Exception { "paketo-buildpacks/spring-boot"); metadata.processOfType("web") .extracting("command", "args") - .containsExactly("bash", Arrays.asList("catalina.sh", "run")); + .satisfiesExactly((command) -> assertThat(command).asString().endsWith("sh"), + (args) -> assertThat(args).asList() + .satisfiesExactly((arg) -> assertThat(arg).asString().endsWith("catalina.sh"), + (arg) -> assertThat(arg).asString().isEqualTo("run"))); metadata.processOfType("tomcat") .extracting("command", "args") - .containsExactly("bash", Arrays.asList("catalina.sh", "run")); + .satisfiesExactly((command) -> assertThat(command).asString().endsWith("sh"), + (args) -> assertThat(args).asList() + .satisfiesExactly((arg) -> assertThat(arg).asString().endsWith("catalina.sh"), + (arg) -> assertThat(arg).asString().isEqualTo("run"))); }); assertImageHasSbomLayer(imageReference, config, "apache-tomcat"); DigestCapturingCondition digest = new DigestCapturingCondition(); From a707c5e83e479099f8dd71fb06806e143efdd119 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Mon, 24 Apr 2023 17:15:56 -0700 Subject: [PATCH 010/163] Polish "Fix support for default values in banner placeholders" Reorder methods and add a test to ensure that getPropertyResolvers can be mutated. See gh-34764 --- .../springframework/boot/ResourceBanner.java | 61 ++++++++++++------- .../boot/ResourceBannerTests.java | 47 +++++++++++++- 2 files changed, 84 insertions(+), 24 deletions(-) diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ResourceBanner.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ResourceBanner.java index 46108497dfaf..68867dec2c4f 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ResourceBanner.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ResourceBanner.java @@ -19,6 +19,7 @@ import java.io.PrintStream; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -65,7 +66,6 @@ public void printBanner(Environment environment, Class sourceClass, PrintStre try { String banner = StreamUtils.copyToString(this.resource.getInputStream(), environment.getProperty("spring.banner.charset", Charset.class, StandardCharsets.UTF_8)); - for (PropertyResolver resolver : getPropertyResolvers(environment, sourceClass)) { banner = resolver.resolvePlaceholders(banner); } @@ -77,15 +77,46 @@ public void printBanner(Environment environment, Class sourceClass, PrintStre } } + /** + * Return a mutable list of the {@link PropertyResolver} instances that will be used + * to resolve placeholders. + * @param environment the environment + * @param sourceClass the source class + * @return a mutable list of property resolvers + */ protected List getPropertyResolvers(Environment environment, Class sourceClass) { - MutablePropertySources propertySources = new MutablePropertySources(); + MutablePropertySources sources = new MutablePropertySources(); if (environment instanceof ConfigurableEnvironment) { - ((ConfigurableEnvironment) environment).getPropertySources().forEach(propertySources::addLast); + ((ConfigurableEnvironment) environment).getPropertySources().forEach(sources::addLast); } - propertySources.addLast(getTitleSource(sourceClass)); - propertySources.addLast(getAnsiSource()); - propertySources.addLast(getVersionSource(sourceClass)); - return Collections.singletonList(new PropertySourcesPropertyResolver(propertySources)); + sources.addLast(getTitleSource(sourceClass)); + sources.addLast(getAnsiSource()); + sources.addLast(getVersionSource(sourceClass)); + List resolvers = new ArrayList<>(); + resolvers.add(new PropertySourcesPropertyResolver(sources)); + return resolvers; + } + + private MapPropertySource getTitleSource(Class sourceClass) { + String applicationTitle = getApplicationTitle(sourceClass); + Map titleMap = Collections.singletonMap("application.title", + (applicationTitle != null) ? applicationTitle : ""); + return new MapPropertySource("title", titleMap); + } + + /** + * Return the application title that should be used for the source class. By default + * will use {@link Package#getImplementationTitle()}. + * @param sourceClass the source class + * @return the application title + */ + protected String getApplicationTitle(Class sourceClass) { + Package sourcePackage = (sourceClass != null) ? sourceClass.getPackage() : null; + return (sourcePackage != null) ? sourcePackage.getImplementationTitle() : null; + } + + private AnsiPropertySource getAnsiSource() { + return new AnsiPropertySource("ansi", true); } private MapPropertySource getVersionSource(Class sourceClass) { @@ -119,20 +150,4 @@ private String getVersionString(String version, boolean format) { return format ? " (v" + version + ")" : version; } - private AnsiPropertySource getAnsiSource() { - return new AnsiPropertySource("ansi", true); - } - - private MapPropertySource getTitleSource(Class sourceClass) { - String applicationTitle = getApplicationTitle(sourceClass); - Map titleMap = Collections.singletonMap("application.title", - (applicationTitle != null) ? applicationTitle : ""); - return new MapPropertySource("title", titleMap); - } - - protected String getApplicationTitle(Class sourceClass) { - Package sourcePackage = (sourceClass != null) ? sourceClass.getPackage() : null; - return (sourcePackage != null) ? sourcePackage.getImplementationTitle() : null; - } - } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/ResourceBannerTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/ResourceBannerTests.java index 9960e78c9b88..8ba272032d46 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/ResourceBannerTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/ResourceBannerTests.java @@ -19,6 +19,7 @@ import java.io.ByteArrayOutputStream; import java.io.PrintStream; import java.util.Collections; +import java.util.List; import java.util.Map; import org.junit.jupiter.api.AfterEach; @@ -26,8 +27,11 @@ import org.springframework.boot.ansi.AnsiOutput; import org.springframework.boot.ansi.AnsiOutput.Enabled; +import org.springframework.core.env.AbstractPropertyResolver; import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.Environment; import org.springframework.core.env.MapPropertySource; +import org.springframework.core.env.PropertyResolver; import org.springframework.core.io.ByteArrayResource; import org.springframework.core.io.Resource; import org.springframework.mock.env.MockEnvironment; @@ -136,9 +140,20 @@ void renderWithDefaultValues() { assertThat(banner).startsWith("banner 1 default-b 10.2 1.0"); } + @Test + void renderWithMutation() { + Resource resource = new ByteArrayResource("banner ${foo}".getBytes()); + String banner = printBanner(new MutatingResourceBanner(resource, "1", "2", null)); + assertThat(banner).startsWith("banner bar"); + + } + private String printBanner(Resource resource, String bootVersion, String applicationVersion, String applicationTitle) { - ResourceBanner banner = new MockResourceBanner(resource, bootVersion, applicationVersion, applicationTitle); + return printBanner(new MockResourceBanner(resource, bootVersion, applicationVersion, applicationTitle)); + } + + private String printBanner(ResourceBanner banner) { ConfigurableEnvironment environment = new MockEnvironment(); Map source = Collections.singletonMap("a", "1"); environment.getPropertySources().addLast(new MapPropertySource("map", source)); @@ -179,4 +194,34 @@ protected String getApplicationTitle(Class sourceClass) { } + static class MutatingResourceBanner extends MockResourceBanner { + + MutatingResourceBanner(Resource resource, String bootVersion, String applicationVersion, + String applicationTitle) { + super(resource, bootVersion, applicationVersion, applicationTitle); + } + + @Override + protected List getPropertyResolvers(Environment environment, Class sourceClass) { + List resolvers = super.getPropertyResolvers(environment, sourceClass); + PropertyResolver resolver = new AbstractPropertyResolver() { + + @Override + @SuppressWarnings("unchecked") + public T getProperty(String key, Class targetType) { + return String.class.equals(targetType) ? (T) getPropertyAsRawString(key) : null; + } + + @Override + protected String getPropertyAsRawString(String key) { + return ("foo".equals(key)) ? "bar" : null; + } + + }; + resolvers.add(resolver); + return resolvers; + } + + } + } From 472afafd4bc351f139716edf8b899a5a79df6808 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 25 Apr 2023 11:22:33 +0100 Subject: [PATCH 011/163] Stop WebFilterChainPostProcessor from causing eager init Fixes gh-35163 --- ...tiveCloudFoundryActuatorAutoConfiguration.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundryActuatorAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundryActuatorAutoConfiguration.java index 1548bbbb10b9..dd109244b628 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundryActuatorAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundryActuatorAutoConfiguration.java @@ -21,6 +21,7 @@ import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.function.Supplier; import java.util.stream.Collectors; import org.springframework.beans.BeansException; @@ -64,6 +65,7 @@ import org.springframework.security.web.server.WebFilterChainProxy; import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher; import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatchers; +import org.springframework.util.function.SingletonSupplier; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.server.WebFilter; @@ -155,8 +157,8 @@ private CorsConfiguration getCorsConfiguration() { static class IgnoredPathsSecurityConfiguration { @Bean - WebFilterChainPostProcessor webFilterChainPostProcessor( - CloudFoundryWebFluxEndpointHandlerMapping handlerMapping) { + static WebFilterChainPostProcessor webFilterChainPostProcessor( + ObjectProvider handlerMapping) { return new WebFilterChainPostProcessor(handlerMapping); } @@ -164,16 +166,17 @@ WebFilterChainPostProcessor webFilterChainPostProcessor( static class WebFilterChainPostProcessor implements BeanPostProcessor { - private final PathMappedEndpoints pathMappedEndpoints; + private Supplier pathMappedEndpoints; - WebFilterChainPostProcessor(CloudFoundryWebFluxEndpointHandlerMapping handlerMapping) { - this.pathMappedEndpoints = new PathMappedEndpoints(BASE_PATH, handlerMapping::getAllEndpoints); + WebFilterChainPostProcessor(ObjectProvider handlerMapping) { + this.pathMappedEndpoints = SingletonSupplier + .of(() -> new PathMappedEndpoints(BASE_PATH, () -> handlerMapping.getObject().getAllEndpoints())); } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof WebFilterChainProxy) { - return postProcess((WebFilterChainProxy) bean, this.pathMappedEndpoints); + return postProcess((WebFilterChainProxy) bean, this.pathMappedEndpoints.get()); } return bean; } From 6b9bc012a54dd7a72130d2163b5d9a012eafb809 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 25 Apr 2023 22:07:31 +0100 Subject: [PATCH 012/163] Check that BPP and BFPP bean methods won't cause eager initialization Closes gh-35164 --- buildSrc/build.gradle | 1 + .../build/architecture/ArchitectureCheck.java | 186 ++++++++++++++++++ .../architecture/ArchitecturePlugin.java | 12 +- .../architecture/PackageTangleCheck.java | 102 ---------- .../boot/build/architecture/Rules.java | 62 ++++++ .../architecture/ArchitectureCheckTests.java | 148 ++++++++++++++ .../architecture/PackageTangleCheckTests.java | 93 --------- ...BeanFactoryPostProcessorConfiguration.java | 30 +++ ...BeanFactoryPostProcessorConfiguration.java | 40 ++++ ...BeanFactoryPostProcessorConfiguration.java | 40 ++++ ...nStaticBeanPostProcessorConfiguration.java | 31 +++ ...ametersBeanPostProcessorConfiguration.java | 41 ++++ ...ametersBeanPostProcessorConfiguration.java | 46 +++++ ...ametersBeanPostProcessorConfiguration.java | 43 ++++ ...ionPropertiesReportEndpointProxyTests.java | 2 +- .../web/annotation/BaseConfiguration.java | 2 +- .../RedisAutoConfigurationJedisTests.java | 2 +- .../ValidationAutoConfigurationTests.java | 2 +- ...ToolsDataSourceAutoConfigurationTests.java | 2 +- .../PropertySourcesDeducerTests.java | 6 +- 20 files changed, 682 insertions(+), 209 deletions(-) create mode 100644 buildSrc/src/main/java/org/springframework/boot/build/architecture/ArchitectureCheck.java delete mode 100644 buildSrc/src/main/java/org/springframework/boot/build/architecture/PackageTangleCheck.java create mode 100644 buildSrc/src/main/java/org/springframework/boot/build/architecture/Rules.java create mode 100644 buildSrc/src/test/java/org/springframework/boot/build/architecture/ArchitectureCheckTests.java delete mode 100644 buildSrc/src/test/java/org/springframework/boot/build/architecture/PackageTangleCheckTests.java create mode 100644 buildSrc/src/test/java/org/springframework/boot/build/architecture/bfpp/nonstatic/NonStaticBeanFactoryPostProcessorConfiguration.java create mode 100644 buildSrc/src/test/java/org/springframework/boot/build/architecture/bfpp/noparameters/NoParametersBeanFactoryPostProcessorConfiguration.java create mode 100644 buildSrc/src/test/java/org/springframework/boot/build/architecture/bfpp/parameters/ParametersBeanFactoryPostProcessorConfiguration.java create mode 100644 buildSrc/src/test/java/org/springframework/boot/build/architecture/bpp/nonstatic/NonStaticBeanPostProcessorConfiguration.java create mode 100644 buildSrc/src/test/java/org/springframework/boot/build/architecture/bpp/noparameters/NoParametersBeanPostProcessorConfiguration.java create mode 100644 buildSrc/src/test/java/org/springframework/boot/build/architecture/bpp/safeparameters/SafeParametersBeanPostProcessorConfiguration.java create mode 100644 buildSrc/src/test/java/org/springframework/boot/build/architecture/bpp/unsafeparameters/UnsafeParametersBeanPostProcessorConfiguration.java diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index f1ee4b87525f..0fc303c70e6e 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -38,6 +38,7 @@ dependencies { testImplementation("org.assertj:assertj-core:3.11.1") testImplementation("org.apache.logging.log4j:log4j-core:2.17.1") testImplementation("org.junit.jupiter:junit-jupiter:5.6.0") + implementation("org.springframework:spring-context") testRuntimeOnly("org.junit.platform:junit-platform-launcher") } diff --git a/buildSrc/src/main/java/org/springframework/boot/build/architecture/ArchitectureCheck.java b/buildSrc/src/main/java/org/springframework/boot/build/architecture/ArchitectureCheck.java new file mode 100644 index 000000000000..e6dba8e5cff5 --- /dev/null +++ b/buildSrc/src/main/java/org/springframework/boot/build/architecture/ArchitectureCheck.java @@ -0,0 +1,186 @@ +/* + * Copyright 2022-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.build.architecture; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.StandardOpenOption; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import com.tngtech.archunit.base.DescribedPredicate; +import com.tngtech.archunit.core.domain.JavaClass; +import com.tngtech.archunit.core.domain.JavaClass.Predicates; +import com.tngtech.archunit.core.domain.JavaClasses; +import com.tngtech.archunit.core.domain.JavaMethod; +import com.tngtech.archunit.core.domain.JavaParameter; +import com.tngtech.archunit.core.domain.properties.CanBeAnnotated; +import com.tngtech.archunit.core.importer.ClassFileImporter; +import com.tngtech.archunit.lang.ArchCondition; +import com.tngtech.archunit.lang.ArchRule; +import com.tngtech.archunit.lang.ConditionEvents; +import com.tngtech.archunit.lang.EvaluationResult; +import com.tngtech.archunit.lang.SimpleConditionEvent; +import com.tngtech.archunit.lang.syntax.ArchRuleDefinition; +import com.tngtech.archunit.library.dependencies.SlicesRuleDefinition; +import org.gradle.api.DefaultTask; +import org.gradle.api.GradleException; +import org.gradle.api.Task; +import org.gradle.api.file.DirectoryProperty; +import org.gradle.api.file.FileCollection; +import org.gradle.api.file.FileTree; +import org.gradle.api.tasks.IgnoreEmptyDirectories; +import org.gradle.api.tasks.InputFiles; +import org.gradle.api.tasks.Internal; +import org.gradle.api.tasks.OutputDirectory; +import org.gradle.api.tasks.PathSensitive; +import org.gradle.api.tasks.PathSensitivity; +import org.gradle.api.tasks.SkipWhenEmpty; +import org.gradle.api.tasks.TaskAction; + +/** + * {@link Task} that checks for architecture problems. + * + * @author Andy Wilkinson + */ +public abstract class ArchitectureCheck extends DefaultTask { + + private FileCollection classes; + + public ArchitectureCheck() { + getOutputDirectory().convention(getProject().getLayout().getBuildDirectory().dir(getName())); + } + + @TaskAction + void checkArchitecture() throws IOException { + JavaClasses javaClasses = new ClassFileImporter() + .importPaths(this.classes.getFiles().stream().map(File::toPath).collect(Collectors.toList())); + List violations = Stream.of(allPackagesShouldBeFreeOfTangles(), + allBeanPostProcessorBeanMethodsShouldBeStaticAndHaveParametersThatWillNotCausePrematureInitialization(), + allBeanFactoryPostProcessorBeanMethodsShouldBeStaticAndHaveNoParameters()) + .map((rule) -> rule.evaluate(javaClasses)) + .filter(EvaluationResult::hasViolation) + .collect(Collectors.toList()); + File outputFile = getOutputDirectory().file("failure-report.txt").get().getAsFile(); + outputFile.getParentFile().mkdirs(); + if (!violations.isEmpty()) { + StringBuilder report = new StringBuilder(); + for (EvaluationResult violation : violations) { + report.append(violation.getFailureReport().toString()); + report.append(String.format("%n")); + } + Files.write(outputFile.toPath(), report.toString().getBytes(StandardCharsets.UTF_8), + StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); + throw new GradleException("Architecture check failed. See '" + outputFile + "' for details."); + } + else { + outputFile.createNewFile(); + } + } + + private ArchRule allPackagesShouldBeFreeOfTangles() { + return SlicesRuleDefinition.slices().matching("(**)").should().beFreeOfCycles(); + } + + private ArchRule allBeanPostProcessorBeanMethodsShouldBeStaticAndHaveParametersThatWillNotCausePrematureInitialization() { + return ArchRuleDefinition.methods() + .that() + .areAnnotatedWith("org.springframework.context.annotation.Bean") + .and() + .haveRawReturnType(Predicates.assignableTo("org.springframework.beans.factory.config.BeanPostProcessor")) + .should(onlyHaveParametersThatWillNotCauseEagerInitialization()) + .andShould() + .beStatic() + .allowEmptyShould(true); + } + + private ArchCondition onlyHaveParametersThatWillNotCauseEagerInitialization() { + DescribedPredicate notAnnotatedWithLazy = DescribedPredicate + .not(CanBeAnnotated.Predicates.annotatedWith("org.springframework.context.annotation.Lazy")); + DescribedPredicate notOfASafeType = DescribedPredicate + .not(Predicates.assignableTo("org.springframework.beans.factory.ObjectProvider") + .or(Predicates.assignableTo("org.springframework.context.ApplicationContext")) + .or(Predicates.assignableTo("org.springframework.core.env.Environment"))); + return new ArchCondition("not have parameters that will cause eager initialization") { + + @Override + public void check(JavaMethod item, ConditionEvents events) { + item.getParameters() + .stream() + .filter(notAnnotatedWithLazy) + .filter((parameter) -> notOfASafeType.test(parameter.getRawType())) + .forEach((parameter) -> events.add(SimpleConditionEvent.violated(parameter, + parameter.getDescription() + " will cause eager initialization as it is " + + notAnnotatedWithLazy.getDescription() + " and is " + + notOfASafeType.getDescription()))); + } + + }; + } + + private ArchRule allBeanFactoryPostProcessorBeanMethodsShouldBeStaticAndHaveNoParameters() { + return ArchRuleDefinition.methods() + .that() + .areAnnotatedWith("org.springframework.context.annotation.Bean") + .and() + .haveRawReturnType( + Predicates.assignableTo("org.springframework.beans.factory.config.BeanFactoryPostProcessor")) + .should(haveNoParameters()) + .andShould() + .beStatic() + .allowEmptyShould(true); + } + + private ArchCondition haveNoParameters() { + return new ArchCondition("have no parameters") { + + @Override + public void check(JavaMethod item, ConditionEvents events) { + List parameters = item.getParameters(); + if (!parameters.isEmpty()) { + events + .add(SimpleConditionEvent.violated(item, item.getDescription() + " should have no parameters")); + } + } + + }; + } + + public void setClasses(FileCollection classes) { + this.classes = classes; + } + + @Internal + public FileCollection getClasses() { + return this.classes; + } + + @InputFiles + @SkipWhenEmpty + @IgnoreEmptyDirectories + @PathSensitive(PathSensitivity.RELATIVE) + final FileTree getInputClasses() { + return this.classes.getAsFileTree(); + } + + @OutputDirectory + public abstract DirectoryProperty getOutputDirectory(); + +} diff --git a/buildSrc/src/main/java/org/springframework/boot/build/architecture/ArchitecturePlugin.java b/buildSrc/src/main/java/org/springframework/boot/build/architecture/ArchitecturePlugin.java index c95c433572e8..102ddf72e002 100644 --- a/buildSrc/src/main/java/org/springframework/boot/build/architecture/ArchitecturePlugin.java +++ b/buildSrc/src/main/java/org/springframework/boot/build/architecture/ArchitecturePlugin.java @@ -44,14 +44,14 @@ public void apply(Project project) { private void registerTasks(Project project) { JavaPluginExtension javaPluginExtension = project.getExtensions().getByType(JavaPluginExtension.class); - List> packageTangleChecks = new ArrayList<>(); + List> packageTangleChecks = new ArrayList<>(); for (SourceSet sourceSet : javaPluginExtension.getSourceSets()) { - TaskProvider checkPackageTangles = project.getTasks() - .register("checkForPackageTangles" + StringUtils.capitalize(sourceSet.getName()), - PackageTangleCheck.class, (task) -> { + TaskProvider checkPackageTangles = project.getTasks() + .register("checkArchitecture" + StringUtils.capitalize(sourceSet.getName()), ArchitectureCheck.class, + (task) -> { task.setClasses(sourceSet.getOutput().getClassesDirs()); - task.setDescription("Checks the classes of the " + sourceSet.getName() - + " source set for package tangles."); + task.setDescription("Checks the architecture of the classes of the " + sourceSet.getName() + + " source set."); task.setGroup(LifecycleBasePlugin.VERIFICATION_GROUP); }); packageTangleChecks.add(checkPackageTangles); diff --git a/buildSrc/src/main/java/org/springframework/boot/build/architecture/PackageTangleCheck.java b/buildSrc/src/main/java/org/springframework/boot/build/architecture/PackageTangleCheck.java deleted file mode 100644 index 715ac5f68618..000000000000 --- a/buildSrc/src/main/java/org/springframework/boot/build/architecture/PackageTangleCheck.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2022-2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.build.architecture; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.StandardOpenOption; -import java.util.stream.Collectors; - -import com.tngtech.archunit.core.domain.JavaClasses; -import com.tngtech.archunit.core.importer.ClassFileImporter; -import com.tngtech.archunit.lang.EvaluationResult; -import com.tngtech.archunit.library.dependencies.SliceRule; -import com.tngtech.archunit.library.dependencies.SlicesRuleDefinition; -import org.gradle.api.DefaultTask; -import org.gradle.api.GradleException; -import org.gradle.api.Task; -import org.gradle.api.file.DirectoryProperty; -import org.gradle.api.file.FileCollection; -import org.gradle.api.file.FileTree; -import org.gradle.api.tasks.IgnoreEmptyDirectories; -import org.gradle.api.tasks.InputFiles; -import org.gradle.api.tasks.Internal; -import org.gradle.api.tasks.OutputDirectory; -import org.gradle.api.tasks.PathSensitive; -import org.gradle.api.tasks.PathSensitivity; -import org.gradle.api.tasks.SkipWhenEmpty; -import org.gradle.api.tasks.TaskAction; - -import org.springframework.util.FileCopyUtils; - -/** - * {@link Task} that checks for package tangles. - * - * @author Andy Wilkinson - */ -public abstract class PackageTangleCheck extends DefaultTask { - - private FileCollection classes; - - public PackageTangleCheck() { - getOutputDirectory().convention(getProject().getLayout().getBuildDirectory().dir(getName())); - } - - @TaskAction - void checkForPackageTangles() throws IOException { - JavaClasses javaClasses = new ClassFileImporter() - .importPaths(this.classes.getFiles().stream().map(File::toPath).collect(Collectors.toList())); - SliceRule freeOfCycles = SlicesRuleDefinition.slices().matching("(**)").should().beFreeOfCycles(); - EvaluationResult result = freeOfCycles.evaluate(javaClasses); - File outputFile = getOutputDirectory().file("failure-report.txt").get().getAsFile(); - outputFile.getParentFile().mkdirs(); - if (result.hasViolation()) { - Files.write(outputFile.toPath(), result.getFailureReport().toString().getBytes(StandardCharsets.UTF_8), - StandardOpenOption.CREATE); - FileWriter writer = new FileWriter(outputFile); - FileCopyUtils.copy(result.getFailureReport().toString(), writer); - throw new GradleException("Package tangle check failed. See '" + outputFile + "' for details."); - } - else { - outputFile.createNewFile(); - } - } - - public void setClasses(FileCollection classes) { - this.classes = classes; - } - - @Internal - public FileCollection getClasses() { - return this.classes; - } - - @InputFiles - @SkipWhenEmpty - @IgnoreEmptyDirectories - @PathSensitive(PathSensitivity.RELATIVE) - final FileTree getInputClasses() { - return this.classes.getAsFileTree(); - } - - @OutputDirectory - public abstract DirectoryProperty getOutputDirectory(); - -} diff --git a/buildSrc/src/main/java/org/springframework/boot/build/architecture/Rules.java b/buildSrc/src/main/java/org/springframework/boot/build/architecture/Rules.java new file mode 100644 index 000000000000..d12c0a813bd2 --- /dev/null +++ b/buildSrc/src/main/java/org/springframework/boot/build/architecture/Rules.java @@ -0,0 +1,62 @@ +/* + * Copyright 2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.build.architecture; + +import java.util.stream.Stream; + +import com.tngtech.archunit.base.DescribedPredicate; +import com.tngtech.archunit.core.domain.JavaClass.Predicates; +import com.tngtech.archunit.lang.ArchRule; +import com.tngtech.archunit.lang.syntax.ArchRuleDefinition; +import com.tngtech.archunit.library.dependencies.SlicesRuleDefinition; + +/** + * Architecture rules evaluated by {@link ArchitectureCheck}. + * + * @author Andy Wilkinson + */ +final class Rules { + + private Rules() { + + } + + static Stream stream() { + return Stream.of(allPackagesShouldBeFreeOfTangles(), + allBeanPostProcessorBeanMethodsShouldBeStaticAndHaveParametersThatWillNotCausePrematureInitialization()); + } + + static ArchRule allPackagesShouldBeFreeOfTangles() { + return SlicesRuleDefinition.slices().matching("(**)").should().beFreeOfCycles(); + } + + static ArchRule allBeanPostProcessorBeanMethodsShouldBeStaticAndHaveParametersThatWillNotCausePrematureInitialization() { + return ArchRuleDefinition.methods() + .that() + .areAnnotatedWith("org.springframework.context.annotation.Bean") + .and() + .haveRawReturnType(Predicates.assignableTo("org.springframework.beans.factory.config.BeanPostProcessor")) + .should() + .beStatic() + .andShould() + .haveRawParameterTypes(DescribedPredicate + .allElements(Predicates.assignableTo("org.springframework.beans.factory.ObjectProvider") + .or(Predicates.assignableTo("org.springframework.context.ApplicationContext")))) + .allowEmptyShould(true); + } + +} diff --git a/buildSrc/src/test/java/org/springframework/boot/build/architecture/ArchitectureCheckTests.java b/buildSrc/src/test/java/org/springframework/boot/build/architecture/ArchitectureCheckTests.java new file mode 100644 index 000000000000..61001c784339 --- /dev/null +++ b/buildSrc/src/test/java/org/springframework/boot/build/architecture/ArchitectureCheckTests.java @@ -0,0 +1,148 @@ +/* + * Copyright 2012-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.build.architecture; + +import java.io.File; +import java.io.IOException; + +import org.gradle.api.GradleException; +import org.gradle.api.Project; +import org.gradle.testfixtures.ProjectBuilder; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.util.FileSystemUtils; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + +/** + * Tests for {@link ArchitectureCheck}. + * + * @author Andy Wilkinson + */ +class ArchitectureCheckTests { + + @TempDir + File temp; + + @Test + void whenPackagesAreTangledTaskFailsAndWritesAReport() throws Exception { + prepareTask("tangled", (architectureCheck) -> { + assertThatExceptionOfType(GradleException.class).isThrownBy(() -> architectureCheck.checkArchitecture()); + assertThat(failureReport(architectureCheck).length()).isGreaterThan(0); + }); + } + + @Test + void whenPackagesAreNotTangledTaskSucceedsAndWritesAnEmptyReport() throws Exception { + prepareTask("untangled", (architectureCheck) -> { + architectureCheck.checkArchitecture(); + assertThat(failureReport(architectureCheck).length()).isZero(); + }); + } + + File failureReport(ArchitectureCheck architectureCheck) { + return new File(architectureCheck.getProject().getBuildDir(), "checkArchitecture/failure-report.txt"); + } + + @Test + void whenBeanPostProcessorBeanMethodIsNotStaticTaskFailsAndWritesAReport() throws Exception { + prepareTask("bpp/nonstatic", (architectureCheck) -> { + assertThatExceptionOfType(GradleException.class).isThrownBy(() -> architectureCheck.checkArchitecture()); + assertThat(failureReport(architectureCheck).length()).isGreaterThan(0); + }); + } + + @Test + void whenBeanPostProcessorBeanMethodIsStaticAndHasUnsafeParametersTaskFailsAndWritesAReport() throws Exception { + prepareTask("bpp/unsafeparameters", (architectureCheck) -> { + assertThatExceptionOfType(GradleException.class).isThrownBy(() -> architectureCheck.checkArchitecture()); + assertThat(failureReport(architectureCheck).length()).isGreaterThan(0); + }); + } + + @Test + void whenBeanPostProcessorBeanMethodIsStaticAndHasSafeParametersTaskSucceedsAndWritesAnEmptyReport() + throws Exception { + prepareTask("bpp/safeparameters", (architectureCheck) -> { + architectureCheck.checkArchitecture(); + assertThat(failureReport(architectureCheck).length()).isZero(); + }); + } + + @Test + void whenBeanPostProcessorBeanMethodIsStaticAndHasNoParametersTaskSucceedsAndWritesAnEmptyReport() + throws Exception { + prepareTask("bpp/noparameters", (architectureCheck) -> { + architectureCheck.checkArchitecture(); + assertThat(failureReport(architectureCheck).length()).isZero(); + }); + } + + @Test + void whenBeanFactoryPostProcessorBeanMethodIsNotStaticTaskFailsAndWritesAReport() throws Exception { + prepareTask("bfpp/nonstatic", (architectureCheck) -> { + assertThatExceptionOfType(GradleException.class).isThrownBy(() -> architectureCheck.checkArchitecture()); + assertThat(failureReport(architectureCheck).length()).isGreaterThan(0); + }); + } + + @Test + void whenBeanFactoryPostProcessorBeanMethodIsStaticAndHasParametersTaskFailsAndWritesAReport() throws Exception { + prepareTask("bfpp/parameters", (architectureCheck) -> { + assertThatExceptionOfType(GradleException.class).isThrownBy(() -> architectureCheck.checkArchitecture()); + assertThat(failureReport(architectureCheck).length()).isGreaterThan(0); + }); + } + + @Test + void whenBeanFactoryPostProcessorBeanMethodIsStaticAndHasNoParametersTaskSucceedsAndWritesAnEmptyReport() + throws Exception { + prepareTask("bfpp/noparameters", (architectureCheck) -> { + architectureCheck.checkArchitecture(); + assertThat(failureReport(architectureCheck).length()).isZero(); + }); + } + + private void prepareTask(String classes, Callback callback) throws Exception { + File projectDir = new File(this.temp, "project"); + projectDir.mkdirs(); + copyClasses(classes, projectDir); + Project project = ProjectBuilder.builder().withProjectDir(projectDir).build(); + ArchitectureCheck architectureCheck = project.getTasks() + .create("checkArchitecture", ArchitectureCheck.class, (task) -> task.setClasses(project.files("classes"))); + callback.accept(architectureCheck); + } + + private void copyClasses(String name, File projectDir) throws IOException { + PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); + Resource root = resolver.getResource("classpath:org/springframework/boot/build/architecture/" + name); + FileSystemUtils.copyRecursively(root.getFile(), + new File(projectDir, "classes/org/springframework/boot/build/architecture/" + name)); + + } + + private interface Callback { + + void accept(T item) throws Exception; + + } + +} diff --git a/buildSrc/src/test/java/org/springframework/boot/build/architecture/PackageTangleCheckTests.java b/buildSrc/src/test/java/org/springframework/boot/build/architecture/PackageTangleCheckTests.java deleted file mode 100644 index a0909e6f8a2c..000000000000 --- a/buildSrc/src/test/java/org/springframework/boot/build/architecture/PackageTangleCheckTests.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2012-2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.build.architecture; - -import java.io.File; -import java.io.IOException; - -import org.gradle.api.GradleException; -import org.gradle.api.Project; -import org.gradle.testfixtures.ProjectBuilder; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; - -import org.springframework.core.io.Resource; -import org.springframework.core.io.support.PathMatchingResourcePatternResolver; -import org.springframework.util.FileSystemUtils; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; - -/** - * Tests for {@link PackageTangleCheck}. - * - * @author Andy Wilkinson - */ -class PackageTangleCheckTests { - - @TempDir - File temp; - - @Test - void whenPackagesAreTangledTaskFailsAndWritesAReport() throws Exception { - prepareTask("tangled", (packageTangleCheck) -> { - assertThatExceptionOfType(GradleException.class) - .isThrownBy(() -> packageTangleCheck.checkForPackageTangles()); - assertThat( - new File(packageTangleCheck.getProject().getBuildDir(), "checkForPackageTangles/failure-report.txt") - .length()) - .isGreaterThan(0); - }); - } - - @Test - void whenPackagesAreNotTangledTaskSucceedsAndWritesAnEmptyReport() throws Exception { - prepareTask("untangled", (packageTangleCheck) -> { - packageTangleCheck.checkForPackageTangles(); - assertThat( - new File(packageTangleCheck.getProject().getBuildDir(), "checkForPackageTangles/failure-report.txt") - .length()) - .isEqualTo(0); - }); - } - - private void prepareTask(String classes, Callback callback) throws Exception { - File projectDir = new File(this.temp, "project"); - projectDir.mkdirs(); - copyClasses(classes, projectDir); - Project project = ProjectBuilder.builder().withProjectDir(projectDir).build(); - PackageTangleCheck packageTangleCheck = project.getTasks() - .create("checkForPackageTangles", PackageTangleCheck.class, - (task) -> task.setClasses(project.files("classes"))); - callback.accept(packageTangleCheck); - } - - private void copyClasses(String name, File projectDir) throws IOException { - PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); - Resource root = resolver.getResource("classpath:org/springframework/boot/build/architecture/" + name); - FileSystemUtils.copyRecursively(root.getFile(), - new File(projectDir, "classes/org/springframework/boot/build/architecture/" + name)); - - } - - private interface Callback { - - void accept(T item) throws Exception; - - } - -} diff --git a/buildSrc/src/test/java/org/springframework/boot/build/architecture/bfpp/nonstatic/NonStaticBeanFactoryPostProcessorConfiguration.java b/buildSrc/src/test/java/org/springframework/boot/build/architecture/bfpp/nonstatic/NonStaticBeanFactoryPostProcessorConfiguration.java new file mode 100644 index 000000000000..13bf730aaa07 --- /dev/null +++ b/buildSrc/src/test/java/org/springframework/boot/build/architecture/bfpp/nonstatic/NonStaticBeanFactoryPostProcessorConfiguration.java @@ -0,0 +1,30 @@ +/* + * Copyright 2012-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.build.architecture.bfpp.nonstatic; + +import org.springframework.beans.factory.config.BeanFactoryPostProcessor; +import org.springframework.context.annotation.Bean; + +class NonStaticBeanFactoryPostProcessorConfiguration { + + @Bean + BeanFactoryPostProcessor nonStaticBeanFactoryPostProcessor() { + return (beanFactory) -> { + }; + } + +} diff --git a/buildSrc/src/test/java/org/springframework/boot/build/architecture/bfpp/noparameters/NoParametersBeanFactoryPostProcessorConfiguration.java b/buildSrc/src/test/java/org/springframework/boot/build/architecture/bfpp/noparameters/NoParametersBeanFactoryPostProcessorConfiguration.java new file mode 100644 index 000000000000..659c9c7960db --- /dev/null +++ b/buildSrc/src/test/java/org/springframework/boot/build/architecture/bfpp/noparameters/NoParametersBeanFactoryPostProcessorConfiguration.java @@ -0,0 +1,40 @@ +/* + * Copyright 2012-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.build.architecture.bfpp.noparameters; + +import org.springframework.beans.factory.config.BeanFactoryPostProcessor; +import org.springframework.context.annotation.Bean; + +class NoParametersBeanFactoryPostProcessorConfiguration { + + @Bean + static BeanFactoryPostProcessor noParametersBeanFactoryPostProcessor() { + return (beanFactory) -> { + }; + } + + @Bean + Integer beanOne() { + return 1; + } + + @Bean + String beanTwo() { + return "test"; + } + +} diff --git a/buildSrc/src/test/java/org/springframework/boot/build/architecture/bfpp/parameters/ParametersBeanFactoryPostProcessorConfiguration.java b/buildSrc/src/test/java/org/springframework/boot/build/architecture/bfpp/parameters/ParametersBeanFactoryPostProcessorConfiguration.java new file mode 100644 index 000000000000..e090a654d1f7 --- /dev/null +++ b/buildSrc/src/test/java/org/springframework/boot/build/architecture/bfpp/parameters/ParametersBeanFactoryPostProcessorConfiguration.java @@ -0,0 +1,40 @@ +/* + * Copyright 2012-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.build.architecture.bfpp.parameters; + +import org.springframework.beans.factory.config.BeanFactoryPostProcessor; +import org.springframework.context.annotation.Bean; + +class ParametersBeanFactoryPostProcessorConfiguration { + + @Bean + static BeanFactoryPostProcessor parametersBeanFactoryPostProcessor(Integer param) { + return (beanFactory) -> { + }; + } + + @Bean + Integer beanOne() { + return 1; + } + + @Bean + String beanTwo() { + return "test"; + } + +} diff --git a/buildSrc/src/test/java/org/springframework/boot/build/architecture/bpp/nonstatic/NonStaticBeanPostProcessorConfiguration.java b/buildSrc/src/test/java/org/springframework/boot/build/architecture/bpp/nonstatic/NonStaticBeanPostProcessorConfiguration.java new file mode 100644 index 000000000000..fe2ab7c11645 --- /dev/null +++ b/buildSrc/src/test/java/org/springframework/boot/build/architecture/bpp/nonstatic/NonStaticBeanPostProcessorConfiguration.java @@ -0,0 +1,31 @@ +/* + * Copyright 2012-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.build.architecture.bpp.nonstatic; + +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.context.annotation.Bean; + +class NonStaticBeanPostProcessorConfiguration { + + @Bean + BeanPostProcessor nonStaticBeanPostProcessor() { + return new BeanPostProcessor() { + + }; + } + +} diff --git a/buildSrc/src/test/java/org/springframework/boot/build/architecture/bpp/noparameters/NoParametersBeanPostProcessorConfiguration.java b/buildSrc/src/test/java/org/springframework/boot/build/architecture/bpp/noparameters/NoParametersBeanPostProcessorConfiguration.java new file mode 100644 index 000000000000..39d30105ec25 --- /dev/null +++ b/buildSrc/src/test/java/org/springframework/boot/build/architecture/bpp/noparameters/NoParametersBeanPostProcessorConfiguration.java @@ -0,0 +1,41 @@ +/* + * Copyright 2012-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.build.architecture.bpp.noparameters; + +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.context.annotation.Bean; + +class NoParametersBeanPostProcessorConfiguration { + + @Bean + static BeanPostProcessor noParametersBeanPostProcessor() { + return new BeanPostProcessor() { + + }; + } + + @Bean + Integer beanOne() { + return 1; + } + + @Bean + String beanTwo() { + return "test"; + } + +} diff --git a/buildSrc/src/test/java/org/springframework/boot/build/architecture/bpp/safeparameters/SafeParametersBeanPostProcessorConfiguration.java b/buildSrc/src/test/java/org/springframework/boot/build/architecture/bpp/safeparameters/SafeParametersBeanPostProcessorConfiguration.java new file mode 100644 index 000000000000..ae793225fef9 --- /dev/null +++ b/buildSrc/src/test/java/org/springframework/boot/build/architecture/bpp/safeparameters/SafeParametersBeanPostProcessorConfiguration.java @@ -0,0 +1,46 @@ +/* + * Copyright 2012-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.build.architecture.bpp.safeparameters; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Lazy; +import org.springframework.core.env.Environment; + +class SafeParametersBeanPostProcessorConfiguration { + + @Bean + static BeanPostProcessor safeParametersBeanPostProcessor(ApplicationContext context, ObjectProvider beanOne, + ObjectProvider beanTwo, Environment environment, @Lazy String beanThree) { + return new BeanPostProcessor() { + + }; + } + + @Bean + Integer beanOne() { + return 1; + } + + @Bean + String beanTwo() { + return "test"; + } + +} diff --git a/buildSrc/src/test/java/org/springframework/boot/build/architecture/bpp/unsafeparameters/UnsafeParametersBeanPostProcessorConfiguration.java b/buildSrc/src/test/java/org/springframework/boot/build/architecture/bpp/unsafeparameters/UnsafeParametersBeanPostProcessorConfiguration.java new file mode 100644 index 000000000000..29d9be81c712 --- /dev/null +++ b/buildSrc/src/test/java/org/springframework/boot/build/architecture/bpp/unsafeparameters/UnsafeParametersBeanPostProcessorConfiguration.java @@ -0,0 +1,43 @@ +/* + * Copyright 2012-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.build.architecture.bpp.unsafeparameters; + +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; + +class UnsafeParametersBeanPostProcessorConfiguration { + + @Bean + static BeanPostProcessor unsafeParametersBeanPostProcessor(ApplicationContext context, Integer beanOne, + String beanTwo) { + return new BeanPostProcessor() { + + }; + } + + @Bean + Integer beanOne() { + return 1; + } + + @Bean + String beanTwo() { + return "test"; + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpointProxyTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpointProxyTests.java index f359af84e950..ef8515555887 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpointProxyTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpointProxyTests.java @@ -108,7 +108,7 @@ PlatformTransactionManager transactionManager(DataSource dataSource) { } @Bean - MethodValidationPostProcessor testPostProcessor() { + static MethodValidationPostProcessor testPostProcessor() { return new MethodValidationPostProcessor(); } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/BaseConfiguration.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/BaseConfiguration.java index c9784db2c105..ae3768e7a8a9 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/BaseConfiguration.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/BaseConfiguration.java @@ -70,7 +70,7 @@ WebEndpointDiscoverer webEndpointDiscoverer(EndpointMediaTypes endpointMediaType } @Bean - PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { + static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { return new PropertySourcesPlaceholderConfigurer(); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfigurationJedisTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfigurationJedisTests.java index 1703575e2bd4..04435b273eb0 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfigurationJedisTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfigurationJedisTests.java @@ -239,7 +239,7 @@ JedisClientConfigurationBuilderCustomizer customizer() { static class JedisConnectionFactoryCaptorConfiguration { @Bean - JedisConnectionFactoryCaptor jedisConnectionFactoryCaptor() { + static JedisConnectionFactoryCaptor jedisConnectionFactoryCaptor() { return new JedisConnectionFactoryCaptor(); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/validation/ValidationAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/validation/ValidationAutoConfigurationTests.java index 59d4d7583d62..ffc3278f6c05 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/validation/ValidationAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/validation/ValidationAutoConfigurationTests.java @@ -368,7 +368,7 @@ AnotherSampleService anotherSampleService() { static class SampleConfiguration { @Bean - MethodValidationPostProcessor testMethodValidationPostProcessor() { + static MethodValidationPostProcessor testMethodValidationPostProcessor() { return new MethodValidationPostProcessor(); } diff --git a/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/AbstractDevToolsDataSourceAutoConfigurationTests.java b/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/AbstractDevToolsDataSourceAutoConfigurationTests.java index 432298e17e2a..f2b531ba02ca 100644 --- a/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/AbstractDevToolsDataSourceAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/AbstractDevToolsDataSourceAutoConfigurationTests.java @@ -151,7 +151,7 @@ DataSource dataSourceTwo() { static class DataSourceSpyConfiguration { @Bean - DataSourceSpyBeanPostProcessor dataSourceSpyBeanPostProcessor() { + static DataSourceSpyBeanPostProcessor dataSourceSpyBeanPostProcessor() { return new DataSourceSpyBeanPostProcessor(); } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/PropertySourcesDeducerTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/PropertySourcesDeducerTests.java index 6cb182a36f76..25738886289d 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/PropertySourcesDeducerTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/PropertySourcesDeducerTests.java @@ -87,7 +87,7 @@ void getPropertySourcesWhenUnavailableThrowsException() { static class PropertySourcesPlaceholderConfigurerConfiguration { @Bean - PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { + static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer(); MutablePropertySources propertySources = new MutablePropertySources(); propertySources.addFirst(new TestPropertySource()); @@ -106,12 +106,12 @@ static class EmptyConfiguration { static class MultiplePropertySourcesPlaceholderConfigurerConfiguration { @Bean - PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer1() { + static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer1() { return new PropertySourcesPlaceholderConfigurer(); } @Bean - PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer2() { + static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer2() { return new PropertySourcesPlaceholderConfigurer(); } From c72b77c08e635cde7876e8557e641d786e4f5f61 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 26 Apr 2023 20:36:45 +0100 Subject: [PATCH 013/163] Polish --- .../boot/build/architecture/Rules.java | 62 ------------------- 1 file changed, 62 deletions(-) delete mode 100644 buildSrc/src/main/java/org/springframework/boot/build/architecture/Rules.java diff --git a/buildSrc/src/main/java/org/springframework/boot/build/architecture/Rules.java b/buildSrc/src/main/java/org/springframework/boot/build/architecture/Rules.java deleted file mode 100644 index d12c0a813bd2..000000000000 --- a/buildSrc/src/main/java/org/springframework/boot/build/architecture/Rules.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.build.architecture; - -import java.util.stream.Stream; - -import com.tngtech.archunit.base.DescribedPredicate; -import com.tngtech.archunit.core.domain.JavaClass.Predicates; -import com.tngtech.archunit.lang.ArchRule; -import com.tngtech.archunit.lang.syntax.ArchRuleDefinition; -import com.tngtech.archunit.library.dependencies.SlicesRuleDefinition; - -/** - * Architecture rules evaluated by {@link ArchitectureCheck}. - * - * @author Andy Wilkinson - */ -final class Rules { - - private Rules() { - - } - - static Stream stream() { - return Stream.of(allPackagesShouldBeFreeOfTangles(), - allBeanPostProcessorBeanMethodsShouldBeStaticAndHaveParametersThatWillNotCausePrematureInitialization()); - } - - static ArchRule allPackagesShouldBeFreeOfTangles() { - return SlicesRuleDefinition.slices().matching("(**)").should().beFreeOfCycles(); - } - - static ArchRule allBeanPostProcessorBeanMethodsShouldBeStaticAndHaveParametersThatWillNotCausePrematureInitialization() { - return ArchRuleDefinition.methods() - .that() - .areAnnotatedWith("org.springframework.context.annotation.Bean") - .and() - .haveRawReturnType(Predicates.assignableTo("org.springframework.beans.factory.config.BeanPostProcessor")) - .should() - .beStatic() - .andShould() - .haveRawParameterTypes(DescribedPredicate - .allElements(Predicates.assignableTo("org.springframework.beans.factory.ObjectProvider") - .or(Predicates.assignableTo("org.springframework.context.ApplicationContext")))) - .allowEmptyShould(true); - } - -} From 79673e61e9dcf1bc3653f566a8ad1da01f2cd08c Mon Sep 17 00:00:00 2001 From: Scott Frederick Date: Thu, 27 Apr 2023 17:03:56 -0500 Subject: [PATCH 014/163] Upgrade CI to Docker 23.0.5 Closes gh-35177 --- ci/images/get-docker-url.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/images/get-docker-url.sh b/ci/images/get-docker-url.sh index 547adf2f5013..677f8ed4a0d1 100755 --- a/ci/images/get-docker-url.sh +++ b/ci/images/get-docker-url.sh @@ -1,5 +1,5 @@ #!/bin/bash set -e -version="23.0.4" +version="23.0.5" echo "https://download.docker.com/linux/static/stable/x86_64/docker-$version.tgz"; From de2df9311c7e633e6946e163e2300fa3b73dba12 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Fri, 28 Apr 2023 18:05:06 +0100 Subject: [PATCH 015/163] Test Gradle plugin against Gradle 8.1.1 Closes gh-35195 --- .../boot/testsupport/gradle/testkit/GradleVersions.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-test-support/src/main/java/org/springframework/boot/testsupport/gradle/testkit/GradleVersions.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-test-support/src/main/java/org/springframework/boot/testsupport/gradle/testkit/GradleVersions.java index 0b84fbadc6e9..21a1ff6af390 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-test-support/src/main/java/org/springframework/boot/testsupport/gradle/testkit/GradleVersions.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-test-support/src/main/java/org/springframework/boot/testsupport/gradle/testkit/GradleVersions.java @@ -34,15 +34,15 @@ private GradleVersions() { public static List allCompatible() { if (isJava18()) { - return Arrays.asList("7.3.3", GradleVersion.current().getVersion(), "8.0.2", "8.1"); + return Arrays.asList("7.3.3", GradleVersion.current().getVersion(), "8.0.2", "8.1.1"); } if (isJava17()) { - return Arrays.asList("7.2", GradleVersion.current().getVersion(), "8.0.2", "8.1"); + return Arrays.asList("7.2", GradleVersion.current().getVersion(), "8.0.2", "8.1.1"); } if (isJava16()) { - return Arrays.asList("7.0.2", GradleVersion.current().getVersion(), "8.0.2", "8.1"); + return Arrays.asList("7.0.2", GradleVersion.current().getVersion(), "8.0.2", "8.1.1"); } - return Arrays.asList("6.8.3", "6.9.4", "7.0.2", GradleVersion.current().getVersion(), "8.0.2", "8.1"); + return Arrays.asList("6.8.3", "6.9.4", "7.0.2", GradleVersion.current().getVersion(), "8.0.2", "8.1.1"); } public static String minimumCompatible() { From e7578f0595b37ce59174b71d573cdfb83208be1a Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Mon, 1 May 2023 20:42:06 +0100 Subject: [PATCH 016/163] Add Docker Hub credentials to system tests task Closes gh-35213 --- ci/tasks/run-system-tests.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ci/tasks/run-system-tests.yml b/ci/tasks/run-system-tests.yml index 6dc0bef5c084..06d745d9cab8 100644 --- a/ci/tasks/run-system-tests.yml +++ b/ci/tasks/run-system-tests.yml @@ -20,6 +20,10 @@ run: args: - -ec - | + mkdir -p /root/.docker + cat > /root/.docker/config.json < Date: Mon, 1 May 2023 12:18:33 -0700 Subject: [PATCH 017/163] Search for main methods from the bottom of the stack Update `MainMethod` to search from the bottom of the stack rather than the start. Prior to this commit, an incorrect `main` method would be found if more than one `main` was in the stack. Fixes gh-35214 --- .../boot/devtools/restart/MainMethod.java | 6 ++++-- .../boot/devtools/restart/MainMethodTests.java | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/MainMethod.java b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/MainMethod.java index 5c1c4570fc2f..a2435453783c 100644 --- a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/MainMethod.java +++ b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/MainMethod.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,7 +40,9 @@ class MainMethod { } private Method getMainMethod(Thread thread) { - for (StackTraceElement element : thread.getStackTrace()) { + StackTraceElement[] stackTrace = thread.getStackTrace(); + for (int i = stackTrace.length - 1; i >= 0; i--) { + StackTraceElement element = stackTrace[i]; if ("main".equals(element.getMethodName())) { Method method = getMainMethod(element); if (method != null) { diff --git a/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/restart/MainMethodTests.java b/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/restart/MainMethodTests.java index 5fe407a427a0..3995241ab41a 100644 --- a/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/restart/MainMethodTests.java +++ b/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/restart/MainMethodTests.java @@ -56,6 +56,14 @@ void validMainMethod() throws Exception { assertThat(method.getDeclaringClassName()).isEqualTo(this.actualMain.getDeclaringClass().getName()); } + @Test // gh-35214 + void nestedMainMethod() throws Exception { + MainMethod method = new TestThread(Nested::main).test(); + Method nestedMain = Nested.class.getMethod("main", String[].class); + assertThat(method.getMethod()).isEqualTo(nestedMain); + assertThat(method.getDeclaringClassName()).isEqualTo(nestedMain.getDeclaringClass().getName()); + } + @Test void missingArgsMainMethod() { assertThatIllegalStateException().isThrownBy(() -> new TestThread(MissingArgs::main).test()) @@ -114,6 +122,15 @@ private static void someOtherMethod() { } + public static class Nested { + + public static void main(String... args) { + mainMethod.set(new MainMethod()); + Valid.main(args); + } + + } + public static class MissingArgs { public static void main() { From d0a354352d9641557ff906eaddbf41f188e66b6c Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 2 May 2023 08:40:58 +0100 Subject: [PATCH 018/163] Polish buildSrc's build.gradle --- buildSrc/build.gradle | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index 0fc303c70e6e..bca461aed16f 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -23,22 +23,25 @@ ext { dependencies { checkstyle "io.spring.javaformat:spring-javaformat-checkstyle:${javaFormatVersion}" + implementation(platform("org.springframework:spring-framework-bom:5.3.15")) implementation("com.fasterxml.jackson.core:jackson-databind:2.11.4") implementation("com.gradle:gradle-enterprise-gradle-plugin:3.12.1") implementation("com.tngtech.archunit:archunit:1.0.0") implementation("commons-codec:commons-codec:1.13") + implementation("io.spring.javaformat:spring-javaformat-gradle-plugin:${javaFormatVersion}") implementation("org.apache.maven:maven-embedder:3.6.2") implementation("org.asciidoctor:asciidoctor-gradle-jvm:3.3.2") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}") implementation("org.jetbrains.kotlin:kotlin-compiler-embeddable:${kotlinVersion}") + implementation("org.springframework:spring-context") implementation("org.springframework:spring-core") implementation("org.springframework:spring-web") - implementation("io.spring.javaformat:spring-javaformat-gradle-plugin:${javaFormatVersion}") + testImplementation("org.assertj:assertj-core:3.11.1") testImplementation("org.apache.logging.log4j:log4j-core:2.17.1") testImplementation("org.junit.jupiter:junit-jupiter:5.6.0") - implementation("org.springframework:spring-context") + testRuntimeOnly("org.junit.platform:junit-platform-launcher") } From 695e58f418b46bc9e28a8c6bd88a641d874921ec Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 2 May 2023 08:59:58 +0100 Subject: [PATCH 019/163] Align buildSrc's Framework version with the main build's version Closes gh-35224 --- buildSrc/build.gradle | 3 ++- gradle.properties | 1 + spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index bca461aed16f..a313abb61974 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -18,13 +18,14 @@ ext { def properties = new Properties() properties.load(it) set("kotlinVersion", properties["kotlinVersion"]) + set("springFrameworkVersion", properties["springFrameworkVersion"]) } } dependencies { checkstyle "io.spring.javaformat:spring-javaformat-checkstyle:${javaFormatVersion}" - implementation(platform("org.springframework:spring-framework-bom:5.3.15")) + implementation(platform("org.springframework:spring-framework-bom:${springFrameworkVersion}")) implementation("com.fasterxml.jackson.core:jackson-databind:2.11.4") implementation("com.gradle:gradle-enterprise-gradle-plugin:3.12.1") implementation("com.tngtech.archunit:archunit:1.0.0") diff --git a/gradle.properties b/gradle.properties index 8cf2e99d1688..284895299a2f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,6 +5,7 @@ org.gradle.parallel=true org.gradle.jvmargs=-Xmx2g -Dfile.encoding=UTF-8 kotlinVersion=1.6.21 +springFrameworkVersion=5.3.27 tomcatVersion=9.0.74 kotlin.stdlib.default.dependency=false diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index b3ff6d72a25b..1a4f357f51aa 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1750,7 +1750,7 @@ bom { ] } } - library("Spring Framework", "5.3.27") { + library("Spring Framework", "${springFrameworkVersion}") { prohibit { versionRange "[6.0.0-M1,)" because "we upgrade in Spring Boot 3.x" From 3b702867470455f305f7eff0d0212c88fea0c18a Mon Sep 17 00:00:00 2001 From: Juhan Aasaru Date: Thu, 27 Apr 2023 10:55:33 +0300 Subject: [PATCH 020/163] Correct list of annotations equivalent to @SpringBootApplication See gh-35180 --- .../boot/autoconfigure/SpringBootApplication.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/SpringBootApplication.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/SpringBootApplication.java index 83e16137708a..934489651b90 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/SpringBootApplication.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/SpringBootApplication.java @@ -40,7 +40,7 @@ * Indicates a {@link Configuration configuration} class that declares one or more * {@link Bean @Bean} methods and also triggers {@link EnableAutoConfiguration * auto-configuration} and {@link ComponentScan component scanning}. This is a convenience - * annotation that is equivalent to declaring {@code @Configuration}, + * annotation that is equivalent to declaring {@code @SpringBootConfiguration}, * {@code @EnableAutoConfiguration} and {@code @ComponentScan}. * * @author Phillip Webb From 9f109fe785a76d40edcf2809933349c84c4c9378 Mon Sep 17 00:00:00 2001 From: Moritz Halbritter Date: Tue, 2 May 2023 11:40:16 +0200 Subject: [PATCH 021/163] Disable Couchbase integration tests on aarch64 linux and mac See gh-35228 --- .../couchbase/CouchbaseAutoConfigurationIntegrationTests.java | 4 ++++ .../data/couchbase/DataCouchbaseTestIntegrationTests.java | 4 ++++ .../couchbase/DataCouchbaseTestReactiveIntegrationTests.java | 4 ++++ .../DataCouchbaseTestWithIncludeFilterIntegrationTests.java | 4 ++++ 4 files changed, 16 insertions(+) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseAutoConfigurationIntegrationTests.java index 82ef9350db84..08fedda54e6b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseAutoConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseAutoConfigurationIntegrationTests.java @@ -27,6 +27,7 @@ import com.couchbase.client.java.json.JsonObject; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.OS; import org.testcontainers.couchbase.BucketDefinition; import org.testcontainers.couchbase.CouchbaseContainer; import org.testcontainers.junit.jupiter.Container; @@ -34,6 +35,7 @@ import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.testsupport.junit.DisabledOnOs; import org.springframework.boot.testsupport.testcontainers.DockerImageNames; import static org.assertj.core.api.Assertions.assertThat; @@ -44,6 +46,8 @@ * @author Stephane Nicoll * @author Brian Clozel */ +@DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64", + disabledReason = "The Couchbase image has no ARM support") @Testcontainers(disabledWithoutDocker = true) class CouchbaseAutoConfigurationIntegrationTests { diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/couchbase/DataCouchbaseTestIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/couchbase/DataCouchbaseTestIntegrationTests.java index 1261a74edc4f..e3e5ea1d84b1 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/couchbase/DataCouchbaseTestIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/couchbase/DataCouchbaseTestIntegrationTests.java @@ -19,6 +19,7 @@ import java.time.Duration; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.OS; import org.testcontainers.couchbase.BucketDefinition; import org.testcontainers.couchbase.CouchbaseContainer; import org.testcontainers.junit.jupiter.Container; @@ -26,6 +27,7 @@ import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.testsupport.junit.DisabledOnOs; import org.springframework.boot.testsupport.testcontainers.DockerImageNames; import org.springframework.context.ApplicationContext; import org.springframework.data.couchbase.core.CouchbaseTemplate; @@ -42,6 +44,8 @@ */ @DataCouchbaseTest @Testcontainers(disabledWithoutDocker = true) +@DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64", + disabledReason = "The Couchbase image has no ARM support") class DataCouchbaseTestIntegrationTests { private static final String BUCKET_NAME = "cbbucket"; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/couchbase/DataCouchbaseTestReactiveIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/couchbase/DataCouchbaseTestReactiveIntegrationTests.java index 27be882a85b5..d2d132c1b5ca 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/couchbase/DataCouchbaseTestReactiveIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/couchbase/DataCouchbaseTestReactiveIntegrationTests.java @@ -19,12 +19,14 @@ import java.time.Duration; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.OS; import org.testcontainers.couchbase.BucketDefinition; import org.testcontainers.couchbase.CouchbaseContainer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.testsupport.junit.DisabledOnOs; import org.springframework.boot.testsupport.testcontainers.DockerImageNames; import org.springframework.data.couchbase.core.ReactiveCouchbaseTemplate; import org.springframework.test.context.DynamicPropertyRegistry; @@ -40,6 +42,8 @@ */ @DataCouchbaseTest @Testcontainers(disabledWithoutDocker = true) +@DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64", + disabledReason = "The Couchbase image has no ARM support") class DataCouchbaseTestReactiveIntegrationTests { private static final String BUCKET_NAME = "cbbucket"; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/couchbase/DataCouchbaseTestWithIncludeFilterIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/couchbase/DataCouchbaseTestWithIncludeFilterIntegrationTests.java index 1e779b709bc1..6081b9cbe9bf 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/couchbase/DataCouchbaseTestWithIncludeFilterIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/couchbase/DataCouchbaseTestWithIncludeFilterIntegrationTests.java @@ -19,12 +19,14 @@ import java.time.Duration; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.OS; import org.testcontainers.couchbase.BucketDefinition; import org.testcontainers.couchbase.CouchbaseContainer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.testsupport.junit.DisabledOnOs; import org.springframework.boot.testsupport.testcontainers.DockerImageNames; import org.springframework.context.annotation.ComponentScan.Filter; import org.springframework.stereotype.Service; @@ -41,6 +43,8 @@ */ @DataCouchbaseTest(includeFilters = @Filter(Service.class)) @Testcontainers(disabledWithoutDocker = true) +@DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64", + disabledReason = "The Couchbase image has no ARM support") class DataCouchbaseTestWithIncludeFilterIntegrationTests { private static final String BUCKET_NAME = "cbbucket"; From d7a9f87b64803d9b7f9f5099934480da68c1d429 Mon Sep 17 00:00:00 2001 From: Moritz Halbritter Date: Tue, 2 May 2023 11:54:13 +0200 Subject: [PATCH 022/163] Disable Neo4j tests on aarch64 linux and mac See gh-35228 --- .../neo4j/Neo4jReactiveHealthIndicatorIntegrationTests.java | 4 ++++ .../Neo4jRepositoriesAutoConfigurationIntegrationTests.java | 4 ++++ .../neo4j/Neo4jAutoConfigurationIntegrationTests.java | 4 ++++ .../data/neo4j/DataNeo4jTestIntegrationTests.java | 4 ++++ .../data/neo4j/DataNeo4jTestPropertiesIntegrationTests.java | 4 ++++ .../data/neo4j/DataNeo4jTestReactiveIntegrationTests.java | 4 ++++ .../neo4j/DataNeo4jTestWithIncludeFilterIntegrationTests.java | 4 ++++ 7 files changed, 28 insertions(+) diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/neo4j/Neo4jReactiveHealthIndicatorIntegrationTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/neo4j/Neo4jReactiveHealthIndicatorIntegrationTests.java index e1f78865c688..1620441cf535 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/neo4j/Neo4jReactiveHealthIndicatorIntegrationTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/neo4j/Neo4jReactiveHealthIndicatorIntegrationTests.java @@ -19,6 +19,7 @@ import java.time.Duration; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.OS; import org.testcontainers.containers.Neo4jContainer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; @@ -29,6 +30,7 @@ import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.testsupport.junit.DisabledOnOs; import org.springframework.boot.testsupport.testcontainers.DockerImageNames; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -44,6 +46,8 @@ */ @SpringBootTest @Testcontainers(disabledWithoutDocker = true) +@DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64", + disabledReason = "The Neo4j image has no ARM support") public class Neo4jReactiveHealthIndicatorIntegrationTests { // gh-33428 diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesAutoConfigurationIntegrationTests.java index b32f0dddccb5..70ada3a203c5 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesAutoConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jRepositoriesAutoConfigurationIntegrationTests.java @@ -19,6 +19,7 @@ import java.time.Duration; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.OS; import org.testcontainers.containers.Neo4jContainer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; @@ -28,6 +29,7 @@ import org.springframework.boot.autoconfigure.data.neo4j.country.CountryRepository; import org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.testsupport.junit.DisabledOnOs; import org.springframework.boot.testsupport.testcontainers.DockerImageNames; import org.springframework.context.annotation.Configuration; import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories; @@ -43,6 +45,8 @@ */ @SpringBootTest @Testcontainers(disabledWithoutDocker = true) +@DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64", + disabledReason = "The Neo4j image has no ARM support") class Neo4jRepositoriesAutoConfigurationIntegrationTests { @Container diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/neo4j/Neo4jAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/neo4j/Neo4jAutoConfigurationIntegrationTests.java index c8febbbe6056..bb03bea7bfdb 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/neo4j/Neo4jAutoConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/neo4j/Neo4jAutoConfigurationIntegrationTests.java @@ -19,6 +19,7 @@ import java.time.Duration; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.OS; import org.neo4j.driver.Driver; import org.neo4j.driver.Result; import org.neo4j.driver.Session; @@ -30,6 +31,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.testsupport.junit.DisabledOnOs; import org.springframework.boot.testsupport.testcontainers.DockerImageNames; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.DynamicPropertyRegistry; @@ -45,6 +47,8 @@ */ @SpringBootTest @Testcontainers(disabledWithoutDocker = true) +@DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64", + disabledReason = "The Neo4j image has no ARM support") class Neo4jAutoConfigurationIntegrationTests { @Container diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestIntegrationTests.java index b0e882603a42..bcc170381fd9 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestIntegrationTests.java @@ -19,12 +19,14 @@ import java.time.Duration; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.OS; import org.testcontainers.containers.Neo4jContainer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.testsupport.junit.DisabledOnOs; import org.springframework.boot.testsupport.testcontainers.DockerImageNames; import org.springframework.context.ApplicationContext; import org.springframework.data.neo4j.core.Neo4jTemplate; @@ -43,6 +45,8 @@ */ @DataNeo4jTest @Testcontainers(disabledWithoutDocker = true) +@DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64", + disabledReason = "The Neo4j image has no ARM support") class DataNeo4jTestIntegrationTests { @Container diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestPropertiesIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestPropertiesIntegrationTests.java index 272402cf5e26..7ddabaae3b5a 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestPropertiesIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestPropertiesIntegrationTests.java @@ -20,11 +20,13 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.OS; import org.testcontainers.containers.Neo4jContainer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.testsupport.junit.DisabledOnOs; import org.springframework.boot.testsupport.testcontainers.DockerImageNames; import org.springframework.core.env.Environment; import org.springframework.test.context.DynamicPropertyRegistry; @@ -40,6 +42,8 @@ */ @Testcontainers(disabledWithoutDocker = true) @DataNeo4jTest(properties = "spring.profiles.active=test") +@DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64", + disabledReason = "The Neo4j image has no ARM support") class DataNeo4jTestPropertiesIntegrationTests { @Container diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestReactiveIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestReactiveIntegrationTests.java index 64ba554c95ac..5ac5106ae16c 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestReactiveIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestReactiveIntegrationTests.java @@ -19,6 +19,7 @@ import java.time.Duration; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.OS; import org.neo4j.driver.Driver; import org.testcontainers.containers.Neo4jContainer; import org.testcontainers.junit.jupiter.Container; @@ -29,6 +30,7 @@ import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.boot.testsupport.junit.DisabledOnOs; import org.springframework.boot.testsupport.testcontainers.DockerImageNames; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; @@ -52,6 +54,8 @@ @DataNeo4jTest @Transactional(propagation = Propagation.NOT_SUPPORTED) @Testcontainers(disabledWithoutDocker = true) +@DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64", + disabledReason = "The Neo4j image has no ARM support") class DataNeo4jTestReactiveIntegrationTests { @Container diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestWithIncludeFilterIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestWithIncludeFilterIntegrationTests.java index 85b46d43ae1a..003212a8cb1f 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestWithIncludeFilterIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/neo4j/DataNeo4jTestWithIncludeFilterIntegrationTests.java @@ -19,11 +19,13 @@ import java.time.Duration; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.OS; import org.testcontainers.containers.Neo4jContainer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.testsupport.junit.DisabledOnOs; import org.springframework.boot.testsupport.testcontainers.DockerImageNames; import org.springframework.context.annotation.ComponentScan.Filter; import org.springframework.stereotype.Service; @@ -40,6 +42,8 @@ */ @Testcontainers(disabledWithoutDocker = true) @DataNeo4jTest(includeFilters = @Filter(Service.class)) +@DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64", + disabledReason = "The Neo4j image has no ARM support") class DataNeo4jTestWithIncludeFilterIntegrationTests { @Container From c1cef099d25c5ff62e24e60801ae10a65cb27ca7 Mon Sep 17 00:00:00 2001 From: Moritz Halbritter Date: Tue, 2 May 2023 13:31:47 +0200 Subject: [PATCH 023/163] Limit maximum heap of ElasticSearch in tests --- .../ElasticsearchRepositoriesAutoConfigurationTests.java | 1 + .../ReactiveElasticsearchRepositoriesAutoConfigurationTests.java | 1 + ...ElasticsearchRestClientAutoConfigurationIntegrationTests.java | 1 + ...ElasticsearchRestClientAutoConfigurationIntegrationTests.java | 1 + .../elasticsearch/DataElasticsearchTestIntegrationTests.java | 1 + .../DataElasticsearchTestPropertiesIntegrationTests.java | 1 + .../DataElasticsearchTestReactiveIntegrationTests.java | 1 + .../DataElasticsearchTestWithIncludeFilterIntegrationTests.java | 1 + 8 files changed, 8 insertions(+) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchRepositoriesAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchRepositoriesAutoConfigurationTests.java index ba6922202c36..a000f71b5818 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchRepositoriesAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchRepositoriesAutoConfigurationTests.java @@ -50,6 +50,7 @@ class ElasticsearchRepositoriesAutoConfigurationTests { @Container static final ElasticsearchContainer elasticsearch = new ElasticsearchContainer(DockerImageNames.elasticsearch()) + .withEnv("ES_JAVA_OPTS", "-Xmx1g") .withStartupAttempts(5) .withStartupTimeout(Duration.ofMinutes(10)); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ReactiveElasticsearchRepositoriesAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ReactiveElasticsearchRepositoriesAutoConfigurationTests.java index d85166aeb14e..badda2975bce 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ReactiveElasticsearchRepositoriesAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ReactiveElasticsearchRepositoriesAutoConfigurationTests.java @@ -49,6 +49,7 @@ class ReactiveElasticsearchRepositoriesAutoConfigurationTests { @Container static ElasticsearchContainer elasticsearch = new ElasticsearchContainer(DockerImageNames.elasticsearch()) + .withEnv("ES_JAVA_OPTS", "-Xmx1g") .withStartupAttempts(5) .withStartupTimeout(Duration.ofMinutes(10)); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ReactiveElasticsearchRestClientAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ReactiveElasticsearchRestClientAutoConfigurationIntegrationTests.java index c78e1eb48786..005aa7786a82 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ReactiveElasticsearchRestClientAutoConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ReactiveElasticsearchRestClientAutoConfigurationIntegrationTests.java @@ -45,6 +45,7 @@ class ReactiveElasticsearchRestClientAutoConfigurationIntegrationTests { @Container static ElasticsearchContainer elasticsearch = new ElasticsearchContainer(DockerImageNames.elasticsearch()) + .withEnv("ES_JAVA_OPTS", "-Xmx1g") .withStartupAttempts(5) .withStartupTimeout(Duration.ofMinutes(10)); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfigurationIntegrationTests.java index 4c1c29488fa8..591c9e6003fc 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfigurationIntegrationTests.java @@ -53,6 +53,7 @@ class ElasticsearchRestClientAutoConfigurationIntegrationTests { @Container static final ElasticsearchContainer elasticsearch = new ElasticsearchContainer(DockerImageNames.elasticsearch()) + .withEnv("ES_JAVA_OPTS", "-Xmx1g") .withStartupAttempts(5) .withStartupTimeout(Duration.ofMinutes(10)); diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/elasticsearch/DataElasticsearchTestIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/elasticsearch/DataElasticsearchTestIntegrationTests.java index e57852a4e0e1..71cf9e3f34fe 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/elasticsearch/DataElasticsearchTestIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/elasticsearch/DataElasticsearchTestIntegrationTests.java @@ -46,6 +46,7 @@ class DataElasticsearchTestIntegrationTests { @Container static final ElasticsearchContainer elasticsearch = new ElasticsearchContainer(DockerImageNames.elasticsearch()) + .withEnv("ES_JAVA_OPTS", "-Xmx1g") .withStartupAttempts(5) .withStartupTimeout(Duration.ofMinutes(10)); diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/elasticsearch/DataElasticsearchTestPropertiesIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/elasticsearch/DataElasticsearchTestPropertiesIntegrationTests.java index 41cd78114180..1dee6855cf0d 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/elasticsearch/DataElasticsearchTestPropertiesIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/elasticsearch/DataElasticsearchTestPropertiesIntegrationTests.java @@ -44,6 +44,7 @@ class DataElasticsearchTestPropertiesIntegrationTests { @Container static final ElasticsearchContainer elasticsearch = new ElasticsearchContainer(DockerImageNames.elasticsearch()) + .withEnv("ES_JAVA_OPTS", "-Xmx1g") .withStartupAttempts(5) .withStartupTimeout(Duration.ofMinutes(10)); diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/elasticsearch/DataElasticsearchTestReactiveIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/elasticsearch/DataElasticsearchTestReactiveIntegrationTests.java index 99e6b7fb69c1..c5bfb1ad61af 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/elasticsearch/DataElasticsearchTestReactiveIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/elasticsearch/DataElasticsearchTestReactiveIntegrationTests.java @@ -43,6 +43,7 @@ class DataElasticsearchTestReactiveIntegrationTests { @Container static final ElasticsearchContainer elasticsearch = new ElasticsearchContainer(DockerImageNames.elasticsearch()) + .withEnv("ES_JAVA_OPTS", "-Xmx1g") .withStartupAttempts(5) .withStartupTimeout(Duration.ofMinutes(10)); diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/elasticsearch/DataElasticsearchTestWithIncludeFilterIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/elasticsearch/DataElasticsearchTestWithIncludeFilterIntegrationTests.java index 18ebfef08852..7af03720a3e9 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/elasticsearch/DataElasticsearchTestWithIncludeFilterIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/elasticsearch/DataElasticsearchTestWithIncludeFilterIntegrationTests.java @@ -45,6 +45,7 @@ class DataElasticsearchTestWithIncludeFilterIntegrationTests { @Container static final ElasticsearchContainer elasticsearch = new ElasticsearchContainer(DockerImageNames.elasticsearch()) + .withEnv("ES_JAVA_OPTS", "-Xmx1g") .withStartupAttempts(5) .withStartupTimeout(Duration.ofMinutes(10)); From 312f0c17ede1ca943aff42c705e7f2885ac53afa Mon Sep 17 00:00:00 2001 From: Moritz Halbritter Date: Tue, 2 May 2023 14:37:13 +0200 Subject: [PATCH 024/163] Set initial ElasticSearch heap size in integration tests --- .../ElasticsearchRepositoriesAutoConfigurationTests.java | 2 +- ...ReactiveElasticsearchRepositoriesAutoConfigurationTests.java | 2 +- ...lasticsearchRestClientAutoConfigurationIntegrationTests.java | 2 +- ...lasticsearchRestClientAutoConfigurationIntegrationTests.java | 2 +- .../elasticsearch/DataElasticsearchTestIntegrationTests.java | 2 +- .../DataElasticsearchTestPropertiesIntegrationTests.java | 2 +- .../DataElasticsearchTestReactiveIntegrationTests.java | 2 +- .../DataElasticsearchTestWithIncludeFilterIntegrationTests.java | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchRepositoriesAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchRepositoriesAutoConfigurationTests.java index a000f71b5818..20da516ec7a8 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchRepositoriesAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchRepositoriesAutoConfigurationTests.java @@ -50,7 +50,7 @@ class ElasticsearchRepositoriesAutoConfigurationTests { @Container static final ElasticsearchContainer elasticsearch = new ElasticsearchContainer(DockerImageNames.elasticsearch()) - .withEnv("ES_JAVA_OPTS", "-Xmx1g") + .withEnv("ES_JAVA_OPTS", "-Xms32m -Xmx512m") .withStartupAttempts(5) .withStartupTimeout(Duration.ofMinutes(10)); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ReactiveElasticsearchRepositoriesAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ReactiveElasticsearchRepositoriesAutoConfigurationTests.java index badda2975bce..4bff531dffed 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ReactiveElasticsearchRepositoriesAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ReactiveElasticsearchRepositoriesAutoConfigurationTests.java @@ -49,7 +49,7 @@ class ReactiveElasticsearchRepositoriesAutoConfigurationTests { @Container static ElasticsearchContainer elasticsearch = new ElasticsearchContainer(DockerImageNames.elasticsearch()) - .withEnv("ES_JAVA_OPTS", "-Xmx1g") + .withEnv("ES_JAVA_OPTS", "-Xms32m -Xmx512m") .withStartupAttempts(5) .withStartupTimeout(Duration.ofMinutes(10)); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ReactiveElasticsearchRestClientAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ReactiveElasticsearchRestClientAutoConfigurationIntegrationTests.java index 005aa7786a82..ed9b8b3a71bd 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ReactiveElasticsearchRestClientAutoConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/elasticsearch/ReactiveElasticsearchRestClientAutoConfigurationIntegrationTests.java @@ -45,7 +45,7 @@ class ReactiveElasticsearchRestClientAutoConfigurationIntegrationTests { @Container static ElasticsearchContainer elasticsearch = new ElasticsearchContainer(DockerImageNames.elasticsearch()) - .withEnv("ES_JAVA_OPTS", "-Xmx1g") + .withEnv("ES_JAVA_OPTS", "-Xms32m -Xmx512m") .withStartupAttempts(5) .withStartupTimeout(Duration.ofMinutes(10)); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfigurationIntegrationTests.java index 591c9e6003fc..e133b8d9a980 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/ElasticsearchRestClientAutoConfigurationIntegrationTests.java @@ -53,7 +53,7 @@ class ElasticsearchRestClientAutoConfigurationIntegrationTests { @Container static final ElasticsearchContainer elasticsearch = new ElasticsearchContainer(DockerImageNames.elasticsearch()) - .withEnv("ES_JAVA_OPTS", "-Xmx1g") + .withEnv("ES_JAVA_OPTS", "-Xms32m -Xmx512m") .withStartupAttempts(5) .withStartupTimeout(Duration.ofMinutes(10)); diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/elasticsearch/DataElasticsearchTestIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/elasticsearch/DataElasticsearchTestIntegrationTests.java index 71cf9e3f34fe..70b486b7ff6a 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/elasticsearch/DataElasticsearchTestIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/elasticsearch/DataElasticsearchTestIntegrationTests.java @@ -46,7 +46,7 @@ class DataElasticsearchTestIntegrationTests { @Container static final ElasticsearchContainer elasticsearch = new ElasticsearchContainer(DockerImageNames.elasticsearch()) - .withEnv("ES_JAVA_OPTS", "-Xmx1g") + .withEnv("ES_JAVA_OPTS", "-Xms32m -Xmx512m") .withStartupAttempts(5) .withStartupTimeout(Duration.ofMinutes(10)); diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/elasticsearch/DataElasticsearchTestPropertiesIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/elasticsearch/DataElasticsearchTestPropertiesIntegrationTests.java index 1dee6855cf0d..0020e88b0d44 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/elasticsearch/DataElasticsearchTestPropertiesIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/elasticsearch/DataElasticsearchTestPropertiesIntegrationTests.java @@ -44,7 +44,7 @@ class DataElasticsearchTestPropertiesIntegrationTests { @Container static final ElasticsearchContainer elasticsearch = new ElasticsearchContainer(DockerImageNames.elasticsearch()) - .withEnv("ES_JAVA_OPTS", "-Xmx1g") + .withEnv("ES_JAVA_OPTS", "-Xms32m -Xmx512m") .withStartupAttempts(5) .withStartupTimeout(Duration.ofMinutes(10)); diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/elasticsearch/DataElasticsearchTestReactiveIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/elasticsearch/DataElasticsearchTestReactiveIntegrationTests.java index c5bfb1ad61af..98b061a05f7f 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/elasticsearch/DataElasticsearchTestReactiveIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/elasticsearch/DataElasticsearchTestReactiveIntegrationTests.java @@ -43,7 +43,7 @@ class DataElasticsearchTestReactiveIntegrationTests { @Container static final ElasticsearchContainer elasticsearch = new ElasticsearchContainer(DockerImageNames.elasticsearch()) - .withEnv("ES_JAVA_OPTS", "-Xmx1g") + .withEnv("ES_JAVA_OPTS", "-Xms32m -Xmx512m") .withStartupAttempts(5) .withStartupTimeout(Duration.ofMinutes(10)); diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/elasticsearch/DataElasticsearchTestWithIncludeFilterIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/elasticsearch/DataElasticsearchTestWithIncludeFilterIntegrationTests.java index 7af03720a3e9..08636af63852 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/elasticsearch/DataElasticsearchTestWithIncludeFilterIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/elasticsearch/DataElasticsearchTestWithIncludeFilterIntegrationTests.java @@ -45,7 +45,7 @@ class DataElasticsearchTestWithIncludeFilterIntegrationTests { @Container static final ElasticsearchContainer elasticsearch = new ElasticsearchContainer(DockerImageNames.elasticsearch()) - .withEnv("ES_JAVA_OPTS", "-Xmx1g") + .withEnv("ES_JAVA_OPTS", "-Xms32m -Xmx512m") .withStartupAttempts(5) .withStartupTimeout(Duration.ofMinutes(10)); From 091d6204cbd41971698e02315d6fde0852d41730 Mon Sep 17 00:00:00 2001 From: Moritz Halbritter Date: Tue, 2 May 2023 15:38:42 +0200 Subject: [PATCH 025/163] Disable build image integration tests on aarch64 linux and mac See gh-35229 --- .../gradle/tasks/bundling/BootBuildImageIntegrationTests.java | 2 ++ .../java/org/springframework/boot/maven/BuildImageTests.java | 3 +++ 2 files changed, 5 insertions(+) diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootBuildImageIntegrationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootBuildImageIntegrationTests.java index 7fbcdee652ce..4fc75060ff8c 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootBuildImageIntegrationTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootBuildImageIntegrationTests.java @@ -60,6 +60,8 @@ */ @GradleCompatibility(configurationCache = true) @DisabledIfDockerUnavailable +@org.springframework.boot.testsupport.junit.DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64", + disabledReason = "The builder image has no ARM support") class BootBuildImageIntegrationTests { GradleBuild gradleBuild; diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/BuildImageTests.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/BuildImageTests.java index 343e84114ca6..d78d6a494002 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/BuildImageTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/BuildImageTests.java @@ -25,6 +25,7 @@ import java.util.stream.IntStream; import org.junit.jupiter.api.TestTemplate; +import org.junit.jupiter.api.condition.OS; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.boot.buildpack.platform.docker.DockerApi; @@ -45,6 +46,8 @@ */ @ExtendWith(MavenBuildExtension.class) @DisabledIfDockerUnavailable +@org.springframework.boot.testsupport.junit.DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64", + disabledReason = "The builder image has no ARM support") class BuildImageTests extends AbstractArchiveIntegrationTests { @TestTemplate From 7c2c2ebb1bb632e708399712d6f5e069e11998a4 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 2 May 2023 15:44:38 +0100 Subject: [PATCH 026/163] Make ApplicationAvailabilityBean receive events with lazy init Fixes gh-35161 --- .../ApplicationAvailabilityAutoConfiguration.java | 4 ++-- ...pplicationAvailabilityAutoConfigurationTests.java | 12 ++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/availability/ApplicationAvailabilityAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/availability/ApplicationAvailabilityAutoConfiguration.java index 769c5a3cc8a9..e9e19df7f00c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/availability/ApplicationAvailabilityAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/availability/ApplicationAvailabilityAutoConfiguration.java @@ -34,8 +34,8 @@ public class ApplicationAvailabilityAutoConfiguration { @Bean - @ConditionalOnMissingBean - public ApplicationAvailability applicationAvailability() { + @ConditionalOnMissingBean(ApplicationAvailability.class) + public ApplicationAvailabilityBean applicationAvailability() { return new ApplicationAvailabilityBean(); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/availability/ApplicationAvailabilityAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/availability/ApplicationAvailabilityAutoConfigurationTests.java index 225ce98f5eb4..c18b0bd01d55 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/availability/ApplicationAvailabilityAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/availability/ApplicationAvailabilityAutoConfigurationTests.java @@ -18,8 +18,11 @@ import org.junit.jupiter.api.Test; +import org.springframework.boot.LazyInitializationBeanFactoryPostProcessor; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.availability.ApplicationAvailability; +import org.springframework.boot.availability.AvailabilityChangeEvent; +import org.springframework.boot.availability.ReadinessState; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import static org.assertj.core.api.Assertions.assertThat; @@ -51,4 +54,13 @@ void providerIsNotConfiguredWhenCustomOneIsPresent() { .hasBean("customApplicationAvailability"))); } + @Test + void whenLazyInitializationIsEnabledApplicationAvailabilityBeanShouldStillReceiveAvailabilityChangeEvents() { + this.contextRunner.withBean(LazyInitializationBeanFactoryPostProcessor.class).run((context) -> { + AvailabilityChangeEvent.publish(context, ReadinessState.ACCEPTING_TRAFFIC); + ApplicationAvailability applicationAvailability = context.getBean(ApplicationAvailability.class); + assertThat(applicationAvailability.getLastChangeEvent(ReadinessState.class)).isNotNull(); + }); + } + } From 5ef0ee0ed4a607b983f213d841be3aa211767391 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Tue, 2 May 2023 13:19:41 -0700 Subject: [PATCH 027/163] Prevent early initialization of SessionRepository beans Replace `SessionRepositoryFilterConfiguration` filter registration bean with a `DelegatingFilterProxyRegistrationBean` so that `SessionRepository` beans are not initialized early. Fixes gh-35240 --- .../SessionRepositoryFilterConfiguration.java | 13 ++-- ...onEarlyInitializationIntegrationTests.java | 66 +++++++++++++++++++ .../SessionAutoConfigurationJdbcTests.java | 4 +- .../SessionAutoConfigurationTests.java | 21 ++++-- .../FilterOrderingIntegrationTests.java | 29 ++++---- 5 files changed, 106 insertions(+), 27 deletions(-) create mode 100644 spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationEarlyInitializationIntegrationTests.java diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/SessionRepositoryFilterConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/SessionRepositoryFilterConfiguration.java index 3338603aeb11..6b8785d07441 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/SessionRepositoryFilterConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/SessionRepositoryFilterConfiguration.java @@ -21,12 +21,14 @@ import javax.servlet.DispatcherType; +import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.boot.web.servlet.DelegatingFilterProxyRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.session.web.http.SessionRepositoryFilter; +import org.springframework.util.Assert; /** * Configuration for customizing the registration of the {@link SessionRepositoryFilter}. @@ -39,9 +41,12 @@ class SessionRepositoryFilterConfiguration { @Bean - FilterRegistrationBean> sessionRepositoryFilterRegistration( - SessionProperties sessionProperties, SessionRepositoryFilter filter) { - FilterRegistrationBean> registration = new FilterRegistrationBean<>(filter); + DelegatingFilterProxyRegistrationBean sessionRepositoryFilterRegistration(SessionProperties sessionProperties, + ListableBeanFactory beanFactory) { + String[] targetBeanNames = beanFactory.getBeanNamesForType(SessionRepositoryFilter.class, false, false); + Assert.state(targetBeanNames.length == 1, "Expected single SessionRepositoryFilter bean"); + DelegatingFilterProxyRegistrationBean registration = new DelegatingFilterProxyRegistrationBean( + targetBeanNames[0]); registration.setDispatcherTypes(getDispatcherTypes(sessionProperties)); registration.setOrder(sessionProperties.getServlet().getFilterOrder()); return registration; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationEarlyInitializationIntegrationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationEarlyInitializationIntegrationTests.java new file mode 100644 index 000000000000..6d449f83a4dd --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationEarlyInitializationIntegrationTests.java @@ -0,0 +1,66 @@ +/* + * Copyright 2012-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.session; + +import java.util.LinkedHashMap; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.ImportAutoConfiguration; +import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.session.MapSessionRepository; +import org.springframework.session.config.annotation.web.http.EnableSpringHttpSession; +import org.springframework.util.Assert; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests to ensure {@link SessionAutoConfiguration} and + * {@link SessionRepositoryFilterConfiguration} does not cause early initialization. + * + * @author Phillip Webb + */ +public class SessionAutoConfigurationEarlyInitializationIntegrationTests { + + @Test + void configurationIsFrozenWhenSessionRepositoryAccessed() { + new WebApplicationContextRunner(AnnotationConfigServletWebServerApplicationContext::new) + .withSystemProperties("spring.jndi.ignore=true") + .withPropertyValues("server.port=0") + .withUserConfiguration(TestConfiguration.class) + .run((context) -> assertThat(context).hasSingleBean(MapSessionRepository.class)); + } + + @Configuration(proxyBeanMethods = false) + @EnableSpringHttpSession + @ImportAutoConfiguration({ ServletWebServerFactoryAutoConfiguration.class, SessionAutoConfiguration.class }) + static class TestConfiguration { + + @Bean + MapSessionRepository mapSessionRepository(ConfigurableApplicationContext context) { + Assert.isTrue(context.getBeanFactory().isConfigurationFrozen(), "Context should be frozen"); + return new MapSessionRepository(new LinkedHashMap<>()); + } + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationJdbcTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationJdbcTests.java index 508e3ad3bf8a..3643eff1176e 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationJdbcTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationJdbcTests.java @@ -36,7 +36,7 @@ import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.boot.web.servlet.AbstractFilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; @@ -100,7 +100,7 @@ void filterOrderCanBeCustomized() { this.contextRunner .withPropertyValues("spring.session.store-type=jdbc", "spring.session.servlet.filter-order=123") .run((context) -> { - FilterRegistrationBean registration = context.getBean(FilterRegistrationBean.class); + AbstractFilterRegistrationBean registration = context.getBean(AbstractFilterRegistrationBean.class); assertThat(registration.getOrder()).isEqualTo(123); }); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationTests.java index 80e8b85db72d..ec4a96f0e1cf 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationTests.java @@ -28,7 +28,7 @@ import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.boot.web.servlet.AbstractFilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; @@ -41,6 +41,7 @@ import org.springframework.session.web.http.HeaderHttpSessionIdResolver; import org.springframework.session.web.http.HttpSessionIdResolver; import org.springframework.session.web.http.SessionRepositoryFilter; +import org.springframework.web.filter.DelegatingFilterProxy; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; @@ -99,8 +100,16 @@ void backOffIfSessionRepositoryIsPresent() { @Test void filterIsRegisteredWithAsyncErrorAndRequestDispatcherTypes() { this.contextRunner.withUserConfiguration(SessionRepositoryConfiguration.class).run((context) -> { - FilterRegistrationBean registration = context.getBean(FilterRegistrationBean.class); - assertThat(registration.getFilter()).isSameAs(context.getBean(SessionRepositoryFilter.class)); + AbstractFilterRegistrationBean registration = context.getBean(AbstractFilterRegistrationBean.class); + DelegatingFilterProxy delegatingFilterProxy = (DelegatingFilterProxy) registration.getFilter(); + try { + // Trigger actual initialization + delegatingFilterProxy.doFilter(null, null, null); + } + catch (Exception ex) { + } + assertThat(delegatingFilterProxy).extracting("delegate") + .isSameAs(context.getBean(SessionRepositoryFilter.class)); assertThat(registration) .extracting("dispatcherTypes", InstanceOfAssertFactories.iterable(DispatcherType.class)) .containsOnly(DispatcherType.ASYNC, DispatcherType.ERROR, DispatcherType.REQUEST); @@ -112,7 +121,7 @@ void filterOrderCanBeCustomizedWithCustomStore() { this.contextRunner.withUserConfiguration(SessionRepositoryConfiguration.class) .withPropertyValues("spring.session.servlet.filter-order=123") .run((context) -> { - FilterRegistrationBean registration = context.getBean(FilterRegistrationBean.class); + AbstractFilterRegistrationBean registration = context.getBean(AbstractFilterRegistrationBean.class); assertThat(registration.getOrder()).isEqualTo(123); }); } @@ -122,7 +131,7 @@ void filterDispatcherTypesCanBeCustomized() { this.contextRunner.withUserConfiguration(SessionRepositoryConfiguration.class) .withPropertyValues("spring.session.servlet.filter-dispatcher-types=error, request") .run((context) -> { - FilterRegistrationBean registration = context.getBean(FilterRegistrationBean.class); + AbstractFilterRegistrationBean registration = context.getBean(AbstractFilterRegistrationBean.class); assertThat(registration) .extracting("dispatcherTypes", InstanceOfAssertFactories.iterable(DispatcherType.class)) .containsOnly(DispatcherType.ERROR, DispatcherType.REQUEST); @@ -134,7 +143,7 @@ void emptyFilterDispatcherTypesDoNotThrowException() { this.contextRunner.withUserConfiguration(SessionRepositoryConfiguration.class) .withPropertyValues("spring.session.servlet.filter-dispatcher-types=") .run((context) -> { - FilterRegistrationBean registration = context.getBean(FilterRegistrationBean.class); + AbstractFilterRegistrationBean registration = context.getBean(AbstractFilterRegistrationBean.class); assertThat(registration) .extracting("dispatcherTypes", InstanceOfAssertFactories.iterable(DispatcherType.class)) .isEmpty(); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/FilterOrderingIntegrationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/FilterOrderingIntegrationTests.java index e13e55b4a0a4..1a62aa822a20 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/FilterOrderingIntegrationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/FilterOrderingIntegrationTests.java @@ -16,8 +16,6 @@ package org.springframework.boot.autoconfigure.web.servlet; -import java.util.ArrayList; -import java.util.Iterator; import java.util.List; import java.util.concurrent.ConcurrentHashMap; @@ -44,7 +42,7 @@ import org.springframework.security.web.FilterChainProxy; import org.springframework.session.MapSessionRepository; import org.springframework.session.config.annotation.web.http.EnableSpringHttpSession; -import org.springframework.session.web.http.SessionRepositoryFilter; +import org.springframework.web.filter.DelegatingFilterProxy; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.given; @@ -73,18 +71,19 @@ void testFilterOrdering() { List registeredFilters = this.context.getBean(MockServletWebServerFactory.class) .getWebServer() .getRegisteredFilters(); - List filters = new ArrayList<>(registeredFilters.size()); - for (RegisteredFilter registeredFilter : registeredFilters) { - filters.add(registeredFilter.getFilter()); - } - Iterator iterator = filters.iterator(); - assertThat(iterator.next()).isInstanceOf(OrderedCharacterEncodingFilter.class); - assertThat(iterator.next()).isInstanceOf(SessionRepositoryFilter.class); - assertThat(iterator.next()).isInstanceOf(Filter.class); - assertThat(iterator.next()).isInstanceOf(Filter.class); - assertThat(iterator.next()).isInstanceOf(OrderedRequestContextFilter.class); - assertThat(iterator.next()).isInstanceOf(ErrorPageSecurityFilter.class); - assertThat(iterator.next()).isInstanceOf(FilterChainProxy.class); + assertThat(registeredFilters.get(0).getFilter()).isInstanceOf(OrderedCharacterEncodingFilter.class); + assertThat(registeredFilters.get(1).getFilter()).isInstanceOf(DelegatingFilterProxy.class) + .extracting("targetBeanName") + .isEqualTo("springSessionRepositoryFilter"); + assertThat(registeredFilters.get(2).getFilter()).isInstanceOf(Filter.class) + .extracting("beanName") + .isEqualTo("hiddenHttpMethodFilter"); + assertThat(registeredFilters.get(3).getFilter()).isInstanceOf(Filter.class) + .extracting("beanName") + .isEqualTo("formContentFilter"); + assertThat(registeredFilters.get(4).getFilter()).isInstanceOf(OrderedRequestContextFilter.class); + assertThat(registeredFilters.get(5).getFilter()).isInstanceOf(ErrorPageSecurityFilter.class); + assertThat(registeredFilters.get(6).getFilter()).isInstanceOf(FilterChainProxy.class); } private void load() { From 6b646f6a8e5fd688f12a038e5577dd387300e267 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Tue, 2 May 2023 14:52:12 -0700 Subject: [PATCH 028/163] Update copyright year of changed files --- .../boot/actuate/endpoint/web/annotation/BaseConfiguration.java | 2 +- .../boot/autoconfigure/SpringBootApplication.java | 2 +- .../AbstractDevToolsDataSourceAutoConfigurationTests.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/BaseConfiguration.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/BaseConfiguration.java index ae3768e7a8a9..9b8b8094db9e 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/BaseConfiguration.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/BaseConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/SpringBootApplication.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/SpringBootApplication.java index 934489651b90..99d9ce03646e 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/SpringBootApplication.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/SpringBootApplication.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/AbstractDevToolsDataSourceAutoConfigurationTests.java b/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/AbstractDevToolsDataSourceAutoConfigurationTests.java index f2b531ba02ca..76987fe76e68 100644 --- a/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/AbstractDevToolsDataSourceAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/AbstractDevToolsDataSourceAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From b3226c55d2ba151af127bec6148471160ba870eb Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Tue, 2 May 2023 15:41:55 -0700 Subject: [PATCH 029/163] Polish --- .../BootBuildImageIntegrationTests.java | 4 +-- .../boot/maven/BuildImageTests.java | 3 +- .../boot/testsupport/junit/DisabledOnOs.java | 18 ++++++---- .../junit/DisabledOnOsCondition.java | 33 +++++++++++-------- 4 files changed, 36 insertions(+), 22 deletions(-) diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootBuildImageIntegrationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootBuildImageIntegrationTests.java index 4fc75060ff8c..7aacc87d4f7a 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootBuildImageIntegrationTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootBuildImageIntegrationTests.java @@ -36,7 +36,6 @@ import org.gradle.testkit.runner.BuildResult; import org.gradle.testkit.runner.TaskOutcome; import org.junit.jupiter.api.TestTemplate; -import org.junit.jupiter.api.condition.DisabledOnOs; import org.junit.jupiter.api.condition.OS; import org.springframework.boot.buildpack.platform.docker.DockerApi; @@ -47,6 +46,7 @@ import org.springframework.boot.buildpack.platform.io.FilePermissions; import org.springframework.boot.gradle.junit.GradleCompatibility; import org.springframework.boot.testsupport.gradle.testkit.GradleBuild; +import org.springframework.boot.testsupport.junit.DisabledOnOs; import org.springframework.boot.testsupport.testcontainers.DisabledIfDockerUnavailable; import static org.assertj.core.api.Assertions.assertThat; @@ -60,7 +60,7 @@ */ @GradleCompatibility(configurationCache = true) @DisabledIfDockerUnavailable -@org.springframework.boot.testsupport.junit.DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64", +@DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64", disabledReason = "The builder image has no ARM support") class BootBuildImageIntegrationTests { diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/BuildImageTests.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/BuildImageTests.java index d78d6a494002..7d6d83a67355 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/BuildImageTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/BuildImageTests.java @@ -33,6 +33,7 @@ import org.springframework.boot.buildpack.platform.docker.type.ImageName; import org.springframework.boot.buildpack.platform.docker.type.ImageReference; import org.springframework.boot.buildpack.platform.docker.type.VolumeName; +import org.springframework.boot.testsupport.junit.DisabledOnOs; import org.springframework.boot.testsupport.testcontainers.DisabledIfDockerUnavailable; import static org.assertj.core.api.Assertions.assertThat; @@ -46,7 +47,7 @@ */ @ExtendWith(MavenBuildExtension.class) @DisabledIfDockerUnavailable -@org.springframework.boot.testsupport.junit.DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64", +@DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64", disabledReason = "The builder image has no ARM support") class BuildImageTests extends AbstractArchiveIntegrationTests { diff --git a/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/junit/DisabledOnOs.java b/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/junit/DisabledOnOs.java index 0b0dd15b6940..1535e68d7e38 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/junit/DisabledOnOs.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/junit/DisabledOnOs.java @@ -37,16 +37,22 @@ public @interface DisabledOnOs { /** - * See {@link org.junit.jupiter.api.condition.DisabledOnOs#value()}. - * @return os + * The operating systems on which the annotated class or method should be disabled. + * @return the operating systems where the test is disabled */ - OS[] os(); + OS[] value() default {}; /** - * Architecture of the operating system. - * @return architecture + * The operating systems on which the annotated class or method should be disabled. + * @return the operating systems where the test is disabled */ - String architecture(); + OS[] os() default {}; + + /** + * The architectures on which the annotated class or method should be disabled. + * @return the architectures where the test is disabled + */ + String[] architecture() default {}; /** * See {@link org.junit.jupiter.api.condition.DisabledOnOs#disabledReason()}. diff --git a/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/junit/DisabledOnOsCondition.java b/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/junit/DisabledOnOsCondition.java index 855bcde7a095..32a08b0e88e8 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/junit/DisabledOnOsCondition.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/junit/DisabledOnOsCondition.java @@ -16,42 +16,49 @@ package org.springframework.boot.testsupport.junit; -import java.util.Optional; +import java.util.Arrays; import org.junit.jupiter.api.condition.OS; import org.junit.jupiter.api.extension.ConditionEvaluationResult; import org.junit.jupiter.api.extension.ExecutionCondition; import org.junit.jupiter.api.extension.ExtensionContext; -import org.junit.platform.commons.util.AnnotationUtils; + +import org.springframework.core.annotation.MergedAnnotation; +import org.springframework.core.annotation.MergedAnnotations; +import org.springframework.core.annotation.MergedAnnotations.SearchStrategy; /** * Evaluates {@link DisabledOnOs}. * * @author Moritz Halbritter + * @author Phillip Webb */ class DisabledOnOsCondition implements ExecutionCondition { @Override public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) { - Optional annotation = AnnotationUtils.findAnnotation(context.getElement(), DisabledOnOs.class); + if (!context.getElement().isPresent()) { + return ConditionEvaluationResult.enabled("No element for @DisabledOnOs found"); + } + MergedAnnotation annotation = MergedAnnotations + .from(context.getElement().get(), SearchStrategy.TYPE_HIERARCHY) + .get(DisabledOnOs.class); if (!annotation.isPresent()) { return ConditionEvaluationResult.enabled("No @DisabledOnOs found"); } - return evaluate(annotation.get()); + return evaluate(annotation.synthesize()); } private ConditionEvaluationResult evaluate(DisabledOnOs annotation) { String architecture = System.getProperty("os.arch"); String os = System.getProperty("os.name"); - if (annotation.architecture().equals(architecture)) { - for (OS targetOs : annotation.os()) { - if (targetOs.isCurrentOs()) { - String reason = annotation.disabledReason().isEmpty() - ? String.format("Disabled on OS = %s, architecture = %s", os, architecture) - : annotation.disabledReason(); - return ConditionEvaluationResult.disabled(reason); - } - } + boolean onDisabledOs = Arrays.stream(annotation.os()).anyMatch(OS::isCurrentOs); + boolean onDisabledArchitecture = Arrays.stream(annotation.architecture()).anyMatch(architecture::equals); + if (onDisabledOs && onDisabledArchitecture) { + String reason = annotation.disabledReason().isEmpty() + ? String.format("Disabled on OS = %s, architecture = %s", os, architecture) + : annotation.disabledReason(); + return ConditionEvaluationResult.disabled(reason); } return ConditionEvaluationResult .enabled(String.format("Enabled on OS = %s, architecture = %s", os, architecture)); From f3d0bc7a99320cb6b7874da5dea930ecbdd1850a Mon Sep 17 00:00:00 2001 From: Moritz Halbritter Date: Wed, 3 May 2023 11:32:33 +0200 Subject: [PATCH 030/163] Disable launch script integration tests on aarch64 linux and mac See gh-35229 --- .../boot/launchscript/JarLaunchScriptIntegrationTests.java | 6 +++++- .../launchscript/SysVinitLaunchScriptIntegrationTests.java | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/spring-boot-tests/spring-boot-integration-tests/spring-boot-launch-script-tests/src/intTest/java/org/springframework/boot/launchscript/JarLaunchScriptIntegrationTests.java b/spring-boot-tests/spring-boot-integration-tests/spring-boot-launch-script-tests/src/intTest/java/org/springframework/boot/launchscript/JarLaunchScriptIntegrationTests.java index c8ad70eea8eb..7a6270b7f423 100644 --- a/spring-boot-tests/spring-boot-integration-tests/spring-boot-launch-script-tests/src/intTest/java/org/springframework/boot/launchscript/JarLaunchScriptIntegrationTests.java +++ b/spring-boot-tests/spring-boot-integration-tests/spring-boot-launch-script-tests/src/intTest/java/org/springframework/boot/launchscript/JarLaunchScriptIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,9 +18,11 @@ import java.util.List; +import org.junit.jupiter.api.condition.OS; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.boot.testsupport.junit.DisabledOnOs; import org.springframework.boot.testsupport.testcontainers.DisabledIfDockerUnavailable; import static org.assertj.core.api.Assertions.assertThat; @@ -32,6 +34,8 @@ * @author Andy Wilkinson */ @DisabledIfDockerUnavailable +@DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64", + disabledReason = "The docker images have no ARM support") class JarLaunchScriptIntegrationTests extends AbstractLaunchScriptIntegrationTests { JarLaunchScriptIntegrationTests() { diff --git a/spring-boot-tests/spring-boot-integration-tests/spring-boot-launch-script-tests/src/intTest/java/org/springframework/boot/launchscript/SysVinitLaunchScriptIntegrationTests.java b/spring-boot-tests/spring-boot-integration-tests/spring-boot-launch-script-tests/src/intTest/java/org/springframework/boot/launchscript/SysVinitLaunchScriptIntegrationTests.java index 0275aec3254f..513e3527dc9b 100644 --- a/spring-boot-tests/spring-boot-integration-tests/spring-boot-launch-script-tests/src/intTest/java/org/springframework/boot/launchscript/SysVinitLaunchScriptIntegrationTests.java +++ b/spring-boot-tests/spring-boot-integration-tests/spring-boot-launch-script-tests/src/intTest/java/org/springframework/boot/launchscript/SysVinitLaunchScriptIntegrationTests.java @@ -20,10 +20,12 @@ import java.util.regex.Pattern; import org.junit.jupiter.api.Assumptions; +import org.junit.jupiter.api.condition.OS; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; import org.springframework.boot.ansi.AnsiColor; +import org.springframework.boot.testsupport.junit.DisabledOnOs; import org.springframework.boot.testsupport.testcontainers.DisabledIfDockerUnavailable; import static org.assertj.core.api.Assertions.assertThat; @@ -36,6 +38,8 @@ * @author Alexey Vinogradov */ @DisabledIfDockerUnavailable +@DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64", + disabledReason = "The docker images have no ARM support") class SysVinitLaunchScriptIntegrationTests extends AbstractLaunchScriptIntegrationTests { SysVinitLaunchScriptIntegrationTests() { From f5eb76074bf21b6bdc69f9b32dde2a4d4b0737a3 Mon Sep 17 00:00:00 2001 From: Moritz Halbritter Date: Wed, 3 May 2023 11:32:39 +0200 Subject: [PATCH 031/163] Disable loader integration tests on aarch64 linux and mac See gh-35229 --- .../springframework/boot/loader/LoaderIntegrationTests.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spring-boot-tests/spring-boot-integration-tests/spring-boot-loader-tests/src/intTest/java/org/springframework/boot/loader/LoaderIntegrationTests.java b/spring-boot-tests/spring-boot-integration-tests/spring-boot-loader-tests/src/intTest/java/org/springframework/boot/loader/LoaderIntegrationTests.java index afcdb9975c4a..35ed48e0c326 100644 --- a/spring-boot-tests/spring-boot-integration-tests/spring-boot-loader-tests/src/intTest/java/org/springframework/boot/loader/LoaderIntegrationTests.java +++ b/spring-boot-tests/spring-boot-integration-tests/spring-boot-loader-tests/src/intTest/java/org/springframework/boot/loader/LoaderIntegrationTests.java @@ -23,6 +23,7 @@ import java.util.function.Supplier; import java.util.stream.Stream; +import org.junit.jupiter.api.condition.OS; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; import org.testcontainers.containers.GenericContainer; @@ -33,6 +34,7 @@ import org.testcontainers.utility.MountableFile; import org.springframework.boot.system.JavaVersion; +import org.springframework.boot.testsupport.junit.DisabledOnOs; import org.springframework.boot.testsupport.testcontainers.DisabledIfDockerUnavailable; import org.springframework.util.Assert; @@ -44,6 +46,8 @@ * @author Phillip Webb */ @DisabledIfDockerUnavailable +@DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64", + disabledReason = "Not all docker images have ARM support") class LoaderIntegrationTests { private final ToStringConsumer output = new ToStringConsumer(); From fad24d5ced744818f6377502fa04c6286fd53866 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 3 May 2023 17:32:47 +0100 Subject: [PATCH 032/163] Fix handling of default port in mail health indicator Fixes gh-35247 --- .../actuate/mail/MailHealthIndicator.java | 6 ++-- .../mail/MailHealthIndicatorTests.java | 34 +++++++++++++++---- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/mail/MailHealthIndicator.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/mail/MailHealthIndicator.java index a7abf862f64a..08da5072a5b2 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/mail/MailHealthIndicator.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/mail/MailHealthIndicator.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,7 +38,9 @@ public MailHealthIndicator(JavaMailSenderImpl mailSender) { @Override protected void doHealthCheck(Builder builder) throws Exception { - builder.withDetail("location", this.mailSender.getHost() + ":" + this.mailSender.getPort()); + int port = this.mailSender.getPort(); + builder.withDetail("location", (port == JavaMailSenderImpl.DEFAULT_PORT) ? this.mailSender.getHost() + : this.mailSender.getHost() + ":" + this.mailSender.getPort()); this.mailSender.testConnection(); builder.up(); } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/mail/MailHealthIndicatorTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/mail/MailHealthIndicatorTests.java index 3cf1b7595fc3..1fdb6dba44a3 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/mail/MailHealthIndicatorTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/mail/MailHealthIndicatorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -57,25 +57,47 @@ void setup() { session.addProvider(new Provider(Type.TRANSPORT, "success", SuccessTransport.class.getName(), "Test", "1.0.0")); this.mailSender = mock(JavaMailSenderImpl.class); given(this.mailSender.getHost()).willReturn("smtp.acme.org"); - given(this.mailSender.getPort()).willReturn(25); given(this.mailSender.getSession()).willReturn(session); this.indicator = new MailHealthIndicator(this.mailSender); } @Test - void smtpIsUp() { + void smtpOnDefaultPortIsUp() { + given(this.mailSender.getPort()).willReturn(-1); given(this.mailSender.getProtocol()).willReturn("success"); Health health = this.indicator.health(); assertThat(health.getStatus()).isEqualTo(Status.UP); - assertThat(health.getDetails().get("location")).isEqualTo("smtp.acme.org:25"); + assertThat(health.getDetails().get("location")).isEqualTo("smtp.acme.org"); } @Test - void smtpIsDown() throws MessagingException { + void smtpOnDefaultPortIsDown() throws MessagingException { + given(this.mailSender.getPort()).willReturn(-1); willThrow(new MessagingException("A test exception")).given(this.mailSender).testConnection(); Health health = this.indicator.health(); assertThat(health.getStatus()).isEqualTo(Status.DOWN); - assertThat(health.getDetails().get("location")).isEqualTo("smtp.acme.org:25"); + assertThat(health.getDetails().get("location")).isEqualTo("smtp.acme.org"); + Object errorMessage = health.getDetails().get("error"); + assertThat(errorMessage).isNotNull(); + assertThat(errorMessage.toString().contains("A test exception")).isTrue(); + } + + @Test + void smtpOnCustomPortIsUp() { + given(this.mailSender.getPort()).willReturn(1234); + given(this.mailSender.getProtocol()).willReturn("success"); + Health health = this.indicator.health(); + assertThat(health.getStatus()).isEqualTo(Status.UP); + assertThat(health.getDetails().get("location")).isEqualTo("smtp.acme.org:1234"); + } + + @Test + void smtpOnCustomPortIsDown() throws MessagingException { + given(this.mailSender.getPort()).willReturn(1234); + willThrow(new MessagingException("A test exception")).given(this.mailSender).testConnection(); + Health health = this.indicator.health(); + assertThat(health.getStatus()).isEqualTo(Status.DOWN); + assertThat(health.getDetails().get("location")).isEqualTo("smtp.acme.org:1234"); Object errorMessage = health.getDetails().get("error"); assertThat(errorMessage).isNotNull(); assertThat(errorMessage.toString().contains("A test exception")).isTrue(); From 6ca9f91a8bdbfaea3f4e5c980770d20db85631d3 Mon Sep 17 00:00:00 2001 From: Moritz Halbritter Date: Thu, 4 May 2023 11:54:05 +0200 Subject: [PATCH 033/163] Fix NPE when gracefully shutting down netty Closes gh-35264 --- .../boot/web/embedded/netty/GracefulShutdown.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/GracefulShutdown.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/GracefulShutdown.java index 12a37e2c184a..a67158e1632c 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/GracefulShutdown.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/netty/GracefulShutdown.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -78,7 +78,7 @@ void abort() { while (!this.shuttingDown) { sleep(50); } - this.shutdownThread.interrupt(); + shutdownThread.interrupt(); } } From 75e9a7e95bb7a5b8c4d692f24d2c393956f9b4d3 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Thu, 4 May 2023 16:11:33 +0200 Subject: [PATCH 034/163] Upgrade Ubuntu version in CI images Closes gh-35259 --- ci/images/ci-image-jdk11/Dockerfile | 2 +- ci/images/ci-image-jdk17/Dockerfile | 2 +- ci/images/ci-image-jdk20/Dockerfile | 2 +- ci/images/ci-image/Dockerfile | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ci/images/ci-image-jdk11/Dockerfile b/ci/images/ci-image-jdk11/Dockerfile index fae9fa86b109..7ecc6edc92da 100644 --- a/ci/images/ci-image-jdk11/Dockerfile +++ b/ci/images/ci-image-jdk11/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:jammy-20230308 +FROM ubuntu:jammy-20230425 ADD setup.sh /setup.sh ADD get-jdk-url.sh /get-jdk-url.sh diff --git a/ci/images/ci-image-jdk17/Dockerfile b/ci/images/ci-image-jdk17/Dockerfile index 9516e68ec170..71ded4f77b8a 100644 --- a/ci/images/ci-image-jdk17/Dockerfile +++ b/ci/images/ci-image-jdk17/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:jammy-20230308 +FROM ubuntu:jammy-20230425 ADD setup.sh /setup.sh ADD get-jdk-url.sh /get-jdk-url.sh diff --git a/ci/images/ci-image-jdk20/Dockerfile b/ci/images/ci-image-jdk20/Dockerfile index 0c5b7d4e064a..bcc8a0d25428 100644 --- a/ci/images/ci-image-jdk20/Dockerfile +++ b/ci/images/ci-image-jdk20/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:jammy-20230308 +FROM ubuntu:jammy-20230425 ADD setup.sh /setup.sh ADD get-jdk-url.sh /get-jdk-url.sh diff --git a/ci/images/ci-image/Dockerfile b/ci/images/ci-image/Dockerfile index 4d786702a430..871bf1cca9f7 100644 --- a/ci/images/ci-image/Dockerfile +++ b/ci/images/ci-image/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:jammy-20230308 +FROM ubuntu:jammy-20230425 ADD setup.sh /setup.sh ADD get-jdk-url.sh /get-jdk-url.sh From 3a45d46583ae6a3a8c5fb31d9dfca52c02ff7514 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Fri, 5 May 2023 08:16:37 +0100 Subject: [PATCH 035/163] Allow buildSrc to resolve Framework snapshots Closes gh-35297 --- buildSrc/build.gradle | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index a313abb61974..5e31fcc37b23 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -9,19 +9,22 @@ repositories { gradlePluginPortal() } -sourceCompatibility = 1.8 -targetCompatibility = 1.8 - -ext { - def propertiesFile = new File(new File("$projectDir").parentFile, "gradle.properties") - propertiesFile.withInputStream { - def properties = new Properties() - properties.load(it) - set("kotlinVersion", properties["kotlinVersion"]) - set("springFrameworkVersion", properties["springFrameworkVersion"]) +new File(new File("$projectDir").parentFile, "gradle.properties").withInputStream { + def properties = new Properties() + properties.load(it) + ext.set("kotlinVersion", properties["kotlinVersion"]) + ext.set("springFrameworkVersion", properties["springFrameworkVersion"]) + if (properties["springFrameworkVersion"].contains("-")) { + repositories { + maven { url "https://repo.spring.io/milestone" } + maven { url "https://repo.spring.io/snapshot" } + } } } +sourceCompatibility = 1.8 +targetCompatibility = 1.8 + dependencies { checkstyle "io.spring.javaformat:spring-javaformat-checkstyle:${javaFormatVersion}" From ec72bcc9a8f987263260b189fe2234040e44e4b6 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Fri, 5 May 2023 08:10:57 +0200 Subject: [PATCH 036/163] Start building against Micrometer 1.9.11 snapshots See gh-35290 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 1a4f357f51aa..bc0ad14ce327 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1327,7 +1327,7 @@ bom { ] } } - library("Micrometer", "1.9.10") { + library("Micrometer", "1.9.11-SNAPSHOT") { group("io.micrometer") { modules = [ "micrometer-registry-stackdriver" { From b4715f5e1ef80fadfb85d1cccaddd07c5aef502a Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Fri, 5 May 2023 08:11:02 +0200 Subject: [PATCH 037/163] Start building against Reactor Bom 2020.0.32 snapshots See gh-35291 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index bc0ad14ce327..e455e6171a23 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1486,7 +1486,7 @@ bom { ] } } - library("Reactor Bom", "2020.0.31") { + library("Reactor Bom", "2020.0.32-SNAPSHOT") { group("io.projectreactor") { imports = [ "reactor-bom" From f32923da1a052921e94011b35086555163e5c44d Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Fri, 5 May 2023 08:11:07 +0200 Subject: [PATCH 038/163] Start building against Spring Data Bom 2021.2.12 snapshots See gh-35292 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index e455e6171a23..107f899d7dc2 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1739,7 +1739,7 @@ bom { ] } } - library("Spring Data Bom", "2021.2.11") { + library("Spring Data Bom", "2021.2.12-SNAPSHOT") { prohibit { versionRange "[2022.0.0-M1,)" because "it uses Spring Framework 6" From 546c0e0aafbd34091051fda090add68cfc35597c Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Fri, 5 May 2023 08:11:11 +0200 Subject: [PATCH 039/163] Start building against Spring Framework 5.3.28 snapshots See gh-35293 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 284895299a2f..2030424da7b4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ org.gradle.parallel=true org.gradle.jvmargs=-Xmx2g -Dfile.encoding=UTF-8 kotlinVersion=1.6.21 -springFrameworkVersion=5.3.27 +springFrameworkVersion=5.3.28-SNAPSHOT tomcatVersion=9.0.74 kotlin.stdlib.default.dependency=false From d614d1336e01c0e6c776285d0225612015ec9ab1 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Fri, 5 May 2023 08:11:16 +0200 Subject: [PATCH 040/163] Start building against Spring Integration 5.5.18 snapshots See gh-35294 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 107f899d7dc2..a541f363c416 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1780,7 +1780,7 @@ bom { ] } } - library("Spring Integration", "5.5.17") { + library("Spring Integration", "5.5.18-SNAPSHOT") { prohibit { versionRange "[6.0.0-M1,)" because "it uses Spring Framework 6" From 2b03e51a192d0c8ac8e1698911356f4db3619e31 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Fri, 5 May 2023 08:11:21 +0200 Subject: [PATCH 041/163] Start building against Spring WS 3.1.7 snapshots See gh-35295 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index a541f363c416..df82344ba1fb 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1854,7 +1854,7 @@ bom { ] } } - library("Spring WS", "3.1.6") { + library("Spring WS", "3.1.7-SNAPSHOT") { prohibit { versionRange "[4.0.0-M1,)" because "it uses Spring Framework 6" From eeefb2a1dedc7260ad009fcff318a7a9270e327c Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Fri, 5 May 2023 11:53:02 +0200 Subject: [PATCH 042/163] Polish --- .../metrics/PropertiesMeterFilterTests.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/PropertiesMeterFilterTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/PropertiesMeterFilterTests.java index 5db70a5285f4..e1db8683bb46 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/PropertiesMeterFilterTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/PropertiesMeterFilterTests.java @@ -175,33 +175,33 @@ void configureWhenAllHistogramTrueSetPercentilesHistogramToTrue() { @Test void configureWhenHasPercentilesShouldSetPercentilesToValue() { PropertiesMeterFilter filter = new PropertiesMeterFilter( - createProperties("distribution.percentiles.spring.boot=1,1.5,2")); + createProperties("distribution.percentiles.spring.boot=0.2,0.4,0.8")); assertThat(filter.configure(createMeterId("spring.boot"), DistributionStatisticConfig.DEFAULT).getPercentiles()) - .containsExactly(1, 1.5, 2); + .containsExactly(0.2, 0.4, 0.8); } @Test void configureWhenHasHigherPercentilesShouldSetPercentilesToValue() { PropertiesMeterFilter filter = new PropertiesMeterFilter( - createProperties("distribution.percentiles.spring=1,1.5,2")); + createProperties("distribution.percentiles.spring=0.2,0.4,0.8")); assertThat(filter.configure(createMeterId("spring.boot"), DistributionStatisticConfig.DEFAULT).getPercentiles()) - .containsExactly(1, 1.5, 2); + .containsExactly(0.2, 0.4, 0.8); } @Test void configureWhenHasHigherPercentilesAndLowerShouldSetPercentilesToLower() { PropertiesMeterFilter filter = new PropertiesMeterFilter(createProperties( - "distribution.percentiles.spring=1,1.5,2", "distribution.percentiles.spring.boot=3,3.5,4")); + "distribution.percentiles.spring=0.2,0.4,0.8", "distribution.percentiles.spring.boot=0.85,0.9,0.95")); assertThat(filter.configure(createMeterId("spring.boot"), DistributionStatisticConfig.DEFAULT).getPercentiles()) - .containsExactly(3, 3.5, 4); + .containsExactly(0.85, 0.9, 0.95); } @Test void configureWhenAllPercentilesSetShouldSetPercentilesToValue() { PropertiesMeterFilter filter = new PropertiesMeterFilter( - createProperties("distribution.percentiles.all=1,1.5,2")); + createProperties("distribution.percentiles.all=0.2,0.4,0.8")); assertThat(filter.configure(createMeterId("spring.boot"), DistributionStatisticConfig.DEFAULT).getPercentiles()) - .containsExactly(1, 1.5, 2); + .containsExactly(0.2, 0.4, 0.8); } @Test From 6dc84b164528385ab0ba8030c99e7b3c61024d92 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Fri, 5 May 2023 18:21:04 +0100 Subject: [PATCH 043/163] Ignore non-singleton factory beans when resetting mocks Closes gh-35324 --- .../ResetMocksTestExecutionListener.java | 22 +++++++++++-- .../ResetMocksTestExecutionListenerTests.java | 33 ++++++++++++++++++- 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/ResetMocksTestExecutionListener.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/ResetMocksTestExecutionListener.java index d3157918e099..0dc7b55c1199 100644 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/ResetMocksTestExecutionListener.java +++ b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/ResetMocksTestExecutionListener.java @@ -22,6 +22,8 @@ import org.mockito.Mockito; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; @@ -79,7 +81,7 @@ private void resetMocks(ConfigurableApplicationContext applicationContext, MockR BeanDefinition definition = beanFactory.getBeanDefinition(name); if (definition.isSingleton() && instantiatedSingletons.contains(name)) { Object bean = getBean(beanFactory, name); - if (reset.equals(MockReset.get(bean))) { + if (bean != null && reset.equals(MockReset.get(bean))) { Mockito.reset(bean); } } @@ -102,11 +104,25 @@ private void resetMocks(ConfigurableApplicationContext applicationContext, MockR private Object getBean(ConfigurableListableBeanFactory beanFactory, String name) { try { - return beanFactory.getBean(name); + if (isStandardBeanOrSingletonFactoryBean(beanFactory, name)) { + return beanFactory.getBean(name); + } } catch (Exception ex) { - return beanFactory.getSingleton(name); + // Continue + } + return beanFactory.getSingleton(name); + } + + private boolean isStandardBeanOrSingletonFactoryBean(ConfigurableListableBeanFactory beanFactory, String name) { + String factoryBeanName = BeanFactory.FACTORY_BEAN_PREFIX + name; + if (beanFactory.containsBean(factoryBeanName)) { + FactoryBean factoryBean = (FactoryBean) beanFactory.getBean(factoryBeanName); + if (!factoryBean.isSingleton()) { + return false; + } } + return true; } } diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/ResetMocksTestExecutionListenerTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/ResetMocksTestExecutionListenerTests.java index 1c51cedf9443..5735f4a3ffb5 100644 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/ResetMocksTestExecutionListenerTests.java +++ b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/mock/mockito/ResetMocksTestExecutionListenerTests.java @@ -53,6 +53,7 @@ void test001() { given(getMock("before").greeting()).willReturn("before"); given(getMock("after").greeting()).willReturn("after"); given(getMock("fromFactoryBean").greeting()).willReturn("fromFactoryBean"); + assertThat(this.context.getBean(NonSingletonFactoryBean.class).getObjectInvocations).isEqualTo(0); } @Test @@ -61,6 +62,7 @@ void test002() { assertThat(getMock("before").greeting()).isNull(); assertThat(getMock("after").greeting()).isNull(); assertThat(getMock("fromFactoryBean").greeting()).isNull(); + assertThat(this.context.getBean(NonSingletonFactoryBean.class).getObjectInvocations).isEqualTo(0); } ExampleService getMock(String name) { @@ -109,6 +111,11 @@ WorkingFactoryBean fromFactoryBean() { return new WorkingFactoryBean(); } + @Bean + NonSingletonFactoryBean nonSingletonFactoryBean() { + return new NonSingletonFactoryBean(); + } + } static class BrokenFactoryBean implements FactoryBean { @@ -132,9 +139,11 @@ public boolean isSingleton() { static class WorkingFactoryBean implements FactoryBean { + private final ExampleService service = mock(ExampleService.class, MockReset.before()); + @Override public ExampleService getObject() { - return mock(ExampleService.class, MockReset.before()); + return this.service; } @Override @@ -149,4 +158,26 @@ public boolean isSingleton() { } + static class NonSingletonFactoryBean implements FactoryBean { + + private int getObjectInvocations = 0; + + @Override + public ExampleService getObject() { + this.getObjectInvocations++; + return mock(ExampleService.class, MockReset.before()); + } + + @Override + public Class getObjectType() { + return ExampleService.class; + } + + @Override + public boolean isSingleton() { + return false; + } + + } + } From 5d91c24f63d306764215816126f854d5f85819f8 Mon Sep 17 00:00:00 2001 From: Scott Frederick Date: Tue, 2 May 2023 17:36:46 -0500 Subject: [PATCH 044/163] Update Couchbase image tag used in tests Closes gh-35228 --- .../couchbase/CouchbaseAutoConfigurationIntegrationTests.java | 4 ---- .../data/couchbase/DataCouchbaseTestIntegrationTests.java | 4 ---- .../couchbase/DataCouchbaseTestReactiveIntegrationTests.java | 4 ---- .../DataCouchbaseTestWithIncludeFilterIntegrationTests.java | 4 ---- .../boot/testsupport/testcontainers/DockerImageNames.java | 2 +- 5 files changed, 1 insertion(+), 17 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseAutoConfigurationIntegrationTests.java index 08fedda54e6b..82ef9350db84 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseAutoConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/couchbase/CouchbaseAutoConfigurationIntegrationTests.java @@ -27,7 +27,6 @@ import com.couchbase.client.java.json.JsonObject; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.condition.OS; import org.testcontainers.couchbase.BucketDefinition; import org.testcontainers.couchbase.CouchbaseContainer; import org.testcontainers.junit.jupiter.Container; @@ -35,7 +34,6 @@ import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.boot.testsupport.junit.DisabledOnOs; import org.springframework.boot.testsupport.testcontainers.DockerImageNames; import static org.assertj.core.api.Assertions.assertThat; @@ -46,8 +44,6 @@ * @author Stephane Nicoll * @author Brian Clozel */ -@DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64", - disabledReason = "The Couchbase image has no ARM support") @Testcontainers(disabledWithoutDocker = true) class CouchbaseAutoConfigurationIntegrationTests { diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/couchbase/DataCouchbaseTestIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/couchbase/DataCouchbaseTestIntegrationTests.java index e3e5ea1d84b1..1261a74edc4f 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/couchbase/DataCouchbaseTestIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/couchbase/DataCouchbaseTestIntegrationTests.java @@ -19,7 +19,6 @@ import java.time.Duration; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.condition.OS; import org.testcontainers.couchbase.BucketDefinition; import org.testcontainers.couchbase.CouchbaseContainer; import org.testcontainers.junit.jupiter.Container; @@ -27,7 +26,6 @@ import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.testsupport.junit.DisabledOnOs; import org.springframework.boot.testsupport.testcontainers.DockerImageNames; import org.springframework.context.ApplicationContext; import org.springframework.data.couchbase.core.CouchbaseTemplate; @@ -44,8 +42,6 @@ */ @DataCouchbaseTest @Testcontainers(disabledWithoutDocker = true) -@DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64", - disabledReason = "The Couchbase image has no ARM support") class DataCouchbaseTestIntegrationTests { private static final String BUCKET_NAME = "cbbucket"; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/couchbase/DataCouchbaseTestReactiveIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/couchbase/DataCouchbaseTestReactiveIntegrationTests.java index d2d132c1b5ca..27be882a85b5 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/couchbase/DataCouchbaseTestReactiveIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/couchbase/DataCouchbaseTestReactiveIntegrationTests.java @@ -19,14 +19,12 @@ import java.time.Duration; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.condition.OS; import org.testcontainers.couchbase.BucketDefinition; import org.testcontainers.couchbase.CouchbaseContainer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.testsupport.junit.DisabledOnOs; import org.springframework.boot.testsupport.testcontainers.DockerImageNames; import org.springframework.data.couchbase.core.ReactiveCouchbaseTemplate; import org.springframework.test.context.DynamicPropertyRegistry; @@ -42,8 +40,6 @@ */ @DataCouchbaseTest @Testcontainers(disabledWithoutDocker = true) -@DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64", - disabledReason = "The Couchbase image has no ARM support") class DataCouchbaseTestReactiveIntegrationTests { private static final String BUCKET_NAME = "cbbucket"; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/couchbase/DataCouchbaseTestWithIncludeFilterIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/couchbase/DataCouchbaseTestWithIncludeFilterIntegrationTests.java index 6081b9cbe9bf..1e779b709bc1 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/couchbase/DataCouchbaseTestWithIncludeFilterIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/data/couchbase/DataCouchbaseTestWithIncludeFilterIntegrationTests.java @@ -19,14 +19,12 @@ import java.time.Duration; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.condition.OS; import org.testcontainers.couchbase.BucketDefinition; import org.testcontainers.couchbase.CouchbaseContainer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.testsupport.junit.DisabledOnOs; import org.springframework.boot.testsupport.testcontainers.DockerImageNames; import org.springframework.context.annotation.ComponentScan.Filter; import org.springframework.stereotype.Service; @@ -43,8 +41,6 @@ */ @DataCouchbaseTest(includeFilters = @Filter(Service.class)) @Testcontainers(disabledWithoutDocker = true) -@DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64", - disabledReason = "The Couchbase image has no ARM support") class DataCouchbaseTestWithIncludeFilterIntegrationTests { private static final String BUCKET_NAME = "cbbucket"; diff --git a/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/testcontainers/DockerImageNames.java b/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/testcontainers/DockerImageNames.java index 36803822c387..2a6a5b74c5ec 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/testcontainers/DockerImageNames.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/testcontainers/DockerImageNames.java @@ -28,7 +28,7 @@ public final class DockerImageNames { private static final String CASSANDRA_VERSION = "3.11.10"; - private static final String COUCHBASE_VERSION = "6.5.1"; + private static final String COUCHBASE_VERSION = "7.1.4"; private static final String MONGO_VERSION = "4.0.23"; From 96c792050eef517dfdf39143d691656cef1badf1 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Mon, 8 May 2023 14:13:10 +0200 Subject: [PATCH 045/163] Upgrade to Elasticsearch 7.17.10 Closes gh-35339 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index df82344ba1fb..4db85d217069 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -306,7 +306,7 @@ bom { ] } } - library("Elasticsearch", "7.17.9") { + library("Elasticsearch", "7.17.10") { group("org.elasticsearch") { modules = [ "elasticsearch" From 40a392f65baacfe0cc086e7a2be08ea4a28cc165 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Mon, 8 May 2023 14:13:15 +0200 Subject: [PATCH 046/163] Upgrade to Johnzon 1.2.20 Closes gh-35340 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 4db85d217069..1f75800837b4 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1002,7 +1002,7 @@ bom { ] } } - library("Johnzon", "1.2.19") { + library("Johnzon", "1.2.20") { group("org.apache.johnzon") { modules = [ "johnzon-core", From cf5500fc78b185eeff24f10d590069373d65b0ef Mon Sep 17 00:00:00 2001 From: davin111 Date: Sat, 6 May 2023 21:05:59 +0900 Subject: [PATCH 047/163] Fix test for backing off when a TransactionManager is already defined See gh-35336 --- .../DataSourceTransactionManagerAutoConfigurationTests.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfigurationTests.java index a469c0495ae2..0c4b6d9e26a8 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfigurationTests.java @@ -38,6 +38,7 @@ * @author Dave Syer * @author Stephane Nicoll * @author Kazuki Shimizu + * @author Davin Byeon */ class DataSourceTransactionManagerAutoConfigurationTests { @@ -76,7 +77,7 @@ void transactionManagerWithCustomizationIsConfigured() { @Test void transactionManagerWithExistingTransactionManagerIsNotOverridden() { - this.contextRunner + this.contextRunner.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class)) .withBean("myTransactionManager", TransactionManager.class, () -> mock(TransactionManager.class)) .run((context) -> assertThat(context).hasSingleBean(TransactionManager.class) .hasBean("myTransactionManager")); From 7427e2d52718519eab9436789825cc9c2b27739c Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 9 May 2023 12:04:38 +0100 Subject: [PATCH 048/163] Polish "Fix test for backing off when a TransactionManager is already defined" See gh-35336 --- .../DataSourceTransactionManagerAutoConfigurationTests.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfigurationTests.java index 0c4b6d9e26a8..90044440432a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfigurationTests.java @@ -79,7 +79,8 @@ void transactionManagerWithCustomizationIsConfigured() { void transactionManagerWithExistingTransactionManagerIsNotOverridden() { this.contextRunner.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class)) .withBean("myTransactionManager", TransactionManager.class, () -> mock(TransactionManager.class)) - .run((context) -> assertThat(context).hasSingleBean(TransactionManager.class) + .run((context) -> assertThat(context).hasSingleBean(DataSource.class) + .hasSingleBean(TransactionManager.class) .hasBean("myTransactionManager")); } From c238049729e5dca60160a811bcfc0e9f857f38c0 Mon Sep 17 00:00:00 2001 From: Moritz Halbritter Date: Tue, 9 May 2023 13:53:18 +0200 Subject: [PATCH 049/163] Fix loading of PKCS#8 PEM encoded EC and DSA keys Closes gh-35322 --- .../boot/web/server/PrivateKeyParser.java | 32 +++++++++++++------ .../web/server/PrivateKeyParserTests.java | 25 +++++++++++++-- .../src/test/resources/ssl/pkcs8/key-dsa.pem | 15 +++++++++ .../resources/ssl/pkcs8/key-ec-nist-p256.pem | 6 ++++ .../resources/ssl/pkcs8/key-ec-nist-p384.pem | 7 ++++ .../resources/ssl/pkcs8/key-ec-prime256v1.pem | 6 ++++ .../resources/ssl/pkcs8/key-ec-secp256r1.pem | 6 ++++ .../src/test/resources/ssl/pkcs8/key-rsa.pem | 28 ++++++++++++++++ 8 files changed, 114 insertions(+), 11 deletions(-) create mode 100644 spring-boot-project/spring-boot/src/test/resources/ssl/pkcs8/key-dsa.pem create mode 100644 spring-boot-project/spring-boot/src/test/resources/ssl/pkcs8/key-ec-nist-p256.pem create mode 100644 spring-boot-project/spring-boot/src/test/resources/ssl/pkcs8/key-ec-nist-p384.pem create mode 100644 spring-boot-project/spring-boot/src/test/resources/ssl/pkcs8/key-ec-prime256v1.pem create mode 100644 spring-boot-project/spring-boot/src/test/resources/ssl/pkcs8/key-ec-secp256r1.pem create mode 100644 spring-boot-project/spring-boot/src/test/resources/ssl/pkcs8/key-rsa.pem diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/PrivateKeyParser.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/PrivateKeyParser.java index 93df27cb1c6c..474138e5af24 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/PrivateKeyParser.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/PrivateKeyParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,8 +24,11 @@ import java.security.GeneralSecurityException; import java.security.KeyFactory; import java.security.PrivateKey; +import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.function.Function; @@ -41,6 +44,7 @@ * * @author Scott Frederick * @author Phillip Webb + * @author Moritz Halbritter */ final class PrivateKeyParser { @@ -61,9 +65,12 @@ final class PrivateKeyParser { private static final List PEM_PARSERS; static { List parsers = new ArrayList<>(); - parsers.add(new PemParser(PKCS1_HEADER, PKCS1_FOOTER, "RSA", PrivateKeyParser::createKeySpecForPkcs1)); - parsers.add(new PemParser(EC_HEADER, EC_FOOTER, "EC", PrivateKeyParser::createKeySpecForEc)); - parsers.add(new PemParser(PKCS8_HEADER, PKCS8_FOOTER, "RSA", PKCS8EncodedKeySpec::new)); + parsers.add(new PemParser(PKCS1_HEADER, PKCS1_FOOTER, Collections.singleton("RSA"), + PrivateKeyParser::createKeySpecForPkcs1)); + parsers.add( + new PemParser(EC_HEADER, EC_FOOTER, Collections.singleton("EC"), PrivateKeyParser::createKeySpecForEc)); + parsers.add( + new PemParser(PKCS8_HEADER, PKCS8_FOOTER, Arrays.asList("RSA", "EC", "DSA"), PKCS8EncodedKeySpec::new)); PEM_PARSERS = Collections.unmodifiableList(parsers); } @@ -145,14 +152,14 @@ private static class PemParser { private final Pattern pattern; - private final String algorithm; + private final Collection algorithms; private final Function keySpecFactory; - PemParser(String header, String footer, String algorithm, + PemParser(String header, String footer, Collection algorithms, Function keySpecFactory) { this.pattern = Pattern.compile(header + BASE64_TEXT + footer, Pattern.CASE_INSENSITIVE); - this.algorithm = algorithm; + this.algorithms = algorithms; this.keySpecFactory = keySpecFactory; } @@ -169,8 +176,15 @@ private static byte[] decodeBase64(String content) { private PrivateKey parse(byte[] bytes) { try { PKCS8EncodedKeySpec keySpec = this.keySpecFactory.apply(bytes); - KeyFactory keyFactory = KeyFactory.getInstance(this.algorithm); - return keyFactory.generatePrivate(keySpec); + for (String algorithm : this.algorithms) { + KeyFactory keyFactory = KeyFactory.getInstance(algorithm); + try { + return keyFactory.generatePrivate(keySpec); + } + catch (InvalidKeySpecException ignored) { + } + } + return null; } catch (GeneralSecurityException ex) { throw new IllegalArgumentException("Unexpected key format", ex); diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/PrivateKeyParserTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/PrivateKeyParserTests.java index 390fb1b2b68d..926e5ac12b7b 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/PrivateKeyParserTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/server/PrivateKeyParserTests.java @@ -19,6 +19,8 @@ import java.security.PrivateKey; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalStateException; @@ -27,17 +29,36 @@ * Tests for {@link PrivateKeyParser}. * * @author Scott Frederick + * @author Moritz Halbritter */ class PrivateKeyParserTests { @Test - void parsePkcs8KeyFile() { - PrivateKey privateKey = PrivateKeyParser.parse("classpath:test-key.pem"); + void parsePkcs8RsaKeyFile() { + PrivateKey privateKey = PrivateKeyParser.parse("classpath:ssl/pkcs8/key-rsa.pem"); assertThat(privateKey).isNotNull(); assertThat(privateKey.getFormat()).isEqualTo("PKCS#8"); assertThat(privateKey.getAlgorithm()).isEqualTo("RSA"); } + @ParameterizedTest + @ValueSource(strings = { "key-ec-nist-p256.pem", "key-ec-nist-p384.pem", "key-ec-prime256v1.pem", + "key-ec-secp256r1.pem" }) + void parsePkcs8EcKeyFile(String fileName) { + PrivateKey privateKey = PrivateKeyParser.parse("classpath:ssl/pkcs8/" + fileName); + assertThat(privateKey).isNotNull(); + assertThat(privateKey.getFormat()).isEqualTo("PKCS#8"); + assertThat(privateKey.getAlgorithm()).isEqualTo("EC"); + } + + @Test + void parsePkcs8DsaKeyFile() { + PrivateKey privateKey = PrivateKeyParser.parse("classpath:ssl/pkcs8/key-dsa.pem"); + assertThat(privateKey).isNotNull(); + assertThat(privateKey.getFormat()).isEqualTo("PKCS#8"); + assertThat(privateKey.getAlgorithm()).isEqualTo("DSA"); + } + @Test void parsePkcs8KeyFileWithEcdsa() { PrivateKey privateKey = PrivateKeyParser.parse("classpath:test-ec-key.pem"); diff --git a/spring-boot-project/spring-boot/src/test/resources/ssl/pkcs8/key-dsa.pem b/spring-boot-project/spring-boot/src/test/resources/ssl/pkcs8/key-dsa.pem new file mode 100644 index 000000000000..1aa27e11c20f --- /dev/null +++ b/spring-boot-project/spring-boot/src/test/resources/ssl/pkcs8/key-dsa.pem @@ -0,0 +1,15 @@ +-----BEGIN PRIVATE KEY----- +MIICXAIBADCCAjUGByqGSM44BAEwggIoAoIBAQCPeTXZuarpv6vtiHrPSVG28y7F +njuvNxjo6sSWHz79NgbnQ1GpxBgzObgJ58KuHFObp0dbhdARrbi0eYd1SYRpXKwO +jxSzNggooi/6JxEKPWKpk0U0CaD+aWxGWPhL3SCBnDcJoBBXsZWtzQAjPbpUhLYp +H51kjviDRIZ3l5zsBLQ0pqwudemYXeI9sCkvwRGMn/qdgYHnM423krcw17njSVkv +aAmYchU5Feo9a4tGU8YzRY+AOzKkwuDycpAlbk4/ijsIOKHEUOThjBopo33fXqFD +3ktm/wSQPtXPFiPhWNSHxgjpfyEc2B3KI8tuOAdl+CLjQr5ITAV2OTlgHNZnAh0A +uvaWpoV499/e5/pnyXfHhe8ysjO65YDAvNVpXQKCAQAWplxYIEhQcE51AqOXVwQN +NNo6NHjBVNTkpcAtJC7gT5bmHkvQkEq9rI837rHgnzGC0jyQQ8tkL4gAQWDt+coJ +syB2p5wypifyRz6Rh5uixOdEvSCBVEy1W4AsNo0fqD7UielOD6BojjJCilx4xHjG +jQUntxyaOrsLC+EsRGiWOefTznTbEBplqiuH9kxoJts+xy9LVZmDS7TtsC98kOmk +ltOlXVNb6/xF1PYZ9j897buHOSXC8iTgdzEpbaiH7B5HSPh++1/et1SEMWsiMt7l +U92vAhErDR8C2jCXMiT+J67ai51LKSLZuovjntnhA6Y8UoELxoi34u1DFuHvF9ve +BB4CHHBQgJ3ST6U8rIxoTqGe42TiVckPf1PoSiJy8GY= +-----END PRIVATE KEY----- diff --git a/spring-boot-project/spring-boot/src/test/resources/ssl/pkcs8/key-ec-nist-p256.pem b/spring-boot-project/spring-boot/src/test/resources/ssl/pkcs8/key-ec-nist-p256.pem new file mode 100644 index 000000000000..8cd5d39294cf --- /dev/null +++ b/spring-boot-project/spring-boot/src/test/resources/ssl/pkcs8/key-ec-nist-p256.pem @@ -0,0 +1,6 @@ +-----BEGIN PRIVATE KEY----- +MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgd6SePFfpaTKFd1Gm ++WeHZNkORkot5hx6X9elPdICL9ygCgYIKoZIzj0DAQehRANCAASnMAMgeFBv9ks0 +d0jP+utQ3mohwmxY93xljfaBofdg1IeHgDd4I4pBzPxEnvXrU3kcz+SgPZyH1ybl +P6mSXDXu +-----END PRIVATE KEY----- diff --git a/spring-boot-project/spring-boot/src/test/resources/ssl/pkcs8/key-ec-nist-p384.pem b/spring-boot-project/spring-boot/src/test/resources/ssl/pkcs8/key-ec-nist-p384.pem new file mode 100644 index 000000000000..563b519588b7 --- /dev/null +++ b/spring-boot-project/spring-boot/src/test/resources/ssl/pkcs8/key-ec-nist-p384.pem @@ -0,0 +1,7 @@ +-----BEGIN PRIVATE KEY----- +MIG/AgEAMBAGByqGSM49AgEGBSuBBAAiBIGnMIGkAgEBBDCexXiWKrtrqV1+d1Tv +t1n5huuw2A+204mQHRuPL9UC8l0XniJjx/PVELCciyJM/7+gBwYFK4EEACKhZANi +AASHEELZSdrHiSXqU1B+/jrOCr6yjxCMqQsetTb0q5WZdCXOhggGXfbzlRynqphQ +i4G7azBUklgLaXfxN5eFk6C+E38SYOR7iippcQsSR2ZsCiTk7rnur4b40gQ7IgLA +/sU= +-----END PRIVATE KEY----- diff --git a/spring-boot-project/spring-boot/src/test/resources/ssl/pkcs8/key-ec-prime256v1.pem b/spring-boot-project/spring-boot/src/test/resources/ssl/pkcs8/key-ec-prime256v1.pem new file mode 100644 index 000000000000..66c626d622ef --- /dev/null +++ b/spring-boot-project/spring-boot/src/test/resources/ssl/pkcs8/key-ec-prime256v1.pem @@ -0,0 +1,6 @@ +-----BEGIN PRIVATE KEY----- +MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQg4dVuddgQ6enDvPPw +Dd1mmS6FMm/kzTJjDVsltrNmRuSgCgYIKoZIzj0DAQehRANCAAR1WMrRADEaVj9m +uoUfPhUefJK+lS89NHikQ0ZdkHkybyVKLFMLe1hCynhzpKQmnpgud3E10F0P2PZQ +L9RCEpGf +-----END PRIVATE KEY----- diff --git a/spring-boot-project/spring-boot/src/test/resources/ssl/pkcs8/key-ec-secp256r1.pem b/spring-boot-project/spring-boot/src/test/resources/ssl/pkcs8/key-ec-secp256r1.pem new file mode 100644 index 000000000000..adffc64637e7 --- /dev/null +++ b/spring-boot-project/spring-boot/src/test/resources/ssl/pkcs8/key-ec-secp256r1.pem @@ -0,0 +1,6 @@ +-----BEGIN PRIVATE KEY----- +MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgU9+v5hUNnTKix8fe +Pfz+NfXFlGxQZMReSCT2Id9PfKagCgYIKoZIzj0DAQehRANCAATeJg+YS4BrJ35A +KgRlZ59yKLDpmENCMoaYUuWbQ9hqHzdybQGzQsrNJqgH0nzWghPwP4nFaLPN+pgB +bqiRgbjG +-----END PRIVATE KEY----- diff --git a/spring-boot-project/spring-boot/src/test/resources/ssl/pkcs8/key-rsa.pem b/spring-boot-project/spring-boot/src/test/resources/ssl/pkcs8/key-rsa.pem new file mode 100644 index 000000000000..00d439edc6b0 --- /dev/null +++ b/spring-boot-project/spring-boot/src/test/resources/ssl/pkcs8/key-rsa.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDR0KfxUw7MF/8R +B5/YXOM7yLnoHYb/M/6dyoulMbtEdKKhQhU28o5FiDkHcEG9PJQLgqrRgAjl3VmC +C9omtfZJQ2EpfkTttkJjnKOOroXhYE51/CYSckapBYCVh8GkjUEJuEfnp07cTfYZ +FqViIgIWPZyjkzl3w4girS7kCuzNdDntVJVx5F/EsFwMA8n3C0QazHQoM5s00Fer +6aTwd6AW0JD5QkADavpfzZ554e4HrVGwHlM28WKQQkFzzGu44FFXyVuEF3HeyVPu +g8GRHAc8UU7ijVgJB5TmbvRGYowIErD5i4VvGLuOv9mgR3aVyN0SdJ1N7aJnXpeS +QjAgf03jAgMBAAECggEBAIhQyzwj3WJGWOZkkLqOpufJotcmj/Wwf0VfOdkq9WMl +cB/bAlN/xWVxerPVgDCFch4EWBzi1WUaqbOvJZ2u7QNubmr56aiTmJCFTVI/GyZx +XqiTGN01N6lKtN7xo6LYTyAUhUsBTWAemrx0FSErvTVb9C/mUBj6hbEZ2XQ5kN5t +7qYX4Lu0zyn7s1kX5SLtm5I+YRq7HSwB6wLy+DSroO71izZ/VPwME3SwT5SN+c87 +3dkklR7fumNd9dOpSWKrLPnq4aMko00rvIGc63xD1HrEpXUkB5v24YEn7HwCLEH7 +b8jrp79j2nCvvR47inpf+BR8FIWAHEOUUqCEzjQkdiECgYEA6ifjMM0f02KPeIs7 +zXd1lI7CUmJmzkcklCIpEbKWf/t/PHv3QgqIkJzERzRaJ8b+GhQ4zrSwAhrGUmI8 +kDkXIqe2/2ONgIOX2UOHYHyTDQZHnlXyDecvHUTqs2JQZCGBZkXyZ9i0j3BnTymC +iZ8DvEa0nxsbP+U3rgzPQmXiQVMCgYEA5WN2Y/RndbriNsNrsHYRldbPO5nfV9rp +cDzcQU66HRdK5VIdbXT9tlMYCJIZsSqE0tkOwTgEB/sFvF/tIHSCY5iO6hpIyk6g +kkUzPcld4eM0dEPAge7SYUbakB9CMvA7MkDQSXQNFyZ0mH83+UikwT6uYHFh7+ox +N1P+psDhXzECgYEA1gXLVQnIcy/9LxMkgDMWV8j8uMyUZysDthpbK3/uq+A2dhRg +9g4msPd5OBQT65OpIjElk1n4HpRWfWqpLLHiAZ0GWPynk7W0D7P3gyuaRSdeQs0P +x8FtgPVDCN9t13gAjHiWjnC26Py2kNbCKAQeJ/MAmQTvrUFX2VCACJKTcV0CgYAj +xJWSUmrLfb+GQISLOG3Xim434e9keJsLyEGj4U29+YLRLTOvfJ2PD3fg5j8hU/rw +Ea5uTHi8cdTcIa0M8X3fX8txD3YoLYh2JlouGTcNYOst8d6TpBSj3HN6I5Wj8beZ +R2fy/CiKYpGtsbCdq0kdZNO18BgQW9kewncjs1GxEQKBgQCf8q34h6KuHpHSDh9h +YkDTypk0FReWBAVJCzDNDUMhVLFivjcwtaMd2LiC3FMKZYodr52iKg60cj43vbYI +frmFFxoL37rTmUocCTBKc0LhWj6MicI+rcvQYe1uwTrpWdFf1aZJMYRLRczeKtev +OWaE/9hVZ5+9pild1NukGpOydw== +-----END PRIVATE KEY----- From e47738b84d4e415216cf856067df32318bf67fd6 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Tue, 9 May 2023 13:30:08 +0200 Subject: [PATCH 050/163] Upgrade to Micrometer 1.9.11 Closes gh-35290 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 1f75800837b4..a67f1090cb83 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1327,7 +1327,7 @@ bom { ] } } - library("Micrometer", "1.9.11-SNAPSHOT") { + library("Micrometer", "1.9.11") { group("io.micrometer") { modules = [ "micrometer-registry-stackdriver" { From 21cca4f30de9421e336d2558ba301bb50959a20c Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Tue, 9 May 2023 13:30:09 +0200 Subject: [PATCH 051/163] Upgrade to Reactor Bom 2020.0.32 Closes gh-35291 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index a67f1090cb83..da4dbe886105 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1486,7 +1486,7 @@ bom { ] } } - library("Reactor Bom", "2020.0.32-SNAPSHOT") { + library("Reactor Bom", "2020.0.32") { group("io.projectreactor") { imports = [ "reactor-bom" From 52789cb1917319c25d52bff1a69b99459592f918 Mon Sep 17 00:00:00 2001 From: Moritz Halbritter Date: Wed, 10 May 2023 08:21:17 +0200 Subject: [PATCH 052/163] Fix anchors in Maven plugin documentation Closes gh-35371 --- .../src/docs/asciidoc/anchor-rewrite.properties | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/docs/asciidoc/anchor-rewrite.properties b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/docs/asciidoc/anchor-rewrite.properties index af45d43d6838..0cea3c652e57 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/docs/asciidoc/anchor-rewrite.properties +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/docs/asciidoc/anchor-rewrite.properties @@ -1,17 +1,8 @@ - -build-info=? -getting-started=? -goals=? -help=? -spring-boot-maven-plugin-documentation=? -introduction=?.? -integration-tests=integration-tests integration-tests-no-starter-parent=integration-tests.no-starter-parent integration-tests-example=integration-tests.examples integration-tests-example-random-port=integration-tests.examples.random-port integration-tests-example-jmx-port=integration-tests.examples.jmx-port integration-tests-example-skip=integration-tests.examples.skip -build-image=build-image build-image-docker-daemon=build-image.docker-daemon build-image-docker-registry=build-image.docker-registry build-image-customization=build-image.customization @@ -33,14 +24,12 @@ repackage-example-custom-layout=packaging.examples.custom-layout repackage-example-exclude-dependency=packaging.examples.exclude-dependency repackage-layered-archive-tools=packaging.examples.layered-archive-tools repackage-layered-archive-additional-layers=packaging.examples.custom-layers-configuration -run=run run-examples=run.examples run-example-debug=run.examples.debug run-example-system-properties=run.examples.system-properties run-example-environment-variables=run.examples.environment-variables run-example-application-arguments=run.examples.using-application-arguments run-example-active-profiles=run.examples.specify-active-profiles -using=using using-parent-pom=using.parent-pom using-import=using.import using-overriding-command-line=using.overriding-command-line From 947ac8df7300a9cad3312d6726bdcd536964822d Mon Sep 17 00:00:00 2001 From: Moritz Halbritter Date: Wed, 10 May 2023 10:05:11 +0200 Subject: [PATCH 053/163] Map MinIdle and MaxValidationTime to R2DBC pools Closes gh-34724 --- .../ConnectionFactoryConfigurations.java | 2 ++ .../autoconfigure/r2dbc/R2dbcProperties.java | 33 ++++++++++++++++++- .../r2dbc/R2dbcAutoConfigurationTests.java | 18 +++++++--- 3 files changed, 48 insertions(+), 5 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/ConnectionFactoryConfigurations.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/ConnectionFactoryConfigurations.java index a4c636d2a151..25ec1ea363ef 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/ConnectionFactoryConfigurations.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/ConnectionFactoryConfigurations.java @@ -103,6 +103,8 @@ ConnectionPool connectionFactory(R2dbcProperties properties, ResourceLoader reso map.from(pool.getMaxSize()).to(builder::maxSize); map.from(pool.getValidationQuery()).whenHasText().to(builder::validationQuery); map.from(pool.getValidationDepth()).to(builder::validationDepth); + map.from(pool.getMinIdle()).to(builder::minIdle); + map.from(pool.getMaxValidationTime()).to(builder::maxValidationTime); return new ConnectionPool(builder.build()); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcProperties.java index bcaab87b894e..fb662fba6908 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -136,6 +136,13 @@ public String determineUniqueName() { public static class Pool { + /** + * Minimal number of idle connections. + * + * @since 2.7.12 + */ + private int minIdle = 0; + /** * Maximum amount of time that a connection is allowed to sit idle in the pool. */ @@ -153,6 +160,14 @@ public static class Pool { */ private Duration maxAcquireTime; + /** + * Maximum time to validate a connection from the pool. By default, wait + * indefinitely. + * + * @since 2.7.12 + */ + private Duration maxValidationTime; + /** * Maximum time to wait to create a new connection. By default, wait indefinitely. */ @@ -183,6 +198,14 @@ public static class Pool { */ private boolean enabled = true; + public int getMinIdle() { + return this.minIdle; + } + + public void setMinIdle(int minIdle) { + this.minIdle = minIdle; + } + public Duration getMaxIdleTime() { return this.maxIdleTime; } @@ -199,6 +222,14 @@ public void setMaxLifeTime(Duration maxLifeTime) { this.maxLifeTime = maxLifeTime; } + public Duration getMaxValidationTime() { + return this.maxValidationTime; + } + + public void setMaxValidationTime(Duration maxValidationTime) { + this.maxValidationTime = maxValidationTime; + } + public Duration getMaxAcquireTime() { return this.maxAcquireTime; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcAutoConfigurationTests.java index 8c475362c1d9..87ae445521f3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcAutoConfigurationTests.java @@ -77,15 +77,25 @@ void configureWithUrlCreateConnectionPoolByDefault() { void configureWithUrlAndPoolPropertiesApplyProperties() { this.contextRunner .withPropertyValues("spring.r2dbc.url:r2dbc:h2:mem:///" + randomDatabaseName(), - "spring.r2dbc.pool.max-size=15", "spring.r2dbc.pool.max-acquire-time=3m") + "spring.r2dbc.pool.max-size=15", "spring.r2dbc.pool.max-acquire-time=3m", + "spring.r2dbc.pool.min-idle=1", "spring.r2dbc.pool.max-validation-time=1s", + "spring.r2dbc.pool.initial-size=0") .run((context) -> { assertThat(context).hasSingleBean(ConnectionFactory.class) .hasSingleBean(ConnectionPool.class) .hasSingleBean(R2dbcProperties.class); ConnectionPool connectionPool = context.getBean(ConnectionPool.class); - PoolMetrics poolMetrics = connectionPool.getMetrics().get(); - assertThat(poolMetrics.getMaxAllocatedSize()).isEqualTo(15); - assertThat(connectionPool).hasFieldOrPropertyWithValue("maxAcquireTime", Duration.ofMinutes(3)); + connectionPool.warmup().block(); + try { + PoolMetrics poolMetrics = connectionPool.getMetrics().get(); + assertThat(poolMetrics.idleSize()).isEqualTo(1); + assertThat(poolMetrics.getMaxAllocatedSize()).isEqualTo(15); + assertThat(connectionPool).hasFieldOrPropertyWithValue("maxAcquireTime", Duration.ofMinutes(3)); + assertThat(connectionPool).hasFieldOrPropertyWithValue("maxValidationTime", Duration.ofSeconds(1)); + } + finally { + connectionPool.close().block(); + } }); } From ec4d52e38145e7fe9586aa767efb17e158c68a37 Mon Sep 17 00:00:00 2001 From: Moritz Halbritter Date: Wed, 10 May 2023 10:47:08 +0200 Subject: [PATCH 054/163] Add ReactiveResponseConsumer classpath check to http5 auto-configuration Closes gh-34964 --- .../spring-boot-autoconfigure/build.gradle | 3 ++- .../client/ClientHttpConnectorConfiguration.java | 3 ++- .../client/ClientHttpConnectorConfigurationTests.java | 11 +++++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/build.gradle b/spring-boot-project/spring-boot-autoconfigure/build.gradle index 6c6cdc76bac5..724c0f502e5e 100644 --- a/spring-boot-project/spring-boot-autoconfigure/build.gradle +++ b/spring-boot-project/spring-boot-autoconfigure/build.gradle @@ -73,6 +73,7 @@ dependencies { exclude group: "commons-logging", module: "commons-logging" } optional("org.apache.httpcomponents.client5:httpclient5") + optional("org.apache.httpcomponents.core5:httpcore5-reactive") optional("org.apache.kafka:kafka-streams") optional("org.apache.solr:solr-solrj") { exclude group: "org.slf4j", module: "jcl-over-slf4j" @@ -275,4 +276,4 @@ tasks.named("checkSpringConfigurationMetadata").configure { "spring.datasource.tomcat.*", "spring.groovy.template.configuration.*" ] -} \ No newline at end of file +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/function/client/ClientHttpConnectorConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/function/client/ClientHttpConnectorConfiguration.java index 85ec0c5392f3..be43dbbbe60c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/function/client/ClientHttpConnectorConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/function/client/ClientHttpConnectorConfiguration.java @@ -18,6 +18,7 @@ import org.apache.hc.client5.http.impl.async.HttpAsyncClients; import org.apache.hc.core5.http.nio.AsyncRequestProducer; +import org.apache.hc.core5.reactive.ReactiveResponseConsumer; import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.util.ssl.SslContextFactory; @@ -87,7 +88,7 @@ JettyClientHttpConnector jettyClientHttpConnector(JettyResourceFactory jettyReso } @Configuration(proxyBeanMethods = false) - @ConditionalOnClass({ HttpAsyncClients.class, AsyncRequestProducer.class }) + @ConditionalOnClass({ HttpAsyncClients.class, AsyncRequestProducer.class, ReactiveResponseConsumer.class }) @ConditionalOnMissingBean(ClientHttpConnector.class) static class HttpClient5 { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/function/client/ClientHttpConnectorConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/function/client/ClientHttpConnectorConfigurationTests.java index 5e25714e1863..9314605c18bd 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/function/client/ClientHttpConnectorConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/function/client/ClientHttpConnectorConfigurationTests.java @@ -24,8 +24,10 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; import org.springframework.context.annotation.Bean; +import org.springframework.http.client.reactive.HttpComponentsClientHttpConnector; import org.springframework.http.client.reactive.JettyClientHttpConnector; import org.springframework.http.client.reactive.JettyResourceFactory; import org.springframework.test.util.ReflectionTestUtils; @@ -38,6 +40,7 @@ * * @author Phillip Webb * @author Brian Clozel + * @author Moritz Halbritter */ class ClientHttpConnectorConfigurationTests { @@ -83,6 +86,14 @@ void shouldApplyHttpClientMapper() { }); } + @Test + void shouldNotConfigureReactiveHttpClient5WhenHttpCore5ReactiveJarIsMissing() { + new ReactiveWebApplicationContextRunner() + .withClassLoader(new FilteredClassLoader("org.apache.hc.core5.reactive")) + .withConfiguration(AutoConfigurations.of(ClientHttpConnectorConfiguration.HttpClient5.class)) + .run((context) -> assertThat(context).doesNotHaveBean(HttpComponentsClientHttpConnector.class)); + } + static class CustomHttpClientMapper { static boolean called = false; From e2365ff2a43dfb57a3531d6c96f4d21a37f30026 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Wed, 10 May 2023 09:53:20 -0700 Subject: [PATCH 055/163] Upgrade Java 8 version in CI image and .sdkmanrc and switch to Bellsoft Closes gh-35385 --- .sdkmanrc | 3 +++ ci/images/get-jdk-url.sh | 10 +++++----- 2 files changed, 8 insertions(+), 5 deletions(-) create mode 100644 .sdkmanrc diff --git a/.sdkmanrc b/.sdkmanrc new file mode 100644 index 000000000000..efa0e43ec434 --- /dev/null +++ b/.sdkmanrc @@ -0,0 +1,3 @@ +# Enable auto-env through the sdkman_auto_env config +# Add key=value pairs of SDKs to use below +java=8.0.372-librca diff --git a/ci/images/get-jdk-url.sh b/ci/images/get-jdk-url.sh index 73d0a553686f..0e2d418deb29 100755 --- a/ci/images/get-jdk-url.sh +++ b/ci/images/get-jdk-url.sh @@ -3,18 +3,18 @@ set -e case "$1" in java8) - echo "https://github.com/adoptium/temurin8-binaries/releases/download/jdk8u332-b09/OpenJDK8U-jdk_x64_linux_hotspot_8u332b09.tar.gz" + echo "https://github.com/bell-sw/Liberica/releases/download/8u372+7/bellsoft-jdk8u372+7-linux-amd64.tar.gz" ;; java11) - echo "https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.15%2B10/OpenJDK11U-jdk_x64_linux_hotspot_11.0.15_10.tar.gz" + echo "https://github.com/bell-sw/Liberica/releases/download/11.0.19+7/bellsoft-jdk11.0.19+7-linux-amd64.tar.gz" ;; java17) - echo "https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.3%2B7/OpenJDK17U-jdk_x64_linux_hotspot_17.0.3_7.tar.gz" + echo "https://github.com/bell-sw/Liberica/releases/download/17.0.7+7/bellsoft-jdk17.0.7+7-linux-amd64.tar.gz" ;; java18) - echo "https://github.com/adoptium/temurin18-binaries/releases/download/jdk-18.0.1%2B10/OpenJDK18U-jdk_x64_linux_hotspot_18.0.1_10.tar.gz" + echo "https://github.com/bell-sw/Liberica/releases/download/18.0.2.1+1/bellsoft-jdk18.0.2.1+1-linux-amd64.tar.gz" ;; - *) + *) echo $"Unknown java version" exit 1 esac From 852e3ed7ca13216b1d297e9ff604afb27d438b83 Mon Sep 17 00:00:00 2001 From: Scott Frederick Date: Wed, 10 May 2023 15:31:57 -0500 Subject: [PATCH 056/163] Upgrade CI to Docker 23.0.6 Closes gh-35388 --- ci/images/get-docker-url.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/images/get-docker-url.sh b/ci/images/get-docker-url.sh index 677f8ed4a0d1..67445b9d2f57 100755 --- a/ci/images/get-docker-url.sh +++ b/ci/images/get-docker-url.sh @@ -1,5 +1,5 @@ #!/bin/bash set -e -version="23.0.5" +version="23.0.6" echo "https://download.docker.com/linux/static/stable/x86_64/docker-$version.tgz"; From 9af19370a69bd4395e51a4e349012198d64109a8 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Wed, 10 May 2023 10:06:26 -0700 Subject: [PATCH 057/163] Backport build and CI concerns Backport build and CI concerns primarily related to repo.spring.io changes and Docker config. --- .../boot/build/AsciidoctorConventions.java | 7 +- .../artifactory/ArtifactoryRepository.java | 60 ------------- .../boot/build/artifacts/ArtifactRelease.java | 74 +++++++++++++++ .../AbstractPackageManagerDefinitionTask.java | 19 ++-- .../ArtifactoryRepositoryTests.java | 60 ------------- .../build/artifacts/ArtifactReleaseTests.java | 90 +++++++++++++++++++ ci/images/ci-image-jdk11/Dockerfile | 4 +- ci/images/ci-image-jdk17/Dockerfile | 4 +- ci/images/ci-image-jdk18/Dockerfile | 4 +- ci/images/ci-image/Dockerfile | 3 +- .../releasescripts/sdkman/SdkmanService.java | 2 +- .../sdkman/SdkmanServiceTests.java | 6 +- ci/parameters.yml | 3 - ci/pipeline.yml | 47 +++++----- ci/scripts/detect-jdk-updates.sh | 4 +- ci/scripts/detect-ubuntu-image-updates.sh | 4 +- ci/scripts/update-homebrew-tap.sh | 2 +- ci/tasks/build-ci-image.yml | 6 +- ci/tasks/build-project-windows.yml | 1 + ci/tasks/build-project.yml | 15 ++-- ci/tasks/generate-changelog.yml | 8 +- ci/tasks/stage.yml | 1 + eclipse/eclipse.properties | 2 +- eclipse/spring-boot-project.setup | 31 +++++-- .../src/main/homebrew/spring-boot.rb | 2 +- .../src/main/scoop/springboot.json | 2 +- .../grape/MavenResolverGrapeEngineTests.java | 2 +- .../src/docs/asciidoc/attributes.adoc | 2 +- .../getting-started/first-application.adoc | 4 +- .../asciidoc/getting-started/installing.adoc | 13 +-- .../src/docs/asciidoc/getting-started.adoc | 6 +- .../docs/asciidoc/managing-dependencies.adoc | 6 +- 32 files changed, 278 insertions(+), 216 deletions(-) delete mode 100644 buildSrc/src/main/java/org/springframework/boot/build/artifactory/ArtifactoryRepository.java create mode 100644 buildSrc/src/main/java/org/springframework/boot/build/artifacts/ArtifactRelease.java delete mode 100644 buildSrc/src/test/java/org/springframework/boot/build/artifactory/ArtifactoryRepositoryTests.java create mode 100644 buildSrc/src/test/java/org/springframework/boot/build/artifacts/ArtifactReleaseTests.java diff --git a/buildSrc/src/main/java/org/springframework/boot/build/AsciidoctorConventions.java b/buildSrc/src/main/java/org/springframework/boot/build/AsciidoctorConventions.java index a3b48a724751..a9614e1fd7d8 100644 --- a/buildSrc/src/main/java/org/springframework/boot/build/AsciidoctorConventions.java +++ b/buildSrc/src/main/java/org/springframework/boot/build/AsciidoctorConventions.java @@ -30,7 +30,7 @@ import org.gradle.api.tasks.PathSensitivity; import org.gradle.api.tasks.Sync; -import org.springframework.boot.build.artifactory.ArtifactoryRepository; +import org.springframework.boot.build.artifacts.ArtifactRelease; import org.springframework.util.StringUtils; /** @@ -66,6 +66,7 @@ * * * @author Andy Wilkinson + * @author Scott Frederick */ class AsciidoctorConventions { @@ -128,10 +129,12 @@ private void configureAsciidoctorTask(Project project, AbstractAsciidoctorTask a } private void configureCommonAttributes(Project project, AbstractAsciidoctorTask asciidoctorTask) { + ArtifactRelease artifacts = ArtifactRelease.forProject(project); Map attributes = new HashMap<>(); attributes.put("attribute-missing", "warn"); attributes.put("github-tag", determineGitHubTag(project)); - attributes.put("spring-boot-artifactory-repo", ArtifactoryRepository.forProject(project)); + attributes.put("artifact-release-type", artifacts.getType()); + attributes.put("artifact-download-repo", artifacts.getDownloadRepo()); attributes.put("revnumber", null); asciidoctorTask.attributes(attributes); } diff --git a/buildSrc/src/main/java/org/springframework/boot/build/artifactory/ArtifactoryRepository.java b/buildSrc/src/main/java/org/springframework/boot/build/artifactory/ArtifactoryRepository.java deleted file mode 100644 index 12c9b7f8bb65..000000000000 --- a/buildSrc/src/main/java/org/springframework/boot/build/artifactory/ArtifactoryRepository.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2012-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.build.artifactory; - -import org.gradle.api.Project; - -/** - * An Artifactory repository to which a build of Spring Boot can be published. - * - * @author Andy Wilkinson - */ -public final class ArtifactoryRepository { - - private final String name; - - private ArtifactoryRepository(String name) { - this.name = name; - } - - public String getName() { - return this.name; - } - - @Override - public String toString() { - return this.name; - } - - public static ArtifactoryRepository forProject(Project project) { - return new ArtifactoryRepository(determineArtifactoryRepo(project)); - } - - private static String determineArtifactoryRepo(Project project) { - String version = project.getVersion().toString(); - int modifierIndex = version.lastIndexOf('-'); - if (modifierIndex == -1) { - return "release"; - } - String type = version.substring(modifierIndex + 1); - if (type.startsWith("M") || type.startsWith("RC")) { - return "milestone"; - } - return "snapshot"; - } - -} diff --git a/buildSrc/src/main/java/org/springframework/boot/build/artifacts/ArtifactRelease.java b/buildSrc/src/main/java/org/springframework/boot/build/artifacts/ArtifactRelease.java new file mode 100644 index 000000000000..31a74a56c74d --- /dev/null +++ b/buildSrc/src/main/java/org/springframework/boot/build/artifacts/ArtifactRelease.java @@ -0,0 +1,74 @@ +/* + * Copyright 2012-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.build.artifacts; + +import org.gradle.api.Project; + +/** + * Information about artifacts produced by a build. + * + * @author Andy Wilkinson + * @author Scott Frederick + */ +public final class ArtifactRelease { + + private static final String SNAPSHOT = "snapshot"; + + private static final String MILESTONE = "milestone"; + + private static final String RELEASE = "release"; + + private static final String SPRING_REPO = "https://repo.spring.io/%s"; + + private static final String MAVEN_REPO = "https://repo.maven.apache.org/maven2"; + + private final String type; + + private ArtifactRelease(String type) { + this.type = type; + } + + public String getType() { + return this.type; + } + + public String getDownloadRepo() { + return (this.isRelease()) ? MAVEN_REPO : String.format(SPRING_REPO, this.getType()); + } + + public boolean isRelease() { + return RELEASE.equals(this.type); + } + + public static ArtifactRelease forProject(Project project) { + return new ArtifactRelease(determineReleaseType(project)); + } + + private static String determineReleaseType(Project project) { + String version = project.getVersion().toString(); + int modifierIndex = version.lastIndexOf('-'); + if (modifierIndex == -1) { + return RELEASE; + } + String type = version.substring(modifierIndex + 1); + if (type.startsWith("M") || type.startsWith("RC")) { + return MILESTONE; + } + return SNAPSHOT; + } + +} diff --git a/buildSrc/src/main/java/org/springframework/boot/build/cli/AbstractPackageManagerDefinitionTask.java b/buildSrc/src/main/java/org/springframework/boot/build/cli/AbstractPackageManagerDefinitionTask.java index b2d4ea1f90e7..e6903d1b8c5a 100644 --- a/buildSrc/src/main/java/org/springframework/boot/build/cli/AbstractPackageManagerDefinitionTask.java +++ b/buildSrc/src/main/java/org/springframework/boot/build/cli/AbstractPackageManagerDefinitionTask.java @@ -23,6 +23,7 @@ import org.apache.commons.codec.digest.DigestUtils; import org.gradle.api.DefaultTask; +import org.gradle.api.Project; import org.gradle.api.file.RegularFile; import org.gradle.api.provider.Provider; import org.gradle.api.tasks.InputFile; @@ -31,13 +32,14 @@ import org.gradle.api.tasks.PathSensitivity; import org.gradle.api.tasks.TaskExecutionException; -import org.springframework.boot.build.artifactory.ArtifactoryRepository; +import org.springframework.boot.build.artifacts.ArtifactRelease; /** * Base class for generating a package manager definition file such as a Scoop manifest or * a Homebrew formula. * * @author Andy Wilkinson + * @author Phillip Webb */ public abstract class AbstractPackageManagerDefinitionTask extends DefaultTask { @@ -84,14 +86,19 @@ protected void createDescriptor(Map additionalProperties) { getProject().copy((copy) -> { copy.from(this.template); copy.into(this.outputDir); - Map properties = new HashMap<>(additionalProperties); - properties.put("hash", sha256(this.archive.get().getAsFile())); - properties.put("repo", ArtifactoryRepository.forProject(getProject())); - properties.put("project", getProject()); - copy.expand(properties); + copy.expand(getProperties(additionalProperties)); }); } + private Map getProperties(Map additionalProperties) { + Map properties = new HashMap<>(additionalProperties); + Project project = getProject(); + properties.put("hash", sha256(this.archive.get().getAsFile())); + properties.put("repo", ArtifactRelease.forProject(project).getDownloadRepo()); + properties.put("project", project); + return properties; + } + private String sha256(File file) { try { MessageDigest digest = MessageDigest.getInstance("SHA-256"); diff --git a/buildSrc/src/test/java/org/springframework/boot/build/artifactory/ArtifactoryRepositoryTests.java b/buildSrc/src/test/java/org/springframework/boot/build/artifactory/ArtifactoryRepositoryTests.java deleted file mode 100644 index f878e1afdf41..000000000000 --- a/buildSrc/src/test/java/org/springframework/boot/build/artifactory/ArtifactoryRepositoryTests.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2012-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.build.artifactory; - -import org.gradle.api.Project; -import org.gradle.testfixtures.ProjectBuilder; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link ArtifactoryRepository}. - * - * @author Andy Wilkinson - */ -class ArtifactoryRepositoryTests { - - @Test - void whenProjectVersionIsMilestoneThenRepositoryIsMilestone() { - Project project = ProjectBuilder.builder().build(); - project.setVersion("1.2.3-M1"); - assertThat(ArtifactoryRepository.forProject(project).getName()).isEqualTo("milestone"); - } - - @Test - void whenProjectVersionIsReleaseCandidateThenRepositoryIsMilestone() { - Project project = ProjectBuilder.builder().build(); - project.setVersion("1.2.3-RC1"); - assertThat(ArtifactoryRepository.forProject(project).getName()).isEqualTo("milestone"); - } - - @Test - void whenProjectVersionIsReleaseThenRepositoryIsRelease() { - Project project = ProjectBuilder.builder().build(); - project.setVersion("1.2.3"); - assertThat(ArtifactoryRepository.forProject(project).getName()).isEqualTo("release"); - } - - @Test - void whenProjectVersionIsSnapshotThenRepositoryIsSnapshot() { - Project project = ProjectBuilder.builder().build(); - project.setVersion("1.2.3-SNAPSHOT"); - assertThat(ArtifactoryRepository.forProject(project).getName()).isEqualTo("snapshot"); - } - -} diff --git a/buildSrc/src/test/java/org/springframework/boot/build/artifacts/ArtifactReleaseTests.java b/buildSrc/src/test/java/org/springframework/boot/build/artifacts/ArtifactReleaseTests.java new file mode 100644 index 000000000000..0a9d5e420a75 --- /dev/null +++ b/buildSrc/src/test/java/org/springframework/boot/build/artifacts/ArtifactReleaseTests.java @@ -0,0 +1,90 @@ +/* + * Copyright 2012-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.build.artifacts; + +import org.gradle.api.Project; +import org.gradle.testfixtures.ProjectBuilder; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link ArtifactRelease}. + * + * @author Andy Wilkinson + * @author Scott Frederick + */ +class ArtifactReleaseTests { + + @Test + void whenProjectVersionIsSnapshotThenTypeIsSnapshot() { + Project project = ProjectBuilder.builder().build(); + project.setVersion("1.2.3-SNAPSHOT"); + assertThat(ArtifactRelease.forProject(project).getType()).isEqualTo("snapshot"); + } + + @Test + void whenProjectVersionIsMilestoneThenTypeIsMilestone() { + Project project = ProjectBuilder.builder().build(); + project.setVersion("1.2.3-M1"); + assertThat(ArtifactRelease.forProject(project).getType()).isEqualTo("milestone"); + } + + @Test + void whenProjectVersionIsReleaseCandidateThenTypeIsMilestone() { + Project project = ProjectBuilder.builder().build(); + project.setVersion("1.2.3-RC1"); + assertThat(ArtifactRelease.forProject(project).getType()).isEqualTo("milestone"); + } + + @Test + void whenProjectVersionIsReleaseThenTypeIsRelease() { + Project project = ProjectBuilder.builder().build(); + project.setVersion("1.2.3"); + assertThat(ArtifactRelease.forProject(project).getType()).isEqualTo("release"); + } + + @Test + void whenProjectVersionIsSnapshotThenRepositoryIsArtifactorySnapshot() { + Project project = ProjectBuilder.builder().build(); + project.setVersion("1.2.3-SNAPSHOT"); + assertThat(ArtifactRelease.forProject(project).getDownloadRepo()).contains("repo.spring.io/snapshot"); + } + + @Test + void whenProjectVersionIsMilestoneThenRepositoryIsArtifactoryMilestone() { + Project project = ProjectBuilder.builder().build(); + project.setVersion("1.2.3-M1"); + assertThat(ArtifactRelease.forProject(project).getDownloadRepo()).contains("repo.spring.io/milestone"); + } + + @Test + void whenProjectVersionIsReleaseCandidateThenRepositoryIsArtifactoryMilestone() { + Project project = ProjectBuilder.builder().build(); + project.setVersion("1.2.3-RC1"); + assertThat(ArtifactRelease.forProject(project).getDownloadRepo()).contains("repo.spring.io/milestone"); + } + + @Test + void whenProjectVersionIsReleaseThenRepositoryIsMavenCentral() { + Project project = ProjectBuilder.builder().build(); + project.setVersion("1.2.3"); + assertThat(ArtifactRelease.forProject(project).getDownloadRepo()) + .contains("https://repo.maven.apache.org/maven2"); + } + +} diff --git a/ci/images/ci-image-jdk11/Dockerfile b/ci/images/ci-image-jdk11/Dockerfile index 2107cfce18ab..714275083cdb 100644 --- a/ci/images/ci-image-jdk11/Dockerfile +++ b/ci/images/ci-image-jdk11/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:focal-20220426 +FROM ubuntu:focal-20220922 ADD setup.sh /setup.sh ADD get-jdk-url.sh /get-jdk-url.sh @@ -8,5 +8,3 @@ RUN ./setup.sh java11 ENV JAVA_HOME /opt/openjdk ENV PATH $JAVA_HOME/bin:$PATH ADD docker-lib.sh /docker-lib.sh - -ENTRYPOINT [ "switch", "shell=/bin/bash", "--", "codep", "/bin/docker daemon" ] diff --git a/ci/images/ci-image-jdk17/Dockerfile b/ci/images/ci-image-jdk17/Dockerfile index 289066d61eba..216f1487fdd9 100644 --- a/ci/images/ci-image-jdk17/Dockerfile +++ b/ci/images/ci-image-jdk17/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:focal-20220426 +FROM ubuntu:focal-20220922 ADD setup.sh /setup.sh ADD get-jdk-url.sh /get-jdk-url.sh @@ -8,5 +8,3 @@ RUN ./setup.sh java8 java17 ENV JAVA_HOME /opt/openjdk ENV PATH $JAVA_HOME/bin:$PATH ADD docker-lib.sh /docker-lib.sh - -ENTRYPOINT [ "switch", "shell=/bin/bash", "--", "codep", "/bin/docker daemon" ] diff --git a/ci/images/ci-image-jdk18/Dockerfile b/ci/images/ci-image-jdk18/Dockerfile index f76acac35f0d..b38a98f2dcba 100644 --- a/ci/images/ci-image-jdk18/Dockerfile +++ b/ci/images/ci-image-jdk18/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:focal-20220426 +FROM ubuntu:focal-20220922 ADD setup.sh /setup.sh ADD get-jdk-url.sh /get-jdk-url.sh @@ -8,5 +8,3 @@ RUN ./setup.sh java8 java18 ENV JAVA_HOME /opt/openjdk ENV PATH $JAVA_HOME/bin:$PATH ADD docker-lib.sh /docker-lib.sh - -ENTRYPOINT [ "switch", "shell=/bin/bash", "--", "codep", "/bin/docker daemon" ] diff --git a/ci/images/ci-image/Dockerfile b/ci/images/ci-image/Dockerfile index 52b60e363b4b..0418aa95cdd3 100644 --- a/ci/images/ci-image/Dockerfile +++ b/ci/images/ci-image/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:focal-20220426 +FROM ubuntu:focal-20220922 ADD setup.sh /setup.sh ADD get-jdk-url.sh /get-jdk-url.sh @@ -12,4 +12,3 @@ ADD docker-lib.sh /docker-lib.sh ADD build-release-scripts.sh /build-release-scripts.sh ADD releasescripts /release-scripts RUN ./build-release-scripts.sh -ENTRYPOINT [ "switch", "shell=/bin/bash", "--", "codep", "/bin/docker daemon" ] diff --git a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/sdkman/SdkmanService.java b/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/sdkman/SdkmanService.java index c0e38cc0befd..897df837f85d 100644 --- a/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/sdkman/SdkmanService.java +++ b/ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/sdkman/SdkmanService.java @@ -40,7 +40,7 @@ public class SdkmanService { private static final String SDKMAN_URL = "https://vendors.sdkman.io/"; - private static final String DOWNLOAD_URL = "https://repo.spring.io/simple/libs-release-local/org/springframework/boot/spring-boot-cli/" + private static final String DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot-cli/" + "%s/spring-boot-cli-%s-bin.zip"; private static final String CHANGELOG_URL = "https://github.com/spring-projects/spring-boot/releases/tag/v%s"; diff --git a/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/sdkman/SdkmanServiceTests.java b/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/sdkman/SdkmanServiceTests.java index 419392e523ce..3a81ecfd3f29 100644 --- a/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/sdkman/SdkmanServiceTests.java +++ b/ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/sdkman/SdkmanServiceTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -55,7 +55,7 @@ void tearDown() { @Test void publishWhenMakeDefaultTrue() { setupExpectation("https://vendors.sdkman.io/release", - "{\"candidate\": \"springboot\", \"version\": \"1.2.3\", \"url\": \"https://repo.spring.io/simple/libs-release-local/org/springframework/boot/spring-boot-cli/1.2.3/spring-boot-cli-1.2.3-bin.zip\"}"); + "{\"candidate\": \"springboot\", \"version\": \"1.2.3\", \"url\": \"https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot-cli/1.2.3/spring-boot-cli-1.2.3-bin.zip\"}"); setupExpectation("https://vendors.sdkman.io/default", "{\"candidate\": \"springboot\", \"version\": \"1.2.3\"}", HttpMethod.PUT); setupExpectation("https://vendors.sdkman.io/announce/struct", @@ -67,7 +67,7 @@ void publishWhenMakeDefaultTrue() { @Test void publishWhenMakeDefaultFalse() { setupExpectation("https://vendors.sdkman.io/release", - "{\"candidate\": \"springboot\", \"version\": \"1.2.3\", \"url\": \"https://repo.spring.io/simple/libs-release-local/org/springframework/boot/spring-boot-cli/1.2.3/spring-boot-cli-1.2.3-bin.zip\"}"); + "{\"candidate\": \"springboot\", \"version\": \"1.2.3\", \"url\": \"https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot-cli/1.2.3/spring-boot-cli-1.2.3-bin.zip\"}"); setupExpectation("https://vendors.sdkman.io/announce/struct", "{\"candidate\": \"springboot\", \"version\": \"1.2.3\", \"hashtag\": \"springboot\", \"url\": \"https://github.com/spring-projects/spring-boot/releases/tag/v1.2.3\"}"); this.service.publish("1.2.3", false); diff --git a/ci/parameters.yml b/ci/parameters.yml index 6e2424434023..ee0919ddee6f 100644 --- a/ci/parameters.yml +++ b/ci/parameters.yml @@ -1,6 +1,3 @@ -email-server: "smtp.svc.pivotal.io" -email-from: "ci@spring.io" -email-to: ["spring-boot-dev@pivotal.io"] github-repo: "https://github.com/spring-projects/spring-boot.git" github-repo-name: "spring-projects/spring-boot" homebrew-tap-repo: "https://github.com/spring-io/homebrew-tap.git" diff --git a/ci/pipeline.yml b/ci/pipeline.yml index 2629ababbf47..dd14b4b0a91e 100644 --- a/ci/pipeline.yml +++ b/ci/pipeline.yml @@ -7,19 +7,20 @@ anchors: registry-image-resource-source: ®istry-image-resource-source username: ((docker-hub-username)) password: ((docker-hub-password)) + ci-registry-image-resource-source: &ci-registry-image-resource-source + username: ((docker-hub-username)) + password: ((docker-hub-password)) tag: ((milestone)) - registry_mirror: - host: ((docker-hub-mirror)) - username: ((docker-hub-mirror-username)) - password: ((docker-hub-mirror-password)) gradle-enterprise-task-params: &gradle-enterprise-task-params GRADLE_ENTERPRISE_ACCESS_KEY: ((gradle_enterprise_secret_access_key)) + GRADLE_ENTERPRISE_CACHE_URL: ((gradle_enterprise_cache_url)) GRADLE_ENTERPRISE_CACHE_USERNAME: ((gradle_enterprise_cache_user.username)) GRADLE_ENTERPRISE_CACHE_PASSWORD: ((gradle_enterprise_cache_user.password)) docker-hub-task-params: &docker-hub-task-params DOCKER_HUB_MIRROR: ((docker-hub-mirror)) DOCKER_HUB_USERNAME: ((docker-hub-username)) DOCKER_HUB_PASSWORD: ((docker-hub-password)) + DOCKER_HUB_AUTH: ((docker-hub-auth)) github-task-params: &github-task-params GITHUB_REPO: spring-boot GITHUB_ORGANIZATION: spring-projects @@ -52,7 +53,7 @@ anchors: repo: libs-snapshot-local folder: distribution-repository build_uri: "https://ci.spring.io/teams/${BUILD_TEAM_NAME}/pipelines/${BUILD_PIPELINE_NAME}/jobs/${BUILD_JOB_NAME}/builds/${BUILD_NAME}" - build_number: "${BUILD_PIPELINE_NAME}-${BUILD_JOB_NAME}-${BUILD_NAME}" + build_number: "${BUILD_JOB_NAME}-${BUILD_NAME}" disable_checksum_uploads: true threads: 8 artifact_set: @@ -85,41 +86,43 @@ anchors: gradle-publish-params: &gradle-publish-params GRADLE_PUBLISH_KEY: ((gradle-publish-key)) GRADLE_PUBLISH_SECRET: ((gradle-publish-secret)) - docker-hub-mirror-vars: &docker-hub-mirror-vars - docker-hub-mirror: ((docker-hub-mirror)) - docker-hub-mirror-username: ((docker-hub-mirror-username)) - docker-hub-mirror-password: ((docker-hub-mirror-password)) resource_types: - name: registry-image type: registry-image source: + <<: *registry-image-resource-source repository: concourse/registry-image-resource - tag: 1.5.0 + tag: 1.7.1 - name: artifactory-resource type: registry-image source: + <<: *registry-image-resource-source repository: springio/artifactory-resource - tag: 0.0.17 + tag: 0.0.18 - name: pull-request type: registry-image source: + <<: *registry-image-resource-source repository: teliaoss/github-pr-resource tag: v0.23.0 - name: github-status-resource type: registry-image source: + <<: *registry-image-resource-source repository: dpb587/github-status-resource tag: master - name: slack-notification type: registry-image source: + <<: *registry-image-resource-source repository: cfcommunity/slack-notification-resource tag: latest - name: github-release type: registry-image source: + <<: *registry-image-resource-source repository: concourse/github-release-resource - tag: 1.5.5 + tag: 1.8.0 resources: - name: git-repo type: git @@ -170,25 +173,25 @@ resources: type: registry-image icon: docker source: - <<: *registry-image-resource-source + <<: *ci-registry-image-resource-source repository: ((docker-hub-organization))/spring-boot-ci - name: ci-image-jdk11 type: registry-image icon: docker source: - <<: *registry-image-resource-source + <<: *ci-registry-image-resource-source repository: ((docker-hub-organization))/spring-boot-ci-jdk11 - name: ci-image-jdk17 type: registry-image icon: docker source: - <<: *registry-image-resource-source + <<: *ci-registry-image-resource-source repository: ((docker-hub-organization))/spring-boot-ci-jdk17 - name: ci-image-jdk18 type: registry-image icon: docker source: - <<: *registry-image-resource-source + <<: *ci-registry-image-resource-source repository: ((docker-hub-organization))/spring-boot-ci-jdk18 - name: artifactory-repo type: artifactory-resource @@ -198,6 +201,8 @@ resources: username: ((artifactory-username)) password: ((artifactory-password)) build_name: ((build-name)) + build_number_prefix: "${BUILD_PIPELINE_NAME}-" + check_limit: 500 - name: repo-status-build type: github-status-resource icon: eye-check-outline @@ -265,7 +270,6 @@ jobs: image: ci-image vars: ci-image-name: ci-image - <<: *docker-hub-mirror-vars - task: build-ci-image-jdk11 privileged: true file: git-repo/ci/tasks/build-ci-image.yml @@ -273,7 +277,6 @@ jobs: image: ci-image-jdk11 vars: ci-image-name: ci-image-jdk11 - <<: *docker-hub-mirror-vars - task: build-ci-image-jdk17 privileged: true file: git-repo/ci/tasks/build-ci-image.yml @@ -281,7 +284,6 @@ jobs: image: ci-image-jdk17 vars: ci-image-name: ci-image-jdk17 - <<: *docker-hub-mirror-vars - task: build-ci-image-jdk18 privileged: true file: git-repo/ci/tasks/build-ci-image.yml @@ -289,7 +291,6 @@ jobs: image: ci-image-jdk18 vars: ci-image-name: ci-image-jdk18 - <<: *docker-hub-mirror-vars - in_parallel: - put: ci-image params: @@ -625,8 +626,6 @@ jobs: RELEASE_TYPE: M GITHUB_USERNAME: ((github-username)) GITHUB_TOKEN: ((github-ci-release-token)) - vars: - <<: *docker-hub-mirror-vars - put: github-pre-release params: name: generated-changelog/tag @@ -656,8 +655,6 @@ jobs: RELEASE_TYPE: RC GITHUB_USERNAME: ((github-username)) GITHUB_TOKEN: ((github-ci-release-token)) - vars: - <<: *docker-hub-mirror-vars - put: github-pre-release params: name: generated-changelog/tag @@ -717,8 +714,6 @@ jobs: RELEASE_TYPE: RELEASE GITHUB_USERNAME: ((github-username)) GITHUB_TOKEN: ((github-ci-release-token)) - vars: - <<: *docker-hub-mirror-vars - put: github-release params: name: generated-changelog/tag diff --git a/ci/scripts/detect-jdk-updates.sh b/ci/scripts/detect-jdk-updates.sh index 3d67c7773ea6..35929e94448c 100755 --- a/ci/scripts/detect-jdk-updates.sh +++ b/ci/scripts/detect-jdk-updates.sh @@ -43,7 +43,7 @@ if [[ $current = $latest ]]; then exit 0; fi -milestone_response=$( curl -s https://api.github.com/repos/${GITHUB_ORGANIZATION}/${GITHUB_REPO}/milestones\?state\=open ) +milestone_response=$( curl -s -u ${GITHUB_USERNAME}:${GITHUB_PASSWORD} https://api.github.com/repos/${GITHUB_ORGANIZATION}/${GITHUB_REPO}/milestones\?state\=open ) milestone_result=$( jq -r -c --arg MILESTONE "$MILESTONE" '.[] | select(has("title")) | select(.title==$MILESTONE)' <<< "$milestone_response" ) if [[ ${milestone_result} = "null" || ${milestone_result} = "" ]]; then echo "Could not parse milestone: $milestone_response" @@ -51,7 +51,7 @@ if [[ ${milestone_result} = "null" || ${milestone_result} = "" ]]; then fi milestone_number=$( jq -r '.number' <<< "$milestone_result" ) -existing_tasks=$( curl -s https://api.github.com/repos/${GITHUB_ORGANIZATION}/${GITHUB_REPO}/issues\?labels\=type:%20task\&state\=open\&creator\=spring-builds\&milestone\=${milestone_number} ) +existing_tasks=$( curl -u ${GITHUB_USERNAME}:${GITHUB_PASSWORD} -s https://api.github.com/repos/${GITHUB_ORGANIZATION}/${GITHUB_REPO}/issues\?labels\=type:%20task\&state\=open\&creator\=spring-builds\&milestone\=${milestone_number} ) existing_jdk_issues=$( jq -r -c --arg TITLE "$ISSUE_TITLE" '.[] | select(has("title")) | select(.title==$TITLE)' <<< "$existing_tasks" ) if [[ ${existing_jdk_issues} = "" ]]; then diff --git a/ci/scripts/detect-ubuntu-image-updates.sh b/ci/scripts/detect-ubuntu-image-updates.sh index 9557a5658f28..9bc34b9299d5 100755 --- a/ci/scripts/detect-ubuntu-image-updates.sh +++ b/ci/scripts/detect-ubuntu-image-updates.sh @@ -11,8 +11,8 @@ if [[ $current = $latest ]]; then exit 0; fi -milestone_number=$( curl -s https://api.github.com/repos/${GITHUB_ORGANIZATION}/${GITHUB_REPO}/milestones\?state\=open | jq -c --arg MILESTONE "$MILESTONE" '.[] | select(.title==$MILESTONE)' | jq -r '.number') -existing_tasks=$( curl -s https://api.github.com/repos/${GITHUB_ORGANIZATION}/${GITHUB_REPO}/issues\?labels\=type:%20task\&state\=open\&creator\=spring-builds\&milestone\=${milestone_number} ) +milestone_number=$( curl -u ${GITHUB_USERNAME}:${GITHUB_PASSWORD} -s https://api.github.com/repos/${GITHUB_ORGANIZATION}/${GITHUB_REPO}/milestones\?state\=open | jq -c --arg MILESTONE "$MILESTONE" '.[] | select(.title==$MILESTONE)' | jq -r '.number') +existing_tasks=$( curl -u ${GITHUB_USERNAME}:${GITHUB_PASSWORD} -s https://api.github.com/repos/${GITHUB_ORGANIZATION}/${GITHUB_REPO}/issues\?labels\=type:%20task\&state\=open\&creator\=spring-builds\&milestone\=${milestone_number} ) existing_upgrade_issues=$( echo "$existing_tasks" | jq -c --arg TITLE "$ISSUE_TITLE" '.[] | select(.title==$TITLE)' ) if [[ ${existing_upgrade_issues} = "" ]]; then diff --git a/ci/scripts/update-homebrew-tap.sh b/ci/scripts/update-homebrew-tap.sh index 591f5954139e..6c703eaf31bf 100755 --- a/ci/scripts/update-homebrew-tap.sh +++ b/ci/scripts/update-homebrew-tap.sh @@ -7,7 +7,7 @@ git clone homebrew-tap-repo updated-homebrew-tap-repo > /dev/null if [[ $LATEST_GA = true ]]; then pushd updated-homebrew-tap-repo > /dev/null - curl https://repo.spring.io/libs-release-local/org/springframework/boot/spring-boot-cli/${version}/spring-boot-cli-${version}-homebrew.rb --output spring-boot-cli-${version}-homebrew.rb + curl https://repo1.maven.org/maven2/org/springframework/boot/spring-boot-cli/${version}/spring-boot-cli-${version}-homebrew.rb --output spring-boot-cli-${version}-homebrew.rb rm spring-boot.rb mv spring-boot-cli-*.rb spring-boot.rb git config user.name "Spring Builds" > /dev/null diff --git a/ci/tasks/build-ci-image.yml b/ci/tasks/build-ci-image.yml index dcaa4a06b006..a49bd45f5d79 100644 --- a/ci/tasks/build-ci-image.yml +++ b/ci/tasks/build-ci-image.yml @@ -5,10 +5,8 @@ image_resource: source: repository: concourse/oci-build-task tag: 0.10.0 - registry_mirror: - host: ((docker-hub-mirror)) - username: ((docker-hub-mirror-username)) - password: ((docker-hub-mirror-password)) + username: ((docker-hub-username)) + password: ((docker-hub-password)) inputs: - name: ci-images-git-repo outputs: diff --git a/ci/tasks/build-project-windows.yml b/ci/tasks/build-project-windows.yml index 0dfadb95b717..817ee17482f6 100644 --- a/ci/tasks/build-project-windows.yml +++ b/ci/tasks/build-project-windows.yml @@ -8,6 +8,7 @@ params: BRANCH: CI: true GRADLE_ENTERPRISE_ACCESS_KEY: + GRADLE_ENTERPRISE_CACHE_URL: GRADLE_ENTERPRISE_CACHE_USERNAME: GRADLE_ENTERPRISE_CACHE_PASSWORD: GRADLE_ENTERPRISE_URL: https://ge.spring.io diff --git a/ci/tasks/build-project.yml b/ci/tasks/build-project.yml index b3e050d189ef..db3003af6e0c 100644 --- a/ci/tasks/build-project.yml +++ b/ci/tasks/build-project.yml @@ -12,6 +12,7 @@ params: BRANCH: CI: true GRADLE_ENTERPRISE_ACCESS_KEY: + GRADLE_ENTERPRISE_CACHE_URL: GRADLE_ENTERPRISE_CACHE_USERNAME: GRADLE_ENTERPRISE_CACHE_PASSWORD: GRADLE_ENTERPRISE_URL: https://ge.spring.io @@ -19,8 +20,12 @@ params: run: path: bash args: - - -ec - - | - source /docker-lib.sh - start_docker $DOCKER_HUB_MIRROR - ${PWD}/git-repo/ci/scripts/build-project.sh + - "-ec" + - | + mkdir -p /root/.docker + cat > /root/.docker/config.json < Initialize JDT's package explorer to show working sets as its root objects + + <?xml version="1.0" encoding="UTF-8"?> + <section name="Workbench"> + <section name="org.eclipse.jdt.internal.ui.packageview.PackageExplorerPart"> + <item value="true" key="group_libraries"/> + <item value="false" key="linkWithEditor"/> + <item value="2" key="layout"/> + <item value="2" key="rootMode"/> + <item value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#x0D;&#x0A;&lt;packageExplorer configured=&quot;true&quot; group_libraries=&quot;1&quot; layout=&quot;2&quot; linkWithEditor=&quot;0&quot; rootMode=&quot;2&quot; sortWorkingSets=&quot;false&quot; workingSetName=&quot;&quot;&gt;&#x0D;&#x0A;&lt;localWorkingSetManager&gt;&#x0D;&#x0A;&lt;workingSet editPageId=&quot;org.eclipse.jdt.internal.ui.OthersWorkingSet&quot; factoryID=&quot;org.eclipse.ui.internal.WorkingSetFactory&quot; id=&quot;1382792884467_1&quot; label=&quot;Other Projects&quot; name=&quot;Other Projects&quot;/&gt;&#x0D;&#x0A;&lt;/localWorkingSetManager&gt;&#x0D;&#x0A;&lt;activeWorkingSet workingSetName=&quot;Other Projects&quot;/&gt;&#x0D;&#x0A;&lt;allWorkingSets workingSetName=&quot;Other Projects&quot;/&gt;&#x0D;&#x0A;&lt;/packageExplorer&gt;" key="memento"/> + </section> + </section> + + @@ -78,8 +90,6 @@ name="org.eclipse.wst.server_adapters.feature.feature.group"/> - + url="https://repo.maven.apache.org/maven2/.m2e/connectors/m2eclipse-buildhelper/0.15.0/N/0.15.0.201405280027/"/> + xsi:type="oomph:GradleImportTask" + javaHome="${jre.location-1.8}"> + + + + excludedWorkingSet="//@setupTasks.8/@workingSets[name='spring-boot-smoke-tests'] //@setupTasks.8/@workingSets[name='spring-boot-starters'] //@setupTasks.8/@workingSets[name='spring-boot-tests'] //@setupTasks.8/@workingSets[name='spring-boot-tools']"/> + excludedWorkingSet="//@setupTasks.8/@workingSets[name='spring-boot-smoke-tests']"/> diff --git a/spring-boot-project/spring-boot-cli/src/main/homebrew/spring-boot.rb b/spring-boot-project/spring-boot-cli/src/main/homebrew/spring-boot.rb index e802190723e7..b3973befc939 100644 --- a/spring-boot-project/spring-boot-cli/src/main/homebrew/spring-boot.rb +++ b/spring-boot-project/spring-boot-cli/src/main/homebrew/spring-boot.rb @@ -2,7 +2,7 @@ class SpringBoot < Formula homepage 'https://spring.io/projects/spring-boot' - url 'https://repo.spring.io/${repo}/org/springframework/boot/spring-boot-cli/${project.version}/spring-boot-cli-${project.version}-bin.tar.gz' + url '${repo}/org/springframework/boot/spring-boot-cli/${project.version}/spring-boot-cli-${project.version}-bin.tar.gz' version '${project.version}' sha256 '${hash}' head 'https://github.com/spring-projects/spring-boot.git' diff --git a/spring-boot-project/spring-boot-cli/src/main/scoop/springboot.json b/spring-boot-project/spring-boot-cli/src/main/scoop/springboot.json index dbfe2308cc14..d49cacca6de8 100644 --- a/spring-boot-project/spring-boot-cli/src/main/scoop/springboot.json +++ b/spring-boot-project/spring-boot-cli/src/main/scoop/springboot.json @@ -3,7 +3,7 @@ "version": "${scoopVersion}", "license": "Apache 2.0", "hash": "${hash}", - "url": "https://repo.spring.io/${repo}/org/springframework/boot/spring-boot-cli/${project.version}/spring-boot-cli-${project.version}-bin.zip", + "url": "${repo}/org/springframework/boot/spring-boot-cli/${project.version}/spring-boot-cli-${project.version}-bin.zip", "extract_dir": "spring-${project.version}", "bin": "bin\\\\spring.bat", "suggest": { diff --git a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/grape/MavenResolverGrapeEngineTests.java b/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/grape/MavenResolverGrapeEngineTests.java index 8d9d7fb4eb1e..13c02f51a4e7 100644 --- a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/grape/MavenResolverGrapeEngineTests.java +++ b/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/grape/MavenResolverGrapeEngineTests.java @@ -57,7 +57,7 @@ class MavenResolverGrapeEngineTests { private GrapeEngine createGrapeEngine(RepositoryConfiguration... additionalRepositories) { List repositoryConfigurations = new ArrayList<>(); repositoryConfigurations - .add(new RepositoryConfiguration("central", URI.create("https://repo1.maven.org/maven2"), false)); + .add(new RepositoryConfiguration("central", URI.create("https://repo.maven.apache.org/maven2"), false)); repositoryConfigurations.addAll(Arrays.asList(additionalRepositories)); DependencyResolutionContext dependencyResolutionContext = new DependencyResolutionContext(); dependencyResolutionContext.addDependencyManagement(new SpringBootDependenciesDependencyManagement()); diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/attributes.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/attributes.adoc index 954b2efb593c..43a2ecab9987 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/attributes.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/attributes.adoc @@ -11,7 +11,7 @@ :docinfo: shared,private :attribute-missing: warn :chomp: default headers packages -:spring-boot-artifactory-repo: snapshot +:artifact-release-type: snapshot :github-tag: main :spring-boot-version: current :github-repo: spring-projects/spring-boot diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/getting-started/first-application.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/getting-started/first-application.adoc index e5bf793229b5..1091289e21bd 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/getting-started/first-application.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/getting-started/first-application.adoc @@ -61,8 +61,8 @@ Open your favorite text editor and add the following: -ifeval::["{spring-boot-artifactory-repo}" != "release"] - +ifeval::["{artifact-release-type}" != "release"] + spring-snapshots diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/getting-started/installing.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/getting-started/installing.adoc index 0ad32e14b67b..4f4f83555173 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/getting-started/installing.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/getting-started/installing.adoc @@ -74,13 +74,16 @@ You do not need to use the CLI to work with Spring Boot, but it is a quick way t [[getting-started.installing.cli.manual-installation]] ==== Manual Installation -You can download the Spring CLI distribution from the Spring software repository: +ifeval::["{artifact-release-type}" == "snapshot"] +You can download one of the `spring-boot-cli-\*-bin.zip` or `spring-boot-cli-*-bin.tar.gz` files from the {artifact-download-repo}/org/springframework/boot/spring-boot-cli/{spring-boot-version}/[Spring software repository]. +endif::[] +ifeval::["{artifact-release-type}" != "snapshot"] +You can download the Spring CLI distribution from one of the following locations: -* https://repo.spring.io/{spring-boot-artifactory-repo}/org/springframework/boot/spring-boot-cli/{spring-boot-version}/spring-boot-cli-{spring-boot-version}-bin.zip[spring-boot-cli-{spring-boot-version}-bin.zip] -* https://repo.spring.io/{spring-boot-artifactory-repo}/org/springframework/boot/spring-boot-cli/{spring-boot-version}/spring-boot-cli-{spring-boot-version}-bin.tar.gz[spring-boot-cli-{spring-boot-version}-bin.tar.gz] +* {artifact-download-repo}/org/springframework/boot/spring-boot-cli/{spring-boot-version}/spring-boot-cli-{spring-boot-version}-bin.zip[spring-boot-cli-{spring-boot-version}-bin.zip] +* {artifact-download-repo}/org/springframework/boot/spring-boot-cli/{spring-boot-version}/spring-boot-cli-{spring-boot-version}-bin.tar.gz[spring-boot-cli-{spring-boot-version}-bin.tar.gz] +endif::[] -Cutting edge -https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-cli/[snapshot distributions] are also available. Once downloaded, follow the {github-raw}/spring-boot-project/spring-boot-cli/src/main/content/INSTALL.txt[INSTALL.txt] instructions from the unpacked archive. In summary, there is a `spring` script (`spring.bat` for Windows) in a `bin/` directory in the `.zip` file. diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/getting-started.adoc b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/getting-started.adoc index 2c5d3dd5df42..5828e3b8d932 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/getting-started.adoc +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/getting-started.adoc @@ -2,7 +2,7 @@ = Getting Started To get started with the plugin it needs to be applied to your project. -ifeval::["{spring-boot-artifactory-repo}" == "release"] +ifeval::["{artifact-release-type}" == "release"] The plugin is https://plugins.gradle.org/plugin/org.springframework.boot[published to Gradle's plugin portal] and can be applied using the `plugins` block: [source,groovy,indent=0,subs="verbatim,attributes",role="primary"] .Groovy @@ -16,7 +16,7 @@ include::../gradle/getting-started/apply-plugin-release.gradle[] include::../gradle/getting-started/apply-plugin-release.gradle.kts[] ---- endif::[] -ifeval::["{spring-boot-artifactory-repo}" == "milestone"] +ifeval::["{artifact-release-type}" == "milestone"] The plugin is published to the Spring milestones repository. Gradle can be configured to use the milestones repository and the plugin can then be applied using the `plugins` block. To configure Gradle to use the milestones repository, add the following to your `settings.gradle` (Groovy) or `settings.gradle.kts` (Kotlin): @@ -47,7 +47,7 @@ include::../gradle/getting-started/apply-plugin-release.gradle[] include::../gradle/getting-started/apply-plugin-release.gradle.kts[] ---- endif::[] -ifeval::["{spring-boot-artifactory-repo}" == "snapshot"] +ifeval::["{artifact-release-type}" == "snapshot"] The plugin is published to the Spring snapshots repository. Gradle can be configured to use the snapshots repository and the plugin can then be applied using the `plugins` block. To configure Gradle to use the snapshots repository, add the following to your `settings.gradle` (Groovy) or `settings.gradle.kts` (Kotlin): diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/managing-dependencies.adoc b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/managing-dependencies.adoc index 68d42db0001d..0b6be6238f87 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/managing-dependencies.adoc +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/managing-dependencies.adoc @@ -58,7 +58,7 @@ The `SpringBootPlugin` class provides a `BOM_COORDINATES` constant that can be u First, configure the project to depend on the Spring Boot plugin but do not apply it: -ifeval::["{spring-boot-artifactory-repo}" == "release"] +ifeval::["{artifact-release-type}" == "release"] [source,groovy,indent=0,subs="verbatim,attributes",role="primary"] .Groovy ---- @@ -71,7 +71,7 @@ include::../gradle/managing-dependencies/depend-on-plugin-release.gradle[] include::../gradle/managing-dependencies/depend-on-plugin-release.gradle.kts[] ---- endif::[] -ifeval::["{spring-boot-artifactory-repo}" == "milestone"] +ifeval::["{artifact-release-type}" == "milestone"] [source,groovy,indent=0,subs="verbatim,attributes",role="primary"] .Groovy ---- @@ -83,7 +83,7 @@ include::../gradle/managing-dependencies/depend-on-plugin-milestone.gradle[] include::../gradle/managing-dependencies/depend-on-plugin-release.gradle.kts[] ---- endif::[] -ifeval::["{spring-boot-artifactory-repo}" == "snapshot"] +ifeval::["{artifact-release-type}" == "snapshot"] [source,groovy,indent=0,subs="verbatim,attributes",role="primary"] .Groovy ---- From 4eef8d5a5351ee97005aea4b746f3117d9cddbec Mon Sep 17 00:00:00 2001 From: Moritz Halbritter Date: Wed, 10 May 2023 09:20:10 +0200 Subject: [PATCH 058/163] Separate tag in the Docker API tag call Closes gh-35358 --- .../buildpack/platform/docker/DockerApi.java | 11 +++++++- .../platform/docker/type/ImageReference.java | 14 +++++++++- .../platform/docker/DockerApiTests.java | 13 +++++++++- .../docker/type/ImageReferenceTests.java | 26 +++++++++++++++++++ 4 files changed, 61 insertions(+), 3 deletions(-) diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/DockerApi.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/DockerApi.java index eee724006b96..0f806c8b6ddb 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/DockerApi.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/DockerApi.java @@ -65,6 +65,7 @@ * @author Phillip Webb * @author Scott Frederick * @author Rafael Ceccone + * @author Moritz Halbritter * @since 2.3.0 */ public class DockerApi { @@ -346,7 +347,15 @@ public Image inspect(ImageReference reference) throws IOException { public void tag(ImageReference sourceReference, ImageReference targetReference) throws IOException { Assert.notNull(sourceReference, "SourceReference must not be null"); Assert.notNull(targetReference, "TargetReference must not be null"); - URI uri = buildUrl("/images/" + sourceReference + "/tag", "repo", targetReference.toString()); + String tag = targetReference.getTag(); + URI uri; + if (tag == null) { + uri = buildUrl("/images/" + sourceReference + "/tag", "repo", targetReference.toString()); + } + else { + uri = buildUrl("/images/" + sourceReference + "/tag", "repo", + targetReference.inTaglessForm().toString(), "tag", tag); + } http().post(uri).close(); } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/type/ImageReference.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/type/ImageReference.java index c2a3d7aae08d..3f07f53166e1 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/type/ImageReference.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/type/ImageReference.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,6 +28,7 @@ * * @author Phillip Webb * @author Scott Frederick + * @author Moritz Halbritter * @since 2.3.0 * @see ImageName */ @@ -153,6 +154,17 @@ public ImageReference inTaggedForm() { return new ImageReference(this.name, (this.tag != null) ? this.tag : LATEST, null); } + /** + * Return an {@link ImageReference} without the tag. + * @return the image reference in tagless form + */ + public ImageReference inTaglessForm() { + if (this.tag == null) { + return this; + } + return new ImageReference(this.name, null, this.digest); + } + /** * Return an {@link ImageReference} containing either a tag or a digest. If neither * the digest nor the tag has been defined then tag {@code latest} is used. diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/DockerApiTests.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/DockerApiTests.java index 8410e401b7e4..f974129c89f0 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/DockerApiTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/DockerApiTests.java @@ -75,6 +75,7 @@ * @author Phillip Webb * @author Scott Frederick * @author Rafael Ceccone + * @author Moritz Halbritter */ @ExtendWith(MockitoExtension.class) class DockerApiTests { @@ -419,7 +420,17 @@ void tagWhenTargetIsNullThrowsException() { void tagTagsImage() throws Exception { ImageReference sourceReference = ImageReference.of("localhost:5000/ubuntu"); ImageReference targetReference = ImageReference.of("localhost:5000/ubuntu:tagged"); - URI tagURI = new URI(IMAGES_URL + "/localhost:5000/ubuntu/tag?repo=localhost%3A5000%2Fubuntu%3Atagged"); + URI tagURI = new URI(IMAGES_URL + "/localhost:5000/ubuntu/tag?repo=localhost%3A5000%2Fubuntu&tag=tagged"); + given(http().post(tagURI)).willReturn(emptyResponse()); + this.api.tag(sourceReference, targetReference); + then(http()).should().post(tagURI); + } + + @Test + void tagRenamesImage() throws Exception { + ImageReference sourceReference = ImageReference.of("localhost:5000/ubuntu"); + ImageReference targetReference = ImageReference.of("localhost:5000/ubuntu-2"); + URI tagURI = new URI(IMAGES_URL + "/localhost:5000/ubuntu/tag?repo=localhost%3A5000%2Fubuntu-2"); given(http().post(tagURI)).willReturn(emptyResponse()); this.api.tag(sourceReference, targetReference); then(http()).should().post(tagURI); diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/type/ImageReferenceTests.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/type/ImageReferenceTests.java index b5ad72e1ef7d..7c0c7918e827 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/type/ImageReferenceTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/type/ImageReferenceTests.java @@ -29,6 +29,7 @@ * * @author Phillip Webb * @author Scott Frederick + * @author Moritz Halbritter */ class ImageReferenceTests { @@ -272,4 +273,29 @@ void equalsAndHashCode() { assertThat(r1).isEqualTo(r1).isEqualTo(r2).isNotEqualTo(r3); } + @Test + void withDigest() { + ImageReference reference = ImageReference.of("docker.io/library/ubuntu:bionic"); + ImageReference updated = reference + .withDigest("sha256:6e9f67fa63b0323e9a1e587fd71c561ba48a034504fb804fd26fd8800039835d"); + assertThat(updated).hasToString( + "docker.io/library/ubuntu@sha256:6e9f67fa63b0323e9a1e587fd71c561ba48a034504fb804fd26fd8800039835d"); + } + + @Test + void inTaglessFormWithDigest() { + ImageReference reference = ImageReference + .of("docker.io/library/ubuntu@sha256:6e9f67fa63b0323e9a1e587fd71c561ba48a034504fb804fd26fd8800039835d"); + ImageReference updated = reference.inTaglessForm(); + assertThat(updated).hasToString( + "docker.io/library/ubuntu@sha256:6e9f67fa63b0323e9a1e587fd71c561ba48a034504fb804fd26fd8800039835d"); + } + + @Test + void inTaglessForm() { + ImageReference reference = ImageReference.of("docker.io/library/ubuntu:bionic"); + ImageReference updated = reference.inTaglessForm(); + assertThat(updated).hasToString("docker.io/library/ubuntu"); + } + } From 912cd8378288d54df12b746424d9790dde1a76dc Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Thu, 11 May 2023 14:10:04 +0200 Subject: [PATCH 059/163] Revert "Start building against Spring Framework 5.3.28 snapshots" This reverts commit 546c0e0aafbd34091051fda090add68cfc35597c. See gh-35293 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 2030424da7b4..284895299a2f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ org.gradle.parallel=true org.gradle.jvmargs=-Xmx2g -Dfile.encoding=UTF-8 kotlinVersion=1.6.21 -springFrameworkVersion=5.3.28-SNAPSHOT +springFrameworkVersion=5.3.27 tomcatVersion=9.0.74 kotlin.stdlib.default.dependency=false From 9f55d5de186517a3e033f5a93af19d84f4edfab7 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 11 May 2023 18:14:35 +0100 Subject: [PATCH 060/163] Revert "Start building against Spring WS 3.1.7 snapshots" This reverts commit 2b03e51a192d0c8ac8e1698911356f4db3619e31. See gh-35295 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index da4dbe886105..8fb36a890a5f 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1854,7 +1854,7 @@ bom { ] } } - library("Spring WS", "3.1.7-SNAPSHOT") { + library("Spring WS", "3.1.6") { prohibit { versionRange "[4.0.0-M1,)" because "it uses Spring Framework 6" From 700e89097ce1a553835b58e09b362d94b30a2a33 Mon Sep 17 00:00:00 2001 From: Moritz Halbritter Date: Fri, 12 May 2023 11:57:33 +0200 Subject: [PATCH 061/163] Polish See https://stackoverflow.com/questions/28671903/the-hashsett-removeall-method-is-surprisingly-slow --- .../classpath/CheckClasspathForUnnecessaryExclusions.java | 6 ++---- .../autoconfigure/condition/ConditionEvaluationReport.java | 4 ++-- .../boot/web/error/ErrorAttributeOptions.java | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/buildSrc/src/main/java/org/springframework/boot/build/classpath/CheckClasspathForUnnecessaryExclusions.java b/buildSrc/src/main/java/org/springframework/boot/build/classpath/CheckClasspathForUnnecessaryExclusions.java index 6ea9aa3dc95e..13b50991a547 100644 --- a/buildSrc/src/main/java/org/springframework/boot/build/classpath/CheckClasspathForUnnecessaryExclusions.java +++ b/buildSrc/src/main/java/org/springframework/boot/build/classpath/CheckClasspathForUnnecessaryExclusions.java @@ -18,7 +18,6 @@ import java.util.Collections; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; @@ -107,14 +106,13 @@ public void checkForUnnecessaryExclusions() { this.exclusionsByDependencyId.forEach((dependencyId, exclusions) -> { if (!exclusions.isEmpty()) { Dependency toCheck = this.dependencyById.get(dependencyId); - List dependencies = this.configurations.detachedConfiguration(toCheck, this.platform) + this.configurations.detachedConfiguration(toCheck, this.platform) .getIncoming() .getArtifacts() .getArtifacts() .stream() .map(this::getId) - .collect(Collectors.toList()); - exclusions.removeAll(dependencies); + .forEach(exclusions::remove); removeProfileExclusions(dependencyId, exclusions); if (!exclusions.isEmpty()) { unnecessaryExclusions.put(dependencyId, exclusions); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionEvaluationReport.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionEvaluationReport.java index 4a945908f2d6..cb987b1af3a9 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionEvaluationReport.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionEvaluationReport.java @@ -147,7 +147,7 @@ public List getExclusions() { */ public Set getUnconditionalClasses() { Set filtered = new HashSet<>(this.unconditionalClasses); - filtered.removeAll(this.exclusions); + this.exclusions.forEach(filtered::remove); return Collections.unmodifiableSet(filtered); } @@ -166,7 +166,7 @@ public ConditionEvaluationReport getParent() { * @return the {@link ConditionEvaluationReport} or {@code null} */ public static ConditionEvaluationReport find(BeanFactory beanFactory) { - if (beanFactory != null && beanFactory instanceof ConfigurableListableBeanFactory) { + if (beanFactory instanceof ConfigurableListableBeanFactory) { return ConditionEvaluationReport.get((ConfigurableListableBeanFactory) beanFactory); } return null; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/error/ErrorAttributeOptions.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/error/ErrorAttributeOptions.java index 707a889be10d..ecf1ddc862ce 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/error/ErrorAttributeOptions.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/error/ErrorAttributeOptions.java @@ -75,7 +75,7 @@ public ErrorAttributeOptions including(Include... includes) { */ public ErrorAttributeOptions excluding(Include... excludes) { EnumSet updated = copyIncludes(); - updated.removeAll(Arrays.asList(excludes)); + Arrays.stream(excludes).forEach(updated::remove); return new ErrorAttributeOptions(Collections.unmodifiableSet(updated)); } From 585286e4720f337a59de173f6a8837fada724024 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Fri, 12 May 2023 09:39:27 -0700 Subject: [PATCH 062/163] Revert "Resolve errors in layers.xsd" for 2.5 Revert layers.xsd fix to reduce risk of a regression since it has not yet made it into a 2.5 release. This reverts commit f185b0767a71c2c326769bafea5966b677d6be00, reversing changes made to bf3c6dfdba595f81722cd904723532a2593b7ca5. See gh-31126 --- .../spring-boot-maven-plugin/build.gradle | 17 ++-------- .../boot/maven/AbstractPackagerMojo.java | 3 +- .../boot/maven/CustomLayersProvider.java | 32 +------------------ .../src/main/xsd/layers-2.3.xsd | 6 ++-- .../src/main/xsd/layers-2.4.xsd | 10 +++--- .../src/main/xsd/layers-2.5.xsd | 10 +++--- .../boot/maven/CustomLayersProviderTests.java | 3 +- 7 files changed, 18 insertions(+), 63 deletions(-) diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/build.gradle b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/build.gradle index f220f448ebd9..a8e7b881fb10 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/build.gradle +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/build.gradle @@ -64,11 +64,6 @@ dependencies { versionProperties(project(path: ":spring-boot-project:spring-boot-dependencies", configuration: "effectiveBom")) } -ext { - versionElements = version.split("\\.") - xsdVersion = versionElements[0] + "." + versionElements[1] -} - syncDocumentationSourceForAsciidoctor { from(documentPluginGoals) { into "asciidoc/goals" @@ -76,9 +71,6 @@ syncDocumentationSourceForAsciidoctor { } sourceSets { - main { - output.dir("${buildDir}/generated/resources/xsd", builtBy: "xsdResources") - } intTest { output.dir("${buildDir}/generated-resources", builtBy: "extractVersionProperties") } @@ -86,7 +78,8 @@ sourceSets { tasks.withType(org.asciidoctor.gradle.jvm.AbstractAsciidoctorTask) { doFirst { - attributes "spring-boot-xsd-version" : project.ext.xsdVersion + def versionEl = version.split("\\.") + attributes "spring-boot-xsd-version": versionEl[0] + '.' + versionEl[1] } } @@ -136,12 +129,6 @@ task zip(type: Zip) { } } -task xsdResources(type: Sync) { - from "src/main/xsd/layers-${project.ext.xsdVersion}.xsd" - into "${buildDir}/generated/resources/xsd/org/springframework/boot/maven" - rename { fileName -> "layers.xsd" } -} - prepareMavenBinaries { versions "3.8.1", "3.6.3", "3.5.4" } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractPackagerMojo.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractPackagerMojo.java index 82ff6455e40f..3ce19bf4c105 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractPackagerMojo.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractPackagerMojo.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -171,7 +171,6 @@ private CustomLayers getCustomLayers(File configuration) { private Document getDocumentIfAvailable(File xmlFile) throws Exception { InputSource inputSource = new InputSource(new FileInputStream(xmlFile)); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - factory.setNamespaceAware(true); DocumentBuilder builder = factory.newDocumentBuilder(); return builder.parse(inputSource); } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/CustomLayersProvider.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/CustomLayersProvider.java index 2889520bd400..5d01b34caa95 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/CustomLayersProvider.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/CustomLayersProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,24 +16,16 @@ package org.springframework.boot.maven; -import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.function.Function; import java.util.stream.Collectors; -import javax.xml.XMLConstants; -import javax.xml.transform.dom.DOMSource; -import javax.xml.validation.Schema; -import javax.xml.validation.SchemaFactory; -import javax.xml.validation.Validator; - import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; -import org.xml.sax.SAXException; import org.springframework.boot.loader.tools.Layer; import org.springframework.boot.loader.tools.Library; @@ -53,7 +45,6 @@ class CustomLayersProvider { CustomLayers getLayers(Document document) { - validate(document); Element root = document.getDocumentElement(); List> applicationSelectors = getApplicationSelectors(root); List> librarySelectors = getLibrarySelectors(root); @@ -61,27 +52,6 @@ CustomLayers getLayers(Document document) { return new CustomLayers(layers, applicationSelectors, librarySelectors); } - private void validate(Document document) { - Schema schema = loadSchema(); - try { - Validator validator = schema.newValidator(); - validator.validate(new DOMSource(document)); - } - catch (SAXException | IOException ex) { - throw new IllegalStateException("Invalid layers.xml configuration", ex); - } - } - - private Schema loadSchema() { - try { - SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); - return factory.newSchema(getClass().getResource("layers.xsd")); - } - catch (SAXException ex) { - throw new IllegalStateException("Unable to load layers XSD"); - } - } - private List> getApplicationSelectors(Element root) { return getSelectors(root, "application", (element) -> getSelector(element, ApplicationContentFilter::new)); } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/xsd/layers-2.3.xsd b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/xsd/layers-2.3.xsd index c5c68586516d..01eca01439c9 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/xsd/layers-2.3.xsd +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/xsd/layers-2.3.xsd @@ -6,9 +6,9 @@ - - - + + + diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/xsd/layers-2.4.xsd b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/xsd/layers-2.4.xsd index 20219b9bd8b1..e793e2e0080b 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/xsd/layers-2.4.xsd +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/xsd/layers-2.4.xsd @@ -6,9 +6,9 @@ - - - + + + @@ -78,14 +78,14 @@ - + - + - - - + + + @@ -78,14 +78,14 @@ - + - + Date: Fri, 12 May 2023 13:00:38 -0700 Subject: [PATCH 063/163] Polish --- .../actuate/mail/MailHealthIndicator.java | 4 ++-- .../autoconfigure/r2dbc/R2dbcProperties.java | 4 ---- .../buildpack/platform/docker/DockerApi.java | 24 ++++++++----------- 3 files changed, 12 insertions(+), 20 deletions(-) diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/mail/MailHealthIndicator.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/mail/MailHealthIndicator.java index 08da5072a5b2..afd67045f7fe 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/mail/MailHealthIndicator.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/mail/MailHealthIndicator.java @@ -39,8 +39,8 @@ public MailHealthIndicator(JavaMailSenderImpl mailSender) { @Override protected void doHealthCheck(Builder builder) throws Exception { int port = this.mailSender.getPort(); - builder.withDetail("location", (port == JavaMailSenderImpl.DEFAULT_PORT) ? this.mailSender.getHost() - : this.mailSender.getHost() + ":" + this.mailSender.getPort()); + builder.withDetail("location", (port != JavaMailSenderImpl.DEFAULT_PORT) + ? this.mailSender.getHost() + ":" + this.mailSender.getPort() : this.mailSender.getHost()); this.mailSender.testConnection(); builder.up(); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcProperties.java index fb662fba6908..e07b1dd0a06c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcProperties.java @@ -138,8 +138,6 @@ public static class Pool { /** * Minimal number of idle connections. - * - * @since 2.7.12 */ private int minIdle = 0; @@ -163,8 +161,6 @@ public static class Pool { /** * Maximum time to validate a connection from the pool. By default, wait * indefinitely. - * - * @since 2.7.12 */ private Duration maxValidationTime; diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/DockerApi.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/DockerApi.java index 0f806c8b6ddb..8073cba7956f 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/DockerApi.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/DockerApi.java @@ -33,6 +33,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.stream.Collectors; import org.apache.commons.compress.archivers.tar.TarArchiveEntry; @@ -121,16 +122,16 @@ private JsonStream jsonStream() { return this.jsonStream; } - private URI buildUrl(String path, Collection params) { - return buildUrl(path, StringUtils.toStringArray(params)); + private URI buildUrl(String path, Collection params) { + return buildUrl(path, (params != null) ? params.toArray() : null); } - private URI buildUrl(String path, String... params) { + private URI buildUrl(String path, Object... params) { try { URIBuilder builder = new URIBuilder("/" + API_VERSION + path); int param = 0; while (param < params.length) { - builder.addParameter(params[param++], params[param++]); + builder.addParameter(Objects.toString(params[param++]), Objects.toString(params[param++])); } return builder.build(); } @@ -190,7 +191,7 @@ public Image pull(ImageReference reference, UpdateListener throws IOException { Assert.notNull(reference, "Reference must not be null"); Assert.notNull(listener, "Listener must not be null"); - URI createUri = buildUrl("/images/create", "fromImage", reference.toString()); + URI createUri = buildUrl("/images/create", "fromImage", reference); DigestCaptureUpdateListener digestCapture = new DigestCaptureUpdateListener(); listener.onStart(); try { @@ -348,14 +349,9 @@ public void tag(ImageReference sourceReference, ImageReference targetReference) Assert.notNull(sourceReference, "SourceReference must not be null"); Assert.notNull(targetReference, "TargetReference must not be null"); String tag = targetReference.getTag(); - URI uri; - if (tag == null) { - uri = buildUrl("/images/" + sourceReference + "/tag", "repo", targetReference.toString()); - } - else { - uri = buildUrl("/images/" + sourceReference + "/tag", "repo", - targetReference.inTaglessForm().toString(), "tag", tag); - } + String path = "/images/" + sourceReference + "/tag"; + URI uri = (tag != null) ? buildUrl(path, "repo", targetReference.inTaglessForm(), "tag", tag) + : buildUrl(path, "repo", targetReference); http().post(uri).close(); } @@ -437,7 +433,7 @@ public void start(ContainerReference reference) throws IOException { public void logs(ContainerReference reference, UpdateListener listener) throws IOException { Assert.notNull(reference, "Reference must not be null"); Assert.notNull(listener, "Listener must not be null"); - String[] params = { "stdout", "1", "stderr", "1", "follow", "1" }; + Object[] params = { "stdout", "1", "stderr", "1", "follow", "1" }; URI uri = buildUrl("/containers/" + reference + "/logs", params); listener.onStart(); try { From ef4b09718c4126ecc63a9d91a369a2c297661123 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Fri, 12 May 2023 12:57:56 -0700 Subject: [PATCH 064/163] Fix loading of PKCS#8 PEM encoded EC and DSA keys for buildpack Polish and port support for PKCS#8 PEM encoded EC and DSA keys to the buildpack code. See gh-35322 --- .../platform/docker/ssl/PrivateKeyParser.java | 29 ++++--- .../platform/docker/ssl/PemFileWriter.java | 85 +++++++++++++++---- .../docker/ssl/PrivateKeyParserTests.java | 27 +++++- .../boot/web/server/PrivateKeyParser.java | 21 ++--- 4 files changed, 121 insertions(+), 41 deletions(-) diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/ssl/PrivateKeyParser.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/ssl/PrivateKeyParser.java index 002791a88de9..693919864380 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/ssl/PrivateKeyParser.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/ssl/PrivateKeyParser.java @@ -24,6 +24,7 @@ import java.security.GeneralSecurityException; import java.security.KeyFactory; import java.security.PrivateKey; +import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.util.ArrayList; import java.util.Collections; @@ -39,6 +40,7 @@ * * @author Scott Frederick * @author Phillip Webb + * @author Moritz Halbritter */ final class PrivateKeyParser { @@ -59,9 +61,9 @@ final class PrivateKeyParser { private static final List PEM_PARSERS; static { List parsers = new ArrayList<>(); - parsers.add(new PemParser(PKCS1_HEADER, PKCS1_FOOTER, "RSA", PrivateKeyParser::createKeySpecForPkcs1)); - parsers.add(new PemParser(EC_HEADER, EC_FOOTER, "EC", PrivateKeyParser::createKeySpecForEc)); - parsers.add(new PemParser(PKCS8_HEADER, PKCS8_FOOTER, "RSA", PKCS8EncodedKeySpec::new)); + parsers.add(new PemParser(PKCS1_HEADER, PKCS1_FOOTER, PrivateKeyParser::createKeySpecForPkcs1, "RSA")); + parsers.add(new PemParser(EC_HEADER, EC_FOOTER, PrivateKeyParser::createKeySpecForEc, "EC")); + parsers.add(new PemParser(PKCS8_HEADER, PKCS8_FOOTER, PKCS8EncodedKeySpec::new, "RSA", "EC", "DSA")); PEM_PARSERS = Collections.unmodifiableList(parsers); } @@ -141,14 +143,14 @@ private static class PemParser { private final Pattern pattern; - private final String algorithm; - private final Function keySpecFactory; - PemParser(String header, String footer, String algorithm, - Function keySpecFactory) { + private final String[] algorithms; + + PemParser(String header, String footer, Function keySpecFactory, + String... algorithms) { this.pattern = Pattern.compile(header + BASE64_TEXT + footer, Pattern.CASE_INSENSITIVE); - this.algorithm = algorithm; + this.algorithms = algorithms; this.keySpecFactory = keySpecFactory; } @@ -165,8 +167,15 @@ private static byte[] decodeBase64(String content) { private PrivateKey parse(byte[] bytes) { try { PKCS8EncodedKeySpec keySpec = this.keySpecFactory.apply(bytes); - KeyFactory keyFactory = KeyFactory.getInstance(this.algorithm); - return keyFactory.generatePrivate(keySpec); + for (String algorithm : this.algorithms) { + KeyFactory keyFactory = KeyFactory.getInstance(algorithm); + try { + return keyFactory.generatePrivate(keySpec); + } + catch (InvalidKeySpecException ex) { + } + } + return null; } catch (GeneralSecurityException ex) { throw new IllegalArgumentException("Unexpected key format", ex); diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/ssl/PemFileWriter.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/ssl/PemFileWriter.java index 05888b14401f..c5b458ab6ffb 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/ssl/PemFileWriter.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/ssl/PemFileWriter.java @@ -28,6 +28,7 @@ * Utility to write certificate and key PEM files for testing. * * @author Scott Frederick + * @author Moritz Halbritter */ public class PemFileWriter { @@ -49,22 +50,6 @@ public class PemFileWriter { + "zLEfeu6JPugAR71JYbc2CqGrMneSk1zT91EH6ohIz8OR5VNvzB7N7q65Ci7OFMPl\n" + "ly6k3rHpMCBtHoyNFhNVfPLxGJ9VlWFKLgIAbCmL4OIQm1l6Fr1MSM38Zw==\n" + "-----END TRUSTED CERTIFICATE-----\n"; - public static final String CA_PRIVATE_KEY = EXAMPLE_SECRET_QUALIFIER + "-----BEGIN PRIVATE KEY-----\n" - + "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANWM4sVhKMs63dtA\n" - + "tkdYI8jwqD3xS5RulGE8k9Lbnjcuso7+qmyfJXGYO+tejtyPS7jh4WYfVPnwgwoD\n" - + "34g3ciXwxFvz/nbDjBcjFFz6yT83tsj6Tp71fIieQzPd7nxFYQgssy3WLtD9j94V\n" - + "Nlvk9/yJvQwOxTjwNrxdUqyCdqrVAgMBAAECgYEAyJTlZ8nj3Eg1nLxCue6C5jmN\n" - + "fWkIuanH+zFAE/0utdxJ4WA4yYAOVo1MMr8FZwu9bzHTWe2yDnWnT5/ltPeHYX2X\n" - + "9Pg5cY0tjq07utaMwLKWgJ0Xoh2UpVM799t/rSvMWmLaZ2c8nipX+gQfYJFpX8Vg\n" - + "mR3QPxwdmNyFo13qif0CQQD4z2SqCfARuxscTCJDZ6wReikMQxaJvq74lPEtT26L\n" - + "rBr/bN+mG7+rMEHxs5wtU47aNjUKuVVC0Qfhsf95ahvHAkEA27inSlxrwGvhvFsD\n" - + "FWdgDsfYpPZdL4YgpVSEvcoypRGg2suJw2omcKcY56XpkmWUqZc06QirumtnEC0P\n" - + "HfnsgwJBAMVhEURrOc13FxytsQiz96atuF6H4htH79o3ndQKDXI0B/7VSd6maLjP\n" - + "QaESkTTL8qldE1r8h4zH8m6zHC4fZQUCQFWJ+8bdWC2fUlBr9jVc+26Fqvf92aVo\n" - + "yEjVMKBamYDd7gt/9fAX4UM2KmH0m4wc89VaQoT+lSyMJ6GKiToYVFUCQEXcyoeO\n" - + "zWqtSgEX/eXQXzmMKxYnjv1O//ba3Q7UiHd/XO5j4QXAJpcB6h0h00uC5KY2d0Zy\n" + "JQ1kB1C2l6l9tyc=\n" - + "-----END PRIVATE KEY-----"; - public static final String CERTIFICATE = "-----BEGIN CERTIFICATE-----\n" + "MIICjzCCAfgCAQEwDQYJKoZIhvcNAQEFBQAwgY8xCzAJBgNVBAYTAlVTMRMwEQYD\n" + "VQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMQ0wCwYDVQQK\n" @@ -101,6 +86,74 @@ public class PemFileWriter { + "AwEHoUQDQgAE8y28khug747bA68M90IAMCPHAYyen+RsN6i84LORpNDUhv00QZWd\n" + "hOhjWFCQjnewR98Y8pEb1fnORll4LhHPlQ==\n" + "-----END EC PRIVATE KEY-----"; + public static final String PRIVATE_DSA_KEY = EXAMPLE_SECRET_QUALIFIER + "-----BEGIN PRIVATE KEY-----\n" + + "MIICXAIBADCCAjUGByqGSM44BAEwggIoAoIBAQCPeTXZuarpv6vtiHrPSVG28y7F\n" + + "njuvNxjo6sSWHz79NgbnQ1GpxBgzObgJ58KuHFObp0dbhdARrbi0eYd1SYRpXKwO\n" + + "jxSzNggooi/6JxEKPWKpk0U0CaD+aWxGWPhL3SCBnDcJoBBXsZWtzQAjPbpUhLYp\n" + + "H51kjviDRIZ3l5zsBLQ0pqwudemYXeI9sCkvwRGMn/qdgYHnM423krcw17njSVkv\n" + + "aAmYchU5Feo9a4tGU8YzRY+AOzKkwuDycpAlbk4/ijsIOKHEUOThjBopo33fXqFD\n" + + "3ktm/wSQPtXPFiPhWNSHxgjpfyEc2B3KI8tuOAdl+CLjQr5ITAV2OTlgHNZnAh0A\n" + + "uvaWpoV499/e5/pnyXfHhe8ysjO65YDAvNVpXQKCAQAWplxYIEhQcE51AqOXVwQN\n" + + "NNo6NHjBVNTkpcAtJC7gT5bmHkvQkEq9rI837rHgnzGC0jyQQ8tkL4gAQWDt+coJ\n" + + "syB2p5wypifyRz6Rh5uixOdEvSCBVEy1W4AsNo0fqD7UielOD6BojjJCilx4xHjG\n" + + "jQUntxyaOrsLC+EsRGiWOefTznTbEBplqiuH9kxoJts+xy9LVZmDS7TtsC98kOmk\n" + + "ltOlXVNb6/xF1PYZ9j897buHOSXC8iTgdzEpbaiH7B5HSPh++1/et1SEMWsiMt7l\n" + + "U92vAhErDR8C2jCXMiT+J67ai51LKSLZuovjntnhA6Y8UoELxoi34u1DFuHvF9ve\n" + + "BB4CHHBQgJ3ST6U8rIxoTqGe42TiVckPf1PoSiJy8GY=\n" + "-----END PRIVATE KEY-----\n"; + + public static final String PKCS8_PRIVATE_EC_NIST_P256_KEY = EXAMPLE_SECRET_QUALIFIER + + "-----BEGIN PRIVATE KEY-----\n" + "MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgd6SePFfpaTKFd1Gm\n" + + "+WeHZNkORkot5hx6X9elPdICL9ygCgYIKoZIzj0DAQehRANCAASnMAMgeFBv9ks0\n" + + "d0jP+utQ3mohwmxY93xljfaBofdg1IeHgDd4I4pBzPxEnvXrU3kcz+SgPZyH1ybl\n" + "P6mSXDXu\n" + + "-----END PRIVATE KEY-----\n"; + + public static final String PKCS8_PRIVATE_EC_NIST_P384_KEY = EXAMPLE_SECRET_QUALIFIER + + "-----BEGIN PRIVATE KEY-----\n" + "MIG/AgEAMBAGByqGSM49AgEGBSuBBAAiBIGnMIGkAgEBBDCexXiWKrtrqV1+d1Tv\n" + + "t1n5huuw2A+204mQHRuPL9UC8l0XniJjx/PVELCciyJM/7+gBwYFK4EEACKhZANi\n" + + "AASHEELZSdrHiSXqU1B+/jrOCr6yjxCMqQsetTb0q5WZdCXOhggGXfbzlRynqphQ\n" + + "i4G7azBUklgLaXfxN5eFk6C+E38SYOR7iippcQsSR2ZsCiTk7rnur4b40gQ7IgLA\n" + "/sU=\n" + + "-----END PRIVATE KEY-----\n"; + + public static final String PKCS8_PRIVATE_EC_PRIME256V1_KEY = EXAMPLE_SECRET_QUALIFIER + + "-----BEGIN PRIVATE KEY-----\n" + "MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQg4dVuddgQ6enDvPPw\n" + + "Dd1mmS6FMm/kzTJjDVsltrNmRuSgCgYIKoZIzj0DAQehRANCAAR1WMrRADEaVj9m\n" + + "uoUfPhUefJK+lS89NHikQ0ZdkHkybyVKLFMLe1hCynhzpKQmnpgud3E10F0P2PZQ\n" + "L9RCEpGf\n" + + "-----END PRIVATE KEY-----\n"; + + public static final String PKCS8_PRIVATE_EC_SECP256R1_KEY = EXAMPLE_SECRET_QUALIFIER + + "-----BEGIN PRIVATE KEY-----\n" + "MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgU9+v5hUNnTKix8fe\n" + + "Pfz+NfXFlGxQZMReSCT2Id9PfKagCgYIKoZIzj0DAQehRANCAATeJg+YS4BrJ35A\n" + + "KgRlZ59yKLDpmENCMoaYUuWbQ9hqHzdybQGzQsrNJqgH0nzWghPwP4nFaLPN+pgB\n" + "bqiRgbjG\n" + + "-----END PRIVATE KEY-----\n"; + + public static final String PKCS8_PRIVATE_RSA_KEY = EXAMPLE_SECRET_QUALIFIER + "-----BEGIN PRIVATE KEY-----\n" + + "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDR0KfxUw7MF/8R\n" + + "B5/YXOM7yLnoHYb/M/6dyoulMbtEdKKhQhU28o5FiDkHcEG9PJQLgqrRgAjl3VmC\n" + + "C9omtfZJQ2EpfkTttkJjnKOOroXhYE51/CYSckapBYCVh8GkjUEJuEfnp07cTfYZ\n" + + "FqViIgIWPZyjkzl3w4girS7kCuzNdDntVJVx5F/EsFwMA8n3C0QazHQoM5s00Fer\n" + + "6aTwd6AW0JD5QkADavpfzZ554e4HrVGwHlM28WKQQkFzzGu44FFXyVuEF3HeyVPu\n" + + "g8GRHAc8UU7ijVgJB5TmbvRGYowIErD5i4VvGLuOv9mgR3aVyN0SdJ1N7aJnXpeS\n" + + "QjAgf03jAgMBAAECggEBAIhQyzwj3WJGWOZkkLqOpufJotcmj/Wwf0VfOdkq9WMl\n" + + "cB/bAlN/xWVxerPVgDCFch4EWBzi1WUaqbOvJZ2u7QNubmr56aiTmJCFTVI/GyZx\n" + + "XqiTGN01N6lKtN7xo6LYTyAUhUsBTWAemrx0FSErvTVb9C/mUBj6hbEZ2XQ5kN5t\n" + + "7qYX4Lu0zyn7s1kX5SLtm5I+YRq7HSwB6wLy+DSroO71izZ/VPwME3SwT5SN+c87\n" + + "3dkklR7fumNd9dOpSWKrLPnq4aMko00rvIGc63xD1HrEpXUkB5v24YEn7HwCLEH7\n" + + "b8jrp79j2nCvvR47inpf+BR8FIWAHEOUUqCEzjQkdiECgYEA6ifjMM0f02KPeIs7\n" + + "zXd1lI7CUmJmzkcklCIpEbKWf/t/PHv3QgqIkJzERzRaJ8b+GhQ4zrSwAhrGUmI8\n" + + "kDkXIqe2/2ONgIOX2UOHYHyTDQZHnlXyDecvHUTqs2JQZCGBZkXyZ9i0j3BnTymC\n" + + "iZ8DvEa0nxsbP+U3rgzPQmXiQVMCgYEA5WN2Y/RndbriNsNrsHYRldbPO5nfV9rp\n" + + "cDzcQU66HRdK5VIdbXT9tlMYCJIZsSqE0tkOwTgEB/sFvF/tIHSCY5iO6hpIyk6g\n" + + "kkUzPcld4eM0dEPAge7SYUbakB9CMvA7MkDQSXQNFyZ0mH83+UikwT6uYHFh7+ox\n" + + "N1P+psDhXzECgYEA1gXLVQnIcy/9LxMkgDMWV8j8uMyUZysDthpbK3/uq+A2dhRg\n" + + "9g4msPd5OBQT65OpIjElk1n4HpRWfWqpLLHiAZ0GWPynk7W0D7P3gyuaRSdeQs0P\n" + + "x8FtgPVDCN9t13gAjHiWjnC26Py2kNbCKAQeJ/MAmQTvrUFX2VCACJKTcV0CgYAj\n" + + "xJWSUmrLfb+GQISLOG3Xim434e9keJsLyEGj4U29+YLRLTOvfJ2PD3fg5j8hU/rw\n" + + "Ea5uTHi8cdTcIa0M8X3fX8txD3YoLYh2JlouGTcNYOst8d6TpBSj3HN6I5Wj8beZ\n" + + "R2fy/CiKYpGtsbCdq0kdZNO18BgQW9kewncjs1GxEQKBgQCf8q34h6KuHpHSDh9h\n" + + "YkDTypk0FReWBAVJCzDNDUMhVLFivjcwtaMd2LiC3FMKZYodr52iKg60cj43vbYI\n" + + "frmFFxoL37rTmUocCTBKc0LhWj6MicI+rcvQYe1uwTrpWdFf1aZJMYRLRczeKtev\n" + "OWaE/9hVZ5+9pild1NukGpOydw==\n" + + "-----END PRIVATE KEY-----\n"; + private final Path tempDir; public PemFileWriter() throws IOException { diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/ssl/PrivateKeyParserTests.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/ssl/PrivateKeyParserTests.java index 8ba45fa51398..6d1109ad9656 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/ssl/PrivateKeyParserTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/ssl/PrivateKeyParserTests.java @@ -28,6 +28,8 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import org.springframework.boot.buildpack.platform.docker.ssl.PrivateKeyParser.DerEncoder; @@ -39,6 +41,7 @@ * * @author Scott Frederick * @author Phillip Webb + * @author Moritz Halbritter */ class PrivateKeyParserTests { @@ -55,14 +58,34 @@ void tearDown() throws IOException { } @Test - void parsePkcs8KeyFile() throws IOException { - Path path = this.fileWriter.writeFile("key.pem", PemFileWriter.CA_PRIVATE_KEY); + void parsePkcs8RsaKeyFile() throws IOException { + Path path = this.fileWriter.writeFile("key.pem", PemFileWriter.PKCS8_PRIVATE_RSA_KEY); PrivateKey privateKey = PrivateKeyParser.parse(path); assertThat(privateKey).isNotNull(); assertThat(privateKey.getFormat()).isEqualTo("PKCS#8"); Files.delete(path); } + @ParameterizedTest + @ValueSource(strings = { PemFileWriter.PKCS8_PRIVATE_EC_NIST_P256_KEY, PemFileWriter.PKCS8_PRIVATE_EC_NIST_P384_KEY, + PemFileWriter.PKCS8_PRIVATE_EC_PRIME256V1_KEY, PemFileWriter.PKCS8_PRIVATE_EC_SECP256R1_KEY }) + void parsePkcs8EcKeyFile(String contents) throws IOException { + Path path = this.fileWriter.writeFile("key.pem", contents); + PrivateKey privateKey = PrivateKeyParser.parse(path); + assertThat(privateKey).isNotNull(); + assertThat(privateKey.getFormat()).isEqualTo("PKCS#8"); + assertThat(privateKey.getAlgorithm()).isEqualTo("EC"); + } + + @Test + void parsePkcs8DsaKeyFile() throws IOException { + Path path = this.fileWriter.writeFile("key.pem", PemFileWriter.PRIVATE_DSA_KEY); + PrivateKey privateKey = PrivateKeyParser.parse(path); + assertThat(privateKey).isNotNull(); + assertThat(privateKey.getFormat()).isEqualTo("PKCS#8"); + assertThat(privateKey.getAlgorithm()).isEqualTo("DSA"); + } + @Test void parsePkcs1RsaKeyFile() throws IOException { Path path = this.fileWriter.writeFile("key.pem", PemFileWriter.PRIVATE_RSA_KEY); diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/PrivateKeyParser.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/PrivateKeyParser.java index 474138e5af24..a95f6e72a410 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/PrivateKeyParser.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/server/PrivateKeyParser.java @@ -27,8 +27,6 @@ import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.function.Function; @@ -65,12 +63,9 @@ final class PrivateKeyParser { private static final List PEM_PARSERS; static { List parsers = new ArrayList<>(); - parsers.add(new PemParser(PKCS1_HEADER, PKCS1_FOOTER, Collections.singleton("RSA"), - PrivateKeyParser::createKeySpecForPkcs1)); - parsers.add( - new PemParser(EC_HEADER, EC_FOOTER, Collections.singleton("EC"), PrivateKeyParser::createKeySpecForEc)); - parsers.add( - new PemParser(PKCS8_HEADER, PKCS8_FOOTER, Arrays.asList("RSA", "EC", "DSA"), PKCS8EncodedKeySpec::new)); + parsers.add(new PemParser(PKCS1_HEADER, PKCS1_FOOTER, PrivateKeyParser::createKeySpecForPkcs1, "RSA")); + parsers.add(new PemParser(EC_HEADER, EC_FOOTER, PrivateKeyParser::createKeySpecForEc, "EC")); + parsers.add(new PemParser(PKCS8_HEADER, PKCS8_FOOTER, PKCS8EncodedKeySpec::new, "RSA", "EC", "DSA")); PEM_PARSERS = Collections.unmodifiableList(parsers); } @@ -152,12 +147,12 @@ private static class PemParser { private final Pattern pattern; - private final Collection algorithms; - private final Function keySpecFactory; - PemParser(String header, String footer, Collection algorithms, - Function keySpecFactory) { + private final String[] algorithms; + + PemParser(String header, String footer, Function keySpecFactory, + String... algorithms) { this.pattern = Pattern.compile(header + BASE64_TEXT + footer, Pattern.CASE_INSENSITIVE); this.algorithms = algorithms; this.keySpecFactory = keySpecFactory; @@ -181,7 +176,7 @@ private PrivateKey parse(byte[] bytes) { try { return keyFactory.generatePrivate(keySpec); } - catch (InvalidKeySpecException ignored) { + catch (InvalidKeySpecException ex) { } } return null; From 57e45dfb217bda6238000de6b709bea77f0e8eb9 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Fri, 12 May 2023 13:01:43 -0700 Subject: [PATCH 065/163] Update copyright year of changed files --- .../boot/buildpack/platform/docker/ssl/PrivateKeyParser.java | 2 +- .../boot/buildpack/platform/docker/ssl/PemFileWriter.java | 2 +- .../org/springframework/boot/maven/AbstractPackagerMojo.java | 2 +- .../org/springframework/boot/maven/CustomLayersProvider.java | 2 +- .../springframework/boot/testsupport/junit/DisabledOnOs.java | 2 +- .../boot/testsupport/testcontainers/DockerImageNames.java | 2 +- .../springframework/boot/web/error/ErrorAttributeOptions.java | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/ssl/PrivateKeyParser.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/ssl/PrivateKeyParser.java index 693919864380..df2e5ce1c25f 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/ssl/PrivateKeyParser.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/ssl/PrivateKeyParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/ssl/PemFileWriter.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/ssl/PemFileWriter.java index c5b458ab6ffb..b40c9c9d1a1b 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/ssl/PemFileWriter.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/ssl/PemFileWriter.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractPackagerMojo.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractPackagerMojo.java index 82ff6455e40f..e51f9700884f 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractPackagerMojo.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractPackagerMojo.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/CustomLayersProvider.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/CustomLayersProvider.java index 2889520bd400..4bd71c33b7d8 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/CustomLayersProvider.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/CustomLayersProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/junit/DisabledOnOs.java b/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/junit/DisabledOnOs.java index 1535e68d7e38..c7c2763cb27c 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/junit/DisabledOnOs.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/junit/DisabledOnOs.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/testcontainers/DockerImageNames.java b/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/testcontainers/DockerImageNames.java index 2a6a5b74c5ec..44da467557d9 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/testcontainers/DockerImageNames.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/testcontainers/DockerImageNames.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/error/ErrorAttributeOptions.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/error/ErrorAttributeOptions.java index ecf1ddc862ce..c32f683276e3 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/error/ErrorAttributeOptions.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/error/ErrorAttributeOptions.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From 307f3c339912466e78fcdac648fff95a4edea573 Mon Sep 17 00:00:00 2001 From: Madhura Bhave Date: Thu, 20 Apr 2023 07:42:18 +0100 Subject: [PATCH 066/163] Use endpoint mappings in CloudFoundry integration Closes gh-35411 --- ...dFoundryWebFluxEndpointHandlerMapping.java | 12 +++++-- ...CloudFoundryActuatorAutoConfiguration.java | 35 ++++++++++++++----- ...CloudFoundryActuatorAutoConfiguration.java | 30 ++++++++++++---- ...undryWebEndpointServletHandlerMapping.java | 12 +++++-- ...oundryWebFluxEndpointIntegrationTests.java | 13 ++++--- ...FoundryActuatorAutoConfigurationTests.java | 30 +++++++++++----- ...FoundryActuatorAutoConfigurationTests.java | 21 ++++++++--- ...FoundryMvcWebEndpointIntegrationTests.java | 13 ++++--- 8 files changed, 126 insertions(+), 40 deletions(-) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointHandlerMapping.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointHandlerMapping.java index 0df6400d0a0c..8d3e2d3f44a9 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointHandlerMapping.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointHandlerMapping.java @@ -28,6 +28,7 @@ import org.springframework.boot.actuate.autoconfigure.cloudfoundry.AccessLevel; import org.springframework.boot.actuate.autoconfigure.cloudfoundry.SecurityResponse; import org.springframework.boot.actuate.endpoint.EndpointId; +import org.springframework.boot.actuate.endpoint.ExposableEndpoint; import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver; import org.springframework.boot.actuate.endpoint.web.EndpointMapping; import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes; @@ -56,12 +57,15 @@ class CloudFoundryWebFluxEndpointHandlerMapping extends AbstractWebFluxEndpointH private final EndpointLinksResolver linksResolver; + private final Collection> allEndpoints; + CloudFoundryWebFluxEndpointHandlerMapping(EndpointMapping endpointMapping, Collection endpoints, EndpointMediaTypes endpointMediaTypes, CorsConfiguration corsConfiguration, CloudFoundrySecurityInterceptor securityInterceptor, - EndpointLinksResolver linksResolver) { + Collection> allEndpoints) { super(endpointMapping, endpoints, endpointMediaTypes, corsConfiguration, true); - this.linksResolver = linksResolver; + this.linksResolver = new EndpointLinksResolver(allEndpoints); + this.allEndpoints = allEndpoints; this.securityInterceptor = securityInterceptor; } @@ -76,6 +80,10 @@ protected LinksHandler getLinksHandler() { return new CloudFoundryLinksHandler(); } + Collection> getAllEndpoints() { + return this.allEndpoints; + } + class CloudFoundryLinksHandler implements LinksHandler { @Override diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundryActuatorAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundryActuatorAutoConfiguration.java index 8f58aeda5028..172975c79126 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundryActuatorAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundryActuatorAutoConfiguration.java @@ -33,10 +33,10 @@ import org.springframework.boot.actuate.autoconfigure.info.InfoEndpointAutoConfiguration; import org.springframework.boot.actuate.endpoint.ExposableEndpoint; import org.springframework.boot.actuate.endpoint.invoke.ParameterValueMapper; -import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver; import org.springframework.boot.actuate.endpoint.web.EndpointMapping; import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes; import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint; +import org.springframework.boot.actuate.endpoint.web.PathMappedEndpoints; import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpointsSupplier; import org.springframework.boot.actuate.health.HealthEndpoint; import org.springframework.boot.actuate.health.ReactiveHealthEndpointWebExtension; @@ -82,6 +82,8 @@ @ConditionalOnCloudPlatform(CloudPlatform.CLOUD_FOUNDRY) public class ReactiveCloudFoundryActuatorAutoConfiguration { + private static final String BASE_PATH = "/cloudfoundryapplication"; + @Bean @ConditionalOnMissingBean @ConditionalOnAvailableEndpoint @@ -117,9 +119,8 @@ public CloudFoundryWebFluxEndpointHandlerMapping cloudFoundryWebFluxEndpointHand List> allEndpoints = new ArrayList<>(); allEndpoints.addAll(webEndpoints); allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints()); - return new CloudFoundryWebFluxEndpointHandlerMapping(new EndpointMapping("/cloudfoundryapplication"), - webEndpoints, endpointMediaTypes, getCorsConfiguration(), securityInterceptor, - new EndpointLinksResolver(allEndpoints)); + return new CloudFoundryWebFluxEndpointHandlerMapping(new EndpointMapping(BASE_PATH), webEndpoints, + endpointMediaTypes, getCorsConfiguration(), securityInterceptor, allEndpoints); } private CloudFoundrySecurityInterceptor getSecurityInterceptor(WebClient.Builder webClientBuilder, @@ -155,25 +156,33 @@ private CorsConfiguration getCorsConfiguration() { static class IgnoredPathsSecurityConfiguration { @Bean - WebFilterChainPostProcessor webFilterChainPostProcessor() { - return new WebFilterChainPostProcessor(); + WebFilterChainPostProcessor webFilterChainPostProcessor( + CloudFoundryWebFluxEndpointHandlerMapping handlerMapping) { + return new WebFilterChainPostProcessor(handlerMapping); } } private static class WebFilterChainPostProcessor implements BeanPostProcessor { + private final PathMappedEndpoints pathMappedEndpoints; + + WebFilterChainPostProcessor(CloudFoundryWebFluxEndpointHandlerMapping handlerMapping) { + this.pathMappedEndpoints = new PathMappedEndpoints(BASE_PATH, handlerMapping::getAllEndpoints); + } + @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof WebFilterChainProxy) { - return postProcess((WebFilterChainProxy) bean); + return postProcess((WebFilterChainProxy) bean, this.pathMappedEndpoints); } return bean; } - private WebFilterChainProxy postProcess(WebFilterChainProxy existing) { + private WebFilterChainProxy postProcess(WebFilterChainProxy existing, PathMappedEndpoints pathMappedEndpoints) { + List paths = getPaths(pathMappedEndpoints); ServerWebExchangeMatcher cloudFoundryRequestMatcher = ServerWebExchangeMatchers - .pathMatchers("/cloudfoundryapplication/**"); + .pathMatchers(paths.toArray(new String[] {})); WebFilter noOpFilter = (exchange, chain) -> chain.filter(exchange); MatcherSecurityWebFilterChain ignoredRequestFilterChain = new MatcherSecurityWebFilterChain( cloudFoundryRequestMatcher, Collections.singletonList(noOpFilter)); @@ -182,6 +191,14 @@ private WebFilterChainProxy postProcess(WebFilterChainProxy existing) { return new WebFilterChainProxy(ignoredRequestFilterChain, allRequestsFilterChain); } + private static List getPaths(PathMappedEndpoints pathMappedEndpoints) { + List paths = new ArrayList<>(); + pathMappedEndpoints.getAllPaths().forEach((path) -> paths.add(path + "/**")); + paths.add(BASE_PATH); + paths.add(BASE_PATH + "/"); + return paths; + } + } } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryActuatorAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryActuatorAutoConfiguration.java index 04f24deeb771..a76756565f78 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryActuatorAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryActuatorAutoConfiguration.java @@ -31,10 +31,10 @@ import org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration; import org.springframework.boot.actuate.endpoint.ExposableEndpoint; import org.springframework.boot.actuate.endpoint.invoke.ParameterValueMapper; -import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver; import org.springframework.boot.actuate.endpoint.web.EndpointMapping; import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes; import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint; +import org.springframework.boot.actuate.endpoint.web.PathMappedEndpoints; import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpointsSupplier; import org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpointsSupplier; import org.springframework.boot.actuate.health.HealthEndpoint; @@ -66,6 +66,9 @@ import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; +import org.springframework.security.web.util.matcher.OrRequestMatcher; +import org.springframework.security.web.util.matcher.RequestMatcher; +import org.springframework.util.CollectionUtils; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.servlet.DispatcherServlet; @@ -86,6 +89,8 @@ @ConditionalOnCloudPlatform(CloudPlatform.CLOUD_FOUNDRY) public class CloudFoundryActuatorAutoConfiguration { + private static final String BASE_PATH = "/cloudfoundryapplication"; + @Bean @ConditionalOnMissingBean @ConditionalOnAvailableEndpoint @@ -123,8 +128,7 @@ public CloudFoundryWebEndpointServletHandlerMapping cloudFoundryWebEndpointServl allEndpoints.addAll(servletEndpointsSupplier.getEndpoints()); allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints()); return new CloudFoundryWebEndpointServletHandlerMapping(new EndpointMapping("/cloudfoundryapplication"), - webEndpoints, endpointMediaTypes, getCorsConfiguration(), securityInterceptor, - new EndpointLinksResolver(allEndpoints)); + webEndpoints, endpointMediaTypes, getCorsConfiguration(), securityInterceptor, allEndpoints); } private CloudFoundrySecurityInterceptor getSecurityInterceptor(RestTemplateBuilder restTemplateBuilder, @@ -164,8 +168,9 @@ private CorsConfiguration getCorsConfiguration() { public static class IgnoredCloudFoundryPathsWebSecurityConfiguration { @Bean - IgnoredCloudFoundryPathsWebSecurityCustomizer ignoreCloudFoundryPathsWebSecurityCustomizer() { - return new IgnoredCloudFoundryPathsWebSecurityCustomizer(); + IgnoredCloudFoundryPathsWebSecurityCustomizer ignoreCloudFoundryPathsWebSecurityCustomizer( + CloudFoundryWebEndpointServletHandlerMapping handlerMapping) { + return new IgnoredCloudFoundryPathsWebSecurityCustomizer(handlerMapping); } } @@ -173,9 +178,22 @@ IgnoredCloudFoundryPathsWebSecurityCustomizer ignoreCloudFoundryPathsWebSecurity @Order(SecurityProperties.IGNORED_ORDER) static class IgnoredCloudFoundryPathsWebSecurityCustomizer implements WebSecurityCustomizer { + private final PathMappedEndpoints pathMappedEndpoints; + + IgnoredCloudFoundryPathsWebSecurityCustomizer(CloudFoundryWebEndpointServletHandlerMapping handlerMapping) { + this.pathMappedEndpoints = new PathMappedEndpoints(BASE_PATH, handlerMapping::getAllEndpoints); + } + @Override public void customize(WebSecurity web) { - web.ignoring().requestMatchers(new AntPathRequestMatcher("/cloudfoundryapplication/**")); + List requestMatchers = new ArrayList<>(); + this.pathMappedEndpoints.getAllPaths() + .forEach((path) -> requestMatchers.add(new AntPathRequestMatcher(path + "/**"))); + requestMatchers.add(new AntPathRequestMatcher(BASE_PATH)); + requestMatchers.add(new AntPathRequestMatcher(BASE_PATH + "/")); + if (!CollectionUtils.isEmpty(requestMatchers)) { + web.ignoring().requestMatchers(new OrRequestMatcher(requestMatchers)); + } } } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryWebEndpointServletHandlerMapping.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryWebEndpointServletHandlerMapping.java index 472535cf6b29..8bedd5cea7d3 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryWebEndpointServletHandlerMapping.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryWebEndpointServletHandlerMapping.java @@ -31,6 +31,7 @@ import org.springframework.boot.actuate.autoconfigure.cloudfoundry.AccessLevel; import org.springframework.boot.actuate.autoconfigure.cloudfoundry.SecurityResponse; import org.springframework.boot.actuate.endpoint.EndpointId; +import org.springframework.boot.actuate.endpoint.ExposableEndpoint; import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver; import org.springframework.boot.actuate.endpoint.web.EndpointMapping; import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes; @@ -60,13 +61,16 @@ class CloudFoundryWebEndpointServletHandlerMapping extends AbstractWebMvcEndpoin private final EndpointLinksResolver linksResolver; + private final Collection> allEndpoints; + CloudFoundryWebEndpointServletHandlerMapping(EndpointMapping endpointMapping, Collection endpoints, EndpointMediaTypes endpointMediaTypes, CorsConfiguration corsConfiguration, CloudFoundrySecurityInterceptor securityInterceptor, - EndpointLinksResolver linksResolver) { + Collection> allEndpoints) { super(endpointMapping, endpoints, endpointMediaTypes, corsConfiguration, true); this.securityInterceptor = securityInterceptor; - this.linksResolver = linksResolver; + this.linksResolver = new EndpointLinksResolver(allEndpoints); + this.allEndpoints = allEndpoints; } @Override @@ -80,6 +84,10 @@ protected LinksHandler getLinksHandler() { return new CloudFoundryLinksHandler(); } + Collection> getAllEndpoints() { + return this.allEndpoints; + } + class CloudFoundryLinksHandler implements LinksHandler { @Override diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointIntegrationTests.java index 7b1d3ad0338c..7001df2a7f3c 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointIntegrationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointIntegrationTests.java @@ -17,8 +17,11 @@ package org.springframework.boot.actuate.autoconfigure.cloudfoundry.reactive; import java.time.Duration; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; +import java.util.List; import java.util.Map; import java.util.function.Consumer; @@ -28,15 +31,16 @@ import org.springframework.boot.actuate.autoconfigure.cloudfoundry.AccessLevel; import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException; import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException.Reason; +import org.springframework.boot.actuate.endpoint.ExposableEndpoint; import org.springframework.boot.actuate.endpoint.annotation.Endpoint; import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; import org.springframework.boot.actuate.endpoint.annotation.Selector; import org.springframework.boot.actuate.endpoint.annotation.WriteOperation; import org.springframework.boot.actuate.endpoint.invoke.ParameterValueMapper; import org.springframework.boot.actuate.endpoint.invoke.convert.ConversionServiceParameterValueMapper; -import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver; import org.springframework.boot.actuate.endpoint.web.EndpointMapping; import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes; +import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint; import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointDiscoverer; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration; @@ -184,9 +188,10 @@ CloudFoundryWebFluxEndpointHandlerMapping cloudFoundryWebEndpointServletHandlerM CorsConfiguration corsConfiguration = new CorsConfiguration(); corsConfiguration.setAllowedOrigins(Arrays.asList("https://example.com")); corsConfiguration.setAllowedMethods(Arrays.asList("GET", "POST")); - return new CloudFoundryWebFluxEndpointHandlerMapping(new EndpointMapping("/cfApplication"), - webEndpointDiscoverer.getEndpoints(), endpointMediaTypes, corsConfiguration, interceptor, - new EndpointLinksResolver(webEndpointDiscoverer.getEndpoints())); + Collection webEndpoints = webEndpointDiscoverer.getEndpoints(); + List> allEndpoints = new ArrayList<>(webEndpoints); + return new CloudFoundryWebFluxEndpointHandlerMapping(new EndpointMapping("/cfApplication"), webEndpoints, + endpointMediaTypes, corsConfiguration, interceptor, allEndpoints); } @Bean diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundryActuatorAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundryActuatorAutoConfigurationTests.java index fadaeb8feeae..31ddcdfe6ed7 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundryActuatorAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundryActuatorAutoConfigurationTests.java @@ -95,6 +95,8 @@ class ReactiveCloudFoundryActuatorAutoConfigurationTests { InfoContributorAutoConfiguration.class, InfoEndpointAutoConfiguration.class, ProjectInfoAutoConfiguration.class, ReactiveCloudFoundryActuatorAutoConfiguration.class)); + private static final String BASE_PATH = "/cloudfoundryapplication"; + @AfterEach void close() { HttpResources.reset(); @@ -170,26 +172,36 @@ void cloudFoundryPlatformActiveAndCloudControllerUrlNotPresent() { @Test @SuppressWarnings("unchecked") void cloudFoundryPathsIgnoredBySpringSecurity() { - this.contextRunner.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id", - "vcap.application.cf_api:https://my-cloud-controller.com").run((context) -> { + this.contextRunner.withBean(TestEndpoint.class, TestEndpoint::new).withPropertyValues("VCAP_APPLICATION:---", + "vcap.application.application_id:my-app-id", "vcap.application.cf_api:https://my-cloud-controller.com") + .run((context) -> { WebFilterChainProxy chainProxy = context.getBean(WebFilterChainProxy.class); List filters = (List) ReflectionTestUtils .getField(chainProxy, "filters"); - Boolean cfRequestMatches = filters.get(0) - .matches(MockServerWebExchange - .from(MockServerHttpRequest.get("/cloudfoundryapplication/my-path").build())) - .block(Duration.ofSeconds(30)); - Boolean otherRequestMatches = filters.get(0) - .matches(MockServerWebExchange.from(MockServerHttpRequest.get("/some-other-path").build())) - .block(Duration.ofSeconds(30)); + Boolean cfBaseRequestMatches = getMatches(filters, BASE_PATH); + Boolean cfBaseWithTrailingSlashRequestMatches = getMatches(filters, BASE_PATH + "/"); + Boolean cfRequestMatches = getMatches(filters, BASE_PATH + "/test"); + Boolean cfRequestWithAdditionalPathMatches = getMatches(filters, BASE_PATH + "/test/a"); + Boolean otherCfRequestMatches = getMatches(filters, BASE_PATH + "/other-path"); + Boolean otherRequestMatches = getMatches(filters, "/some-other-path"); + assertThat(cfBaseRequestMatches).isTrue(); + assertThat(cfBaseWithTrailingSlashRequestMatches).isTrue(); assertThat(cfRequestMatches).isTrue(); + assertThat(cfRequestWithAdditionalPathMatches).isTrue(); + assertThat(otherCfRequestMatches).isFalse(); assertThat(otherRequestMatches).isFalse(); otherRequestMatches = filters.get(1) .matches(MockServerWebExchange.from(MockServerHttpRequest.get("/some-other-path").build())) .block(Duration.ofSeconds(30)); assertThat(otherRequestMatches).isTrue(); }); + } + private static Boolean getMatches(List filters, String urlTemplate) { + Boolean cfBaseRequestMatches = filters.get(0) + .matches(MockServerWebExchange.from(MockServerHttpRequest.get(urlTemplate).build())) + .block(Duration.ofSeconds(30)); + return cfBaseRequestMatches; } @Test diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryActuatorAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryActuatorAutoConfigurationTests.java index 2bc35b8b0618..3956b96e7d8a 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryActuatorAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryActuatorAutoConfigurationTests.java @@ -77,6 +77,8 @@ class CloudFoundryActuatorAutoConfigurationTests { ServletManagementContextAutoConfiguration.class, EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class, CloudFoundryActuatorAutoConfiguration.class)); + private static String BASE_PATH = "/cloudfoundryapplication"; + @Test void cloudFoundryPlatformActive() { this.contextRunner.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id", @@ -160,20 +162,31 @@ void cloudFoundryPlatformActiveAndCloudControllerUrlNotPresent() { @Test void cloudFoundryPathsIgnoredBySpringSecurity() { - this.contextRunner.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id") + this.contextRunner.withBean(TestEndpoint.class, TestEndpoint::new) + .withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id") .run((context) -> { FilterChainProxy securityFilterChain = (FilterChainProxy) context .getBean(BeanIds.SPRING_SECURITY_FILTER_CHAIN); SecurityFilterChain chain = securityFilterChain.getFilterChains().get(0); - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setServletPath("/cloudfoundryapplication/my-path"); assertThat(chain.getFilters()).isEmpty(); - assertThat(chain.matches(request)).isTrue(); + MockHttpServletRequest request = new MockHttpServletRequest(); + testCloudFoundrySecurity(request, BASE_PATH, chain); + testCloudFoundrySecurity(request, BASE_PATH + "/", chain); + testCloudFoundrySecurity(request, BASE_PATH + "/test", chain); + testCloudFoundrySecurity(request, BASE_PATH + "/test/a", chain); + request.setServletPath(BASE_PATH + "/other-path"); + assertThat(chain.matches(request)).isFalse(); request.setServletPath("/some-other-path"); assertThat(chain.matches(request)).isFalse(); }); } + private static void testCloudFoundrySecurity(MockHttpServletRequest request, String basePath, + SecurityFilterChain chain) { + request.setServletPath(basePath); + assertThat(chain.matches(request)).isTrue(); + } + @Test void cloudFoundryPlatformInactive() { this.contextRunner.withPropertyValues() diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryMvcWebEndpointIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryMvcWebEndpointIntegrationTests.java index a7affad6a078..0cfcaabb6efd 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryMvcWebEndpointIntegrationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryMvcWebEndpointIntegrationTests.java @@ -17,8 +17,11 @@ package org.springframework.boot.actuate.autoconfigure.cloudfoundry.servlet; import java.time.Duration; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; +import java.util.List; import java.util.Map; import java.util.function.BiConsumer; import java.util.function.Consumer; @@ -28,15 +31,16 @@ import org.springframework.boot.actuate.autoconfigure.cloudfoundry.AccessLevel; import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException; import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException.Reason; +import org.springframework.boot.actuate.endpoint.ExposableEndpoint; import org.springframework.boot.actuate.endpoint.annotation.Endpoint; import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; import org.springframework.boot.actuate.endpoint.annotation.Selector; import org.springframework.boot.actuate.endpoint.annotation.WriteOperation; import org.springframework.boot.actuate.endpoint.invoke.ParameterValueMapper; import org.springframework.boot.actuate.endpoint.invoke.convert.ConversionServiceParameterValueMapper; -import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver; import org.springframework.boot.actuate.endpoint.web.EndpointMapping; import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes; +import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint; import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointDiscoverer; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; @@ -180,9 +184,10 @@ CloudFoundryWebEndpointServletHandlerMapping cloudFoundryWebEndpointServletHandl CorsConfiguration corsConfiguration = new CorsConfiguration(); corsConfiguration.setAllowedOrigins(Arrays.asList("https://example.com")); corsConfiguration.setAllowedMethods(Arrays.asList("GET", "POST")); - return new CloudFoundryWebEndpointServletHandlerMapping(new EndpointMapping("/cfApplication"), - webEndpointDiscoverer.getEndpoints(), endpointMediaTypes, corsConfiguration, interceptor, - new EndpointLinksResolver(webEndpointDiscoverer.getEndpoints())); + Collection webEndpoints = webEndpointDiscoverer.getEndpoints(); + List> allEndpoints = new ArrayList<>(webEndpoints); + return new CloudFoundryWebEndpointServletHandlerMapping(new EndpointMapping("/cfApplication"), webEndpoints, + endpointMediaTypes, corsConfiguration, interceptor, allEndpoints); } @Bean From d1d990acd7a06aa34112896d753bcae679203f35 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 28 Feb 2023 09:39:43 +0000 Subject: [PATCH 067/163] Improve compatibility with SnakeYAML 2.0 Closes gh-35414 --- .../boot/env/OriginTrackedYamlLoader.java | 39 +++++++++++++++++-- ...lPropertySourceLoaderSnakeYaml20Tests.java | 29 ++++++++++++++ src/checkstyle/checkstyle-suppressions.xml | 1 + 3 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 spring-boot-project/spring-boot/src/test/java/org/springframework/boot/env/YamlPropertySourceLoaderSnakeYaml20Tests.java diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/env/OriginTrackedYamlLoader.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/env/OriginTrackedYamlLoader.java index 16861bac0bbf..4051044b7ce7 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/env/OriginTrackedYamlLoader.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/env/OriginTrackedYamlLoader.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,9 @@ package org.springframework.boot.env; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -45,6 +48,7 @@ import org.springframework.boot.origin.TextResourceOrigin; import org.springframework.boot.origin.TextResourceOrigin.Location; import org.springframework.core.io.Resource; +import org.springframework.util.ReflectionUtils; /** * Class to load {@code .yml} files into a map of {@code String} to @@ -73,8 +77,8 @@ protected Yaml createYaml() { private Yaml createYaml(LoaderOptions loaderOptions) { BaseConstructor constructor = new OriginTrackingConstructor(loaderOptions); - Representer representer = new Representer(); DumperOptions dumperOptions = new DumperOptions(); + Representer representer = new Representer(dumperOptions); LimitedResolver resolver = new LimitedResolver(); return new Yaml(constructor, representer, dumperOptions, loaderOptions, resolver); } @@ -167,7 +171,12 @@ private static Node get(Node node) { /** * {@link Resolver} that limits {@link Tag#TIMESTAMP} tags. */ - private static class LimitedResolver extends Resolver { + static class LimitedResolver extends Resolver { + + private static final MethodType SNAKE_YAML_2_ADD_IMPLICIT_RESOLVER_METHOD_TYPE = MethodType + .methodType(void.class, Tag.class, Pattern.class, String.class, int.class); + + private volatile MethodHandle snakeYaml2ImplicitResolverMethod; @Override public void addImplicitResolver(Tag tag, Pattern regexp, String first) { @@ -177,6 +186,30 @@ public void addImplicitResolver(Tag tag, Pattern regexp, String first) { super.addImplicitResolver(tag, regexp, first); } + public void addImplicitResolver(Tag tag, Pattern regexp, String first, int limit) { + // Support for SnakeYAML 2.0 + if (tag == Tag.TIMESTAMP) { + return; + } + try { + getSnakeYaml2ImplicitResolverMethod().invoke(this, tag, regexp, first, limit); + } + catch (Throwable ex) { + ReflectionUtils.rethrowRuntimeException(ex); + } + } + + private MethodHandle getSnakeYaml2ImplicitResolverMethod() + throws NoSuchMethodException, IllegalAccessException { + MethodHandle snakeYaml2ImplicitResolverMethod = this.snakeYaml2ImplicitResolverMethod; + if (snakeYaml2ImplicitResolverMethod == null) { + snakeYaml2ImplicitResolverMethod = MethodHandles.lookup().findSpecial(Resolver.class, + "addImplicitResolver", SNAKE_YAML_2_ADD_IMPLICIT_RESOLVER_METHOD_TYPE, getClass()); + this.snakeYaml2ImplicitResolverMethod = snakeYaml2ImplicitResolverMethod; + } + return snakeYaml2ImplicitResolverMethod; + } + } } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/env/YamlPropertySourceLoaderSnakeYaml20Tests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/env/YamlPropertySourceLoaderSnakeYaml20Tests.java new file mode 100644 index 000000000000..684440176523 --- /dev/null +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/env/YamlPropertySourceLoaderSnakeYaml20Tests.java @@ -0,0 +1,29 @@ +/* + * Copyright 2012-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.env; + +import org.springframework.boot.testsupport.classpath.ClassPathOverrides; + +/** + * Tests for {@link YamlPropertySourceLoader} with SnakeYAML 2.0. + * + * @author Andy Wilkinson + */ +@ClassPathOverrides("org.yaml:snakeyaml:2.0") +class YamlPropertySourceLoaderSnakeYaml20Tests extends YamlPropertySourceLoaderTests { + +} diff --git a/src/checkstyle/checkstyle-suppressions.xml b/src/checkstyle/checkstyle-suppressions.xml index 2547fa96e3b0..44859cc43b25 100644 --- a/src/checkstyle/checkstyle-suppressions.xml +++ b/src/checkstyle/checkstyle-suppressions.xml @@ -54,4 +54,5 @@ + From ef1401fcc9f5bfc21f05b2beb2cb6e83698c1373 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Fri, 12 May 2023 14:20:40 -0700 Subject: [PATCH 068/163] Fix formatting --- .../CloudFoundryWebEndpointServletHandlerMapping.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryWebEndpointServletHandlerMapping.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryWebEndpointServletHandlerMapping.java index d6f2cf0b78be..ddb9c4471477 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryWebEndpointServletHandlerMapping.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryWebEndpointServletHandlerMapping.java @@ -94,7 +94,7 @@ class CloudFoundryLinksHandler implements LinksHandler { @ResponseBody public Map> links(HttpServletRequest request, HttpServletResponse response) { SecurityResponse securityResponse = CloudFoundryWebEndpointServletHandlerMapping.this.securityInterceptor - .preHandle(request, null); + .preHandle(request, null); if (!securityResponse.getStatus().equals(HttpStatus.OK)) { sendFailureResponse(response, securityResponse); } @@ -104,11 +104,10 @@ public Map> links(HttpServletRequest request, HttpServ return Collections.singletonMap("_links", filteredLinks); } Map links = CloudFoundryWebEndpointServletHandlerMapping.this.linksResolver - .resolveLinks(request.getRequestURL().toString()); - filteredLinks = links.entrySet() - .stream() - .filter((e) -> e.getKey().equals("self") || accessLevel.isAccessAllowed(e.getKey())) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + .resolveLinks(request.getRequestURL().toString()); + filteredLinks = links.entrySet().stream() + .filter((e) -> e.getKey().equals("self") || accessLevel.isAccessAllowed(e.getKey())) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); return Collections.singletonMap("_links", filteredLinks); } From 5f86c11f92b619ec6e8c67126eeeb3d81ad8bf59 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Mon, 15 May 2023 08:20:01 +0200 Subject: [PATCH 069/163] Upgrade to Spring Data Bom 2021.2.12 Closes gh-35292 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 8fb36a890a5f..4db344570100 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1739,7 +1739,7 @@ bom { ] } } - library("Spring Data Bom", "2021.2.12-SNAPSHOT") { + library("Spring Data Bom", "2021.2.12") { prohibit { versionRange "[2022.0.0-M1,)" because "it uses Spring Framework 6" From 1ca11458758de6407fdc68ae6dae8ab26773a12e Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Mon, 15 May 2023 10:15:51 -0700 Subject: [PATCH 070/163] Test compatibility with SnakeYAML 1.32 and 1.33 versions Closes gh-35434 --- ...PropertySourceLoaderSnakeYaml132Tests.java | 29 +++++++++++++++++++ ...PropertySourceLoaderSnakeYaml133Tests.java | 29 +++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 spring-boot-project/spring-boot/src/test/java/org/springframework/boot/env/YamlPropertySourceLoaderSnakeYaml132Tests.java create mode 100644 spring-boot-project/spring-boot/src/test/java/org/springframework/boot/env/YamlPropertySourceLoaderSnakeYaml133Tests.java diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/env/YamlPropertySourceLoaderSnakeYaml132Tests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/env/YamlPropertySourceLoaderSnakeYaml132Tests.java new file mode 100644 index 000000000000..70d5b86ef8cf --- /dev/null +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/env/YamlPropertySourceLoaderSnakeYaml132Tests.java @@ -0,0 +1,29 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.env; + +import org.springframework.boot.testsupport.classpath.ClassPathOverrides; + +/** + * Tests for {@link YamlPropertySourceLoader} with SnakeYAML 1.33. + * + * @author Andy Wilkinson + */ +@ClassPathOverrides("org.yaml:snakeyaml:1.32") +class YamlPropertySourceLoaderSnakeYaml132Tests extends YamlPropertySourceLoaderTests { + +} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/env/YamlPropertySourceLoaderSnakeYaml133Tests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/env/YamlPropertySourceLoaderSnakeYaml133Tests.java new file mode 100644 index 000000000000..5c796c0ac311 --- /dev/null +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/env/YamlPropertySourceLoaderSnakeYaml133Tests.java @@ -0,0 +1,29 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.env; + +import org.springframework.boot.testsupport.classpath.ClassPathOverrides; + +/** + * Tests for {@link YamlPropertySourceLoader} with SnakeYAML 1.33. + * + * @author Andy Wilkinson + */ +@ClassPathOverrides("org.yaml:snakeyaml:1.33") +class YamlPropertySourceLoaderSnakeYaml133Tests extends YamlPropertySourceLoaderTests { + +} From 086b1e5f587c68a070cc4a76dcab186145c09d3e Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 25 Apr 2023 11:22:33 +0100 Subject: [PATCH 071/163] Stop WebFilterChainPostProcessor from causing eager init Fixes gh-35437 --- ...tiveCloudFoundryActuatorAutoConfiguration.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundryActuatorAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundryActuatorAutoConfiguration.java index 172975c79126..33bd26a4ab08 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundryActuatorAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundryActuatorAutoConfiguration.java @@ -21,6 +21,7 @@ import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.function.Supplier; import java.util.stream.Collectors; import org.springframework.beans.BeansException; @@ -64,6 +65,7 @@ import org.springframework.security.web.server.WebFilterChainProxy; import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher; import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatchers; +import org.springframework.util.function.SingletonSupplier; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.server.WebFilter; @@ -156,8 +158,8 @@ private CorsConfiguration getCorsConfiguration() { static class IgnoredPathsSecurityConfiguration { @Bean - WebFilterChainPostProcessor webFilterChainPostProcessor( - CloudFoundryWebFluxEndpointHandlerMapping handlerMapping) { + static WebFilterChainPostProcessor webFilterChainPostProcessor( + ObjectProvider handlerMapping) { return new WebFilterChainPostProcessor(handlerMapping); } @@ -165,16 +167,17 @@ WebFilterChainPostProcessor webFilterChainPostProcessor( private static class WebFilterChainPostProcessor implements BeanPostProcessor { - private final PathMappedEndpoints pathMappedEndpoints; + private Supplier pathMappedEndpoints; - WebFilterChainPostProcessor(CloudFoundryWebFluxEndpointHandlerMapping handlerMapping) { - this.pathMappedEndpoints = new PathMappedEndpoints(BASE_PATH, handlerMapping::getAllEndpoints); + WebFilterChainPostProcessor(ObjectProvider handlerMapping) { + this.pathMappedEndpoints = SingletonSupplier + .of(() -> new PathMappedEndpoints(BASE_PATH, () -> handlerMapping.getObject().getAllEndpoints())); } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof WebFilterChainProxy) { - return postProcess((WebFilterChainProxy) bean, this.pathMappedEndpoints); + return postProcess((WebFilterChainProxy) bean, this.pathMappedEndpoints.get()); } return bean; } From 8316a9651575d59dabc521170aba69e0a0abc599 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Mon, 15 May 2023 22:19:06 -0700 Subject: [PATCH 072/163] Polish --- .../reactive/ReactiveCloudFoundryActuatorAutoConfiguration.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundryActuatorAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundryActuatorAutoConfiguration.java index 33bd26a4ab08..47cf3aac0e1d 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundryActuatorAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundryActuatorAutoConfiguration.java @@ -167,7 +167,7 @@ static WebFilterChainPostProcessor webFilterChainPostProcessor( private static class WebFilterChainPostProcessor implements BeanPostProcessor { - private Supplier pathMappedEndpoints; + private final Supplier pathMappedEndpoints; WebFilterChainPostProcessor(ObjectProvider handlerMapping) { this.pathMappedEndpoints = SingletonSupplier From a9739e109ffe53605df22a69512ea46ecc4dcb8d Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Tue, 16 May 2023 07:46:20 +0200 Subject: [PATCH 073/163] Upgrade to Hazelcast 5.1.6 Closes gh-35440 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 4db344570100..fd9212c60733 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -452,7 +452,7 @@ bom { ] } } - library("Hazelcast", "5.1.5") { + library("Hazelcast", "5.1.6") { group("com.hazelcast") { modules = [ "hazelcast", From 47cd3bb052dacc377a188cb6a85b68ed4809ce5d Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Tue, 16 May 2023 07:46:24 +0200 Subject: [PATCH 074/163] Upgrade to Netty 4.1.92.Final Closes gh-35441 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index fd9212c60733..f845d77ae7e9 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1394,7 +1394,7 @@ bom { ] } } - library("Netty", "4.1.91.Final") { + library("Netty", "4.1.92.Final") { group("io.netty") { imports = [ "netty-bom" From 30b4bb0753f562cdcc3badf3cd0785972477a1a1 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Tue, 16 May 2023 07:46:29 +0200 Subject: [PATCH 075/163] Upgrade to Tomcat 9.0.75 Closes gh-35442 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 284895299a2f..eb6c2eb76fb1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,6 +6,6 @@ org.gradle.jvmargs=-Xmx2g -Dfile.encoding=UTF-8 kotlinVersion=1.6.21 springFrameworkVersion=5.3.27 -tomcatVersion=9.0.74 +tomcatVersion=9.0.75 kotlin.stdlib.default.dependency=false From c631f0439155ffa08b5a76e7f45790c411991553 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 16 May 2023 19:23:36 +0100 Subject: [PATCH 076/163] Upgrade to Spring Integration 5.5.18 Closes gh-35294 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index f845d77ae7e9..ead8f25305e8 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1780,7 +1780,7 @@ bom { ] } } - library("Spring Integration", "5.5.18-SNAPSHOT") { + library("Spring Integration", "5.5.18") { prohibit { versionRange "[6.0.0-M1,)" because "it uses Spring Framework 6" From f5ff8007be02ce8992a2cf0e13375f636f00aee7 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 16 May 2023 19:46:43 +0100 Subject: [PATCH 077/163] Adapt to deprecation of rejectIllegalHeader Closes gh-35442 --- .../boot/autoconfigure/web/ServerProperties.java | 2 ++ .../web/embedded/TomcatWebServerFactoryCustomizer.java | 1 + .../web/embedded/TomcatWebServerFactoryCustomizerTests.java | 2 ++ 3 files changed, 5 insertions(+) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java index 49f160cbb735..060cebc0e44e 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java @@ -459,6 +459,7 @@ public static class Tomcat { /** * Whether to reject requests with illegal header names or values. */ + @Deprecated private boolean rejectIllegalHeader = true; /** @@ -612,6 +613,7 @@ public void setConnectionTimeout(Duration connectionTimeout) { this.connectionTimeout = connectionTimeout; } + @DeprecatedConfigurationProperty(reason = "The setting has been deprecated in Tomcat") public boolean isRejectIllegalHeader() { return this.rejectIllegalHeader; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizer.java index 2705680328ca..42a5dba82fa5 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizer.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizer.java @@ -220,6 +220,7 @@ private void customizeRelaxedQueryChars(ConfigurableTomcatWebServerFactory facto factory.addConnectorCustomizers((connector) -> connector.setProperty("relaxedQueryChars", relaxedChars)); } + @SuppressWarnings("deprecation") private void customizeRejectIllegalHeader(ConfigurableTomcatWebServerFactory factory, boolean rejectIllegalHeader) { factory.addConnectorCustomizers((connector) -> { ProtocolHandler handler = connector.getProtocolHandler(); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizerTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizerTests.java index 926a654ee382..1fe8acac2d98 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizerTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizerTests.java @@ -365,6 +365,8 @@ void disableRemoteIpValve() { } @Test + @Deprecated + @SuppressWarnings("deprecation") void testCustomizeRejectIllegalHeader() { bind("server.tomcat.reject-illegal-header=false"); customizeAndRunServer((server) -> assertThat( From 11a1de1e6431f65223c50ec229ef502e6c9082fb Mon Sep 17 00:00:00 2001 From: Junsu Park <101160207+JunJaBoy@users.noreply.github.com> Date: Wed, 17 May 2023 12:29:35 +0900 Subject: [PATCH 078/163] Improve formatting of Kotlin permitAll example See gh-35454 --- .../endpoints/security/exposeall/MySecurityConfiguration.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/endpoints/security/exposeall/MySecurityConfiguration.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/endpoints/security/exposeall/MySecurityConfiguration.kt index f73ef895ee89..bacfe28c2da0 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/endpoints/security/exposeall/MySecurityConfiguration.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/endpoints/security/exposeall/MySecurityConfiguration.kt @@ -27,8 +27,9 @@ class MySecurityConfiguration { @Bean fun securityFilterChain(http: HttpSecurity): SecurityFilterChain { - http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests { - requests -> requests.anyRequest().permitAll() } + http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests { requests -> + requests.anyRequest().permitAll() + } return http.build() } From d66563d544d0c34f866e4c68727123e2af8ceb00 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 10:12:05 +0100 Subject: [PATCH 079/163] Polish "Improve formatting of Kotlin permitAll example" See gh-35454 --- .../endpoints/security/exposeall/MySecurityConfiguration.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/endpoints/security/exposeall/MySecurityConfiguration.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/endpoints/security/exposeall/MySecurityConfiguration.kt index bacfe28c2da0..e795b681b00c 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/endpoints/security/exposeall/MySecurityConfiguration.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/actuator/endpoints/security/exposeall/MySecurityConfiguration.kt @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From 038ec07cf23c5aad1b13865ff0503a0217f11664 Mon Sep 17 00:00:00 2001 From: Moritz Halbritter Date: Tue, 17 Jan 2023 10:32:36 +0100 Subject: [PATCH 080/163] Increase sleep duration after creating GitHub issue in Bomr See gh-30304 --- .../bomr/github/StandardGitHubRepository.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/github/StandardGitHubRepository.java b/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/github/StandardGitHubRepository.java index 2c9059f3ec4a..1920b10698f1 100644 --- a/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/github/StandardGitHubRepository.java +++ b/buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/github/StandardGitHubRepository.java @@ -16,6 +16,7 @@ package org.springframework.boot.build.bom.bomr.github; +import java.time.Duration; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -52,14 +53,10 @@ public int openIssue(String title, String body, List labels, Milestone m requestBody.put("labels", labels); } requestBody.put("body", body); - try { - Thread.sleep(1000); - } - catch (InterruptedException ex) { - Thread.currentThread().interrupt(); - } try { ResponseEntity response = this.rest.postForEntity("issues", requestBody, Map.class); + // See gh-30304 + sleep(Duration.ofSeconds(3)); return (Integer) response.getBody().get("number"); } catch (RestClientException ex) { @@ -96,4 +93,13 @@ private List get(String name, Function, T> mapper) { return body.stream().map(mapper).collect(Collectors.toList()); } + private static void sleep(Duration duration) { + try { + Thread.sleep(duration.toMillis()); + } + catch (InterruptedException ex) { + Thread.currentThread().interrupt(); + } + } + } From 6bbc416616ab0758db7ad174f4b861c0126af0b8 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:26:19 +0100 Subject: [PATCH 081/163] Upgrade to ActiveMQ 5.16.6 Closes gh-35461 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 6913f288dd75..c5e5dc6fab04 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -14,7 +14,7 @@ bom { issueLabels = ["type: dependency-upgrade"] } } - library("ActiveMQ", "5.16.5") { + library("ActiveMQ", "5.16.6") { group("org.apache.activemq") { modules = [ "activemq-amqp", From 6e131fb904e6db31bdc6b01bf7e390768b99a5f1 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:26:21 +0100 Subject: [PATCH 082/163] Upgrade to AppEngine SDK 1.9.98 Closes gh-35462 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index c5e5dc6fab04..c57711603ccc 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -63,7 +63,7 @@ bom { ] } } - library("AppEngine SDK", "1.9.96") { + library("AppEngine SDK", "1.9.98") { group("com.google.appengine") { modules = [ "appengine-api-1.0-sdk" From eaf6831e92ae3ac34937dc33e57ee47779ee80f4 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:26:24 +0100 Subject: [PATCH 083/163] Upgrade to Dependency Management Plugin 1.0.15.RELEASE Closes gh-35463 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index c57711603ccc..6a867c0d9c23 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -233,7 +233,7 @@ bom { ] } } - library("Dependency Management Plugin", "1.0.11.RELEASE") { + library("Dependency Management Plugin", "1.0.15.RELEASE") { group("io.spring.gradle") { modules = [ "dependency-management-plugin" From ed7badc2d1456d188ab1e585851c7878edc96ba1 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:26:27 +0100 Subject: [PATCH 084/163] Upgrade to Dropwizard Metrics 4.1.36 Closes gh-35464 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 6a867c0d9c23..4cd62a3f265c 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -251,7 +251,7 @@ bom { ] } } - library("Dropwizard Metrics", "4.1.31") { + library("Dropwizard Metrics", "4.1.36") { group("io.dropwizard.metrics") { imports = [ "metrics-bom" From acad5b93d8b28d1596c9c7e6208e909c049bf353 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:26:30 +0100 Subject: [PATCH 085/163] Upgrade to Ehcache3 3.9.11 Closes gh-35465 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 4cd62a3f265c..64db705bc897 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -265,7 +265,7 @@ bom { ] } } - library("Ehcache3", "3.9.9") { + library("Ehcache3", "3.9.10") { group("org.ehcache") { modules = [ "ehcache", From 6fb6fc2beca90f0dda19fa3ef8c1ed3d662664cd Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:26:32 +0100 Subject: [PATCH 086/163] Upgrade to FreeMarker 2.3.32 Closes gh-35466 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 64db705bc897..dd75659112f3 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -322,7 +322,7 @@ bom { ] } } - library("FreeMarker", "2.3.31") { + library("FreeMarker", "2.3.32") { group("org.freemarker") { modules = [ "freemarker" From 18c27f9a2ea70ef048bbf34ae0985c24390e994d Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:26:35 +0100 Subject: [PATCH 087/163] Upgrade to Glassfish JAXB 2.3.8 Closes gh-35467 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index dd75659112f3..48647b023ad9 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -346,7 +346,7 @@ bom { ] } } - library("Glassfish JAXB", "2.3.6") { + library("Glassfish JAXB", "2.3.8") { prohibit("[3.0.0-M1,)") { because "it uses the jakarta.* namespace" } From ee8c635083112625a5065e3c3743ff086903766c Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:26:38 +0100 Subject: [PATCH 088/163] Upgrade to Groovy 3.0.17 Closes gh-35468 --- .../ResolveDependencyCoordinatesTransformationTests.java | 8 +++++--- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/ResolveDependencyCoordinatesTransformationTests.java b/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/ResolveDependencyCoordinatesTransformationTests.java index cbea73ba22fc..99e918574e66 100644 --- a/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/ResolveDependencyCoordinatesTransformationTests.java +++ b/spring-boot-project/spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/ResolveDependencyCoordinatesTransformationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,6 +37,8 @@ import org.codehaus.groovy.ast.stmt.ExpressionStatement; import org.codehaus.groovy.control.SourceUnit; import org.codehaus.groovy.control.io.ReaderSource; +import org.codehaus.groovy.syntax.Token; +import org.codehaus.groovy.syntax.Types; import org.codehaus.groovy.transform.ASTTransformation; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -195,8 +197,8 @@ void transformationOfAnnotationOnLocalVariable() { ClassNode classNode = new ClassNode("Test", 0, new ClassNode(Object.class)); this.moduleNode.addClass(classNode); - DeclarationExpression declarationExpression = new DeclarationExpression(new VariableExpression("test"), null, - new ConstantExpression("test")); + DeclarationExpression declarationExpression = new DeclarationExpression(new VariableExpression("test"), + new Token(Types.ASSIGN, "=", 1, 1), new ConstantExpression("test")); declarationExpression.addAnnotation(this.grabAnnotation); BlockStatement code = new BlockStatement(Arrays.asList(new ExpressionStatement(declarationExpression)), diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 48647b023ad9..1f433c312231 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -370,7 +370,7 @@ bom { ] } } - library("Groovy", "3.0.10") { + library("Groovy", "3.0.17") { group("org.codehaus.groovy") { imports = [ "groovy-bom" From 8f9fc7e38de7bf9bda5a4d4901e50f8768a3a8dc Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:26:41 +0100 Subject: [PATCH 089/163] Upgrade to Hazelcast 4.1.10 Closes gh-35469 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 1f433c312231..3bd07c2215a9 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -400,7 +400,7 @@ bom { ] } } - library("Hazelcast", "4.1.9") { + library("Hazelcast", "4.1.10") { group("com.hazelcast") { modules = [ "hazelcast", From 325ff6e518c380b04e2370f5841197f1c22dd04b Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:26:44 +0100 Subject: [PATCH 090/163] Upgrade to Hibernate Validator 6.2.5.Final Closes gh-35470 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 3bd07c2215a9..0557446a0e7c 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -439,7 +439,7 @@ bom { ] } } - library("Hibernate Validator", "6.2.3.Final") { + library("Hibernate Validator", "6.2.5.Final") { prohibit("[7.0.0.Alpha1,)") { because "it uses the jakarta.* namespace" } From 01647600ff302f5e3016ee625eef9fe222de45a8 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:26:48 +0100 Subject: [PATCH 091/163] Upgrade to HttpClient 4.5.14 Closes gh-35471 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 0557446a0e7c..2b11486943a2 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -485,7 +485,7 @@ bom { ] } } - library("HttpClient", "4.5.13") { + library("HttpClient", "4.5.14") { group("org.apache.httpcomponents") { modules = [ "fluent-hc", From d0017f18affb3e3c5a6f3c76a716fdfc7dcfa93c Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:26:50 +0100 Subject: [PATCH 092/163] Upgrade to HttpCore 4.4.16 Closes gh-35472 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 2b11486943a2..99fe9568d7ee 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -509,7 +509,7 @@ bom { ] } } - library("HttpCore", "4.4.15") { + library("HttpCore", "4.4.16") { group("org.apache.httpcomponents") { modules = [ "httpcore", From 1b0a6a286fb869b8a46982bdb5bc7b7f4d9e0e11 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:26:53 +0100 Subject: [PATCH 093/163] Upgrade to HttpCore5 5.1.5 Closes gh-35473 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 99fe9568d7ee..4f867e36bbf8 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -517,7 +517,7 @@ bom { ] } } - library("HttpCore5", "5.1.3") { + library("HttpCore5", "5.1.5") { group("org.apache.httpcomponents.core5") { modules = [ "httpcore5", From e278990ebda0cf98c52f1817bf657b51207d5978 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:26:56 +0100 Subject: [PATCH 094/163] Upgrade to Infinispan 12.1.14.Final Closes gh-35474 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 4f867e36bbf8..411620cb4dfe 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -526,7 +526,7 @@ bom { ] } } - library("Infinispan", "12.1.11.Final") { + library("Infinispan", "12.1.14.Final") { group("org.infinispan") { imports = [ "infinispan-bom" From 9e169b5c3dbb8ab410b5d4b4ba453d47dcb1fc75 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:26:59 +0100 Subject: [PATCH 095/163] Upgrade to Jackson Bom 2.12.7.20221012 Closes gh-35475 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 411620cb4dfe..2da5b863ba28 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -540,7 +540,7 @@ bom { ] } } - library("Jackson Bom", "2.12.6.20220326") { + library("Jackson Bom", "2.12.7.20221012") { group("com.fasterxml.jackson") { imports = [ "jackson-bom" From 4f7abfdec2f0e590bc02a76c6232f6d2f8925265 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:27:01 +0100 Subject: [PATCH 096/163] Upgrade to Janino 3.1.9 Closes gh-35476 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 2da5b863ba28..e17d8a1d7b60 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -719,7 +719,7 @@ bom { ] } } - library("Janino", "3.1.7") { + library("Janino", "3.1.9") { group("org.codehaus.janino") { modules = [ "commons-compiler", From 82805bbd8d59c8312a852ab7bb85b825757b36c7 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:27:04 +0100 Subject: [PATCH 097/163] Upgrade to Jaybird 4.0.9.java8 Closes gh-35477 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index e17d8a1d7b60..f7ad12cf5e8f 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -833,7 +833,7 @@ bom { ] } } - library("Jaybird", "4.0.6.java8") { + library("Jaybird", "4.0.9.java8") { group("org.firebirdsql.jdbc") { modules = [ "jaybird", From f10685b73ab394f64c507ec498c6e79be3a5833d Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:27:07 +0100 Subject: [PATCH 098/163] Upgrade to Jetty Reactive HTTPClient 1.1.14 Closes gh-35478 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index f7ad12cf5e8f..fb4dd1b74c21 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -893,7 +893,7 @@ bom { ] } } - library("Jetty Reactive HTTPClient", "1.1.11") { + library("Jetty Reactive HTTPClient", "1.1.14") { prohibit("[2,)") { because "it uses the jakarta.* namespace" } From 1723ed338592b770fb4bc1b3d86013825d672ecc Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:27:09 +0100 Subject: [PATCH 099/163] Upgrade to Jetty 9.4.51.v20230217 Closes gh-35479 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index fb4dd1b74c21..22f6771d0391 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -903,7 +903,7 @@ bom { ] } } - library("Jetty", "9.4.46.v20220331") { + library("Jetty", "9.4.51.v20230217") { prohibit("[11.0.0-alpha0,)") { because "it uses the jakarta.* namespace" } From 8fafd886ccde3ff156fbdfd2cd10650de3993348 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:27:12 +0100 Subject: [PATCH 100/163] Upgrade to Johnzon 1.2.20 Closes gh-35480 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 22f6771d0391..e759174481d8 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -920,7 +920,7 @@ bom { ] } } - library("Johnzon", "1.2.18") { + library("Johnzon", "1.2.20") { group("org.apache.johnzon") { modules = [ "johnzon-core", From fe114892e433abd2b4ac9e287aecc1fcd2b2eec4 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:42:08 +0100 Subject: [PATCH 101/163] Upgrade to jOOQ 3.14.16 Closes gh-35481 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index e759174481d8..bf1cf6225aef 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -943,7 +943,7 @@ bom { ] } } - library("jOOQ", "3.14.15") { + library("jOOQ", "3.14.16") { group("org.jooq") { modules = [ "jooq", From 3721328120a4f54c6517b2df74d2f733c8a24568 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:42:12 +0100 Subject: [PATCH 102/163] Upgrade to Json-smart 2.4.10 Closes gh-35482 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index bf1cf6225aef..580fd75b1a0e 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -964,7 +964,7 @@ bom { ] } } - library("Json-smart", "2.4.8") { + library("Json-smart", "2.4.10") { group("net.minidev") { modules = [ "json-smart" From db8100209d71055e41cf9256c42d6aa25480e698 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:42:17 +0100 Subject: [PATCH 103/163] Upgrade to JsonAssert 1.5.1 Closes gh-35483 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 580fd75b1a0e..3f0d3b31b7f5 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -971,7 +971,7 @@ bom { ] } } - library("JsonAssert", "1.5.0") { + library("JsonAssert", "1.5.1") { group("org.skyscreamer") { modules = [ "jsonassert" From 924ee4e0004c906a3c64eb079689573ba0d2fc4b Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:42:22 +0100 Subject: [PATCH 104/163] Upgrade to Lettuce 6.1.10.RELEASE Closes gh-35484 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 3f0d3b31b7f5..d115333a9365 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1058,7 +1058,7 @@ bom { ] } } - library("Lettuce", "6.1.8.RELEASE") { + library("Lettuce", "6.1.10.RELEASE") { group("io.lettuce") { modules = [ "lettuce-core" From 31dee5dc23a23307d3276090dafbb151edf4d753 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:42:27 +0100 Subject: [PATCH 105/163] Upgrade to Logback 1.2.12 Closes gh-35485 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index d115333a9365..65d1bc3fb50e 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1083,7 +1083,7 @@ bom { ] } } - library("Logback", "1.2.11") { + library("Logback", "1.2.12") { group("ch.qos.logback") { modules = [ "logback-access", From 310d8a919b2cc569901c41e84764abcd18397aae Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:42:31 +0100 Subject: [PATCH 106/163] Upgrade to Lombok 1.18.26 Closes gh-35486 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 65d1bc3fb50e..c7431fbf6535 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1092,7 +1092,7 @@ bom { ] } } - library("Lombok", "1.18.24") { + library("Lombok", "1.18.26") { group("org.projectlombok") { modules = [ "lombok" From 22ed3744b22c2743dbb90990fe8a0cd490a278a5 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:42:36 +0100 Subject: [PATCH 107/163] Upgrade to MariaDB 2.7.9 Closes gh-35487 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index c7431fbf6535..e28461845df5 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1099,7 +1099,7 @@ bom { ] } } - library("MariaDB", "2.7.5") { + library("MariaDB", "2.7.9") { group("org.mariadb.jdbc") { modules = [ "mariadb-java-client" From c680e430b02966bbdf0a3707c57c0c112d239e5b Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:42:41 +0100 Subject: [PATCH 108/163] Upgrade to MySQL 8.0.33 Closes gh-35488 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index e28461845df5..6efe062f6ecb 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1278,7 +1278,7 @@ bom { ] } } - library("MySQL", "8.0.29") { + library("MySQL", "8.0.33") { group("mysql") { modules = [ "mysql-connector-java" { From 5094681e3f9c2e6a048c5ee2b0abff7e9fc88b1c Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:42:46 +0100 Subject: [PATCH 109/163] Upgrade to Netty 4.1.92.Final Closes gh-35489 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 6efe062f6ecb..fda026b6d386 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1301,7 +1301,7 @@ bom { ] } } - library("Netty", "4.1.77.Final") { + library("Netty", "4.1.92.Final") { group("io.netty") { imports = [ "netty-bom" From d898520c4c3d0d73ee8d9506e0d520d268795fd8 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:42:50 +0100 Subject: [PATCH 110/163] Upgrade to Netty tcNative 2.0.61.Final Closes gh-35490 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index fda026b6d386..841bb837eed8 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1308,7 +1308,7 @@ bom { ] } } - library("Netty tcNative", "2.0.52.Final") { + library("Netty tcNative", "2.0.61.Final") { group("io.netty") { modules = [ "netty-tcnative", From 0e13c1664d99116cccfbf135944549d21431373c Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:42:55 +0100 Subject: [PATCH 111/163] Upgrade to Postgresql 42.2.27 Closes gh-35491 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 841bb837eed8..fcd5b9230a79 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1417,7 +1417,7 @@ bom { ] } } - library("Postgresql", "42.2.25") { + library("Postgresql", "42.2.27") { group("org.postgresql") { modules = [ "postgresql" From e48a29298850dea25097ca6348a5c171f111115c Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:43:00 +0100 Subject: [PATCH 112/163] Upgrade to Reactive Streams 1.0.4 Closes gh-35492 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index fcd5b9230a79..110503c6e763 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1469,7 +1469,7 @@ bom { ] } } - library("Reactive Streams", "1.0.3") { + library("Reactive Streams", "1.0.4") { group("org.reactivestreams") { modules = [ "reactive-streams" From dd32fd4a4943a0baec4defdb4c4d3b6a0e45e10d Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:43:04 +0100 Subject: [PATCH 113/163] Upgrade to Reactor Bom 2020.0.32 Closes gh-35493 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 110503c6e763..c3607820cd3f 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1476,7 +1476,7 @@ bom { ] } } - library("Reactor Bom", "2020.0.19") { + library("Reactor Bom", "2020.0.32") { group("io.projectreactor") { imports = [ "reactor-bom" From 2598417d3dd6fb9570fa36f153fe840f7fd262b5 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:43:09 +0100 Subject: [PATCH 114/163] Upgrade to RSocket 1.1.3 Closes gh-35494 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index c3607820cd3f..5824d5bcd357 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1496,7 +1496,7 @@ bom { ] } } - library("RSocket", "1.1.2") { + library("RSocket", "1.1.3") { group("io.rsocket") { imports = [ "rsocket-bom" From c575aac67d47b2c4abac38b778a4c1d58a820aa3 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:43:13 +0100 Subject: [PATCH 115/163] Upgrade to Spring Batch 4.3.8 Closes gh-35495 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 5824d5bcd357..862e65d24804 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1699,7 +1699,7 @@ bom { ] } } - library("Spring Batch", "4.3.6") { + library("Spring Batch", "4.3.8") { group("org.springframework.batch") { modules = [ "spring-batch-core", From b00b2ea2c596eb091d475c51d1607d0167f37df2 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:43:18 +0100 Subject: [PATCH 116/163] Upgrade to Spring Data Bom 2021.0.12 Closes gh-35496 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 862e65d24804..ef1e90c7ace8 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1709,7 +1709,7 @@ bom { ] } } - library("Spring Data Bom", "2021.0.11") { + library("Spring Data Bom", "2021.0.12") { group("org.springframework.data") { imports = [ "spring-data-bom" From cf1dc6dae18af3989e99f8a506423270f9320345 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:43:23 +0100 Subject: [PATCH 117/163] Upgrade to Spring Framework 5.3.27 Closes gh-35497 --- .../jdbc/HikariDriverConfigurationFailureAnalyzer.java | 8 ++++---- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/HikariDriverConfigurationFailureAnalyzer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/HikariDriverConfigurationFailureAnalyzer.java index 30d4d4aa58cb..9e04c28871d2 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/HikariDriverConfigurationFailureAnalyzer.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/HikariDriverConfigurationFailureAnalyzer.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,12 +28,12 @@ */ class HikariDriverConfigurationFailureAnalyzer extends AbstractFailureAnalyzer { - private static final String EXPECTED_MESSAGE = "Failed to obtain JDBC Connection:" - + " cannot use driverClassName and dataSourceClassName together."; + private static final String EXPECTED_MESSAGE = "cannot use driverClassName and dataSourceClassName together."; @Override protected FailureAnalysis analyze(Throwable rootFailure, CannotGetJdbcConnectionException cause) { - if (!EXPECTED_MESSAGE.equals(cause.getMessage())) { + Throwable subCause = cause.getCause(); + if (subCause == null || !EXPECTED_MESSAGE.equals(subCause.getMessage())) { return null; } return new FailureAnalysis( diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index ef1e90c7ace8..c3dd406c49d2 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1716,7 +1716,7 @@ bom { ] } } - library("Spring Framework", "5.3.20") { + library("Spring Framework", "5.3.27") { group("org.springframework") { imports = [ "spring-framework-bom" From 9972c4030bea6954cb41c695de52b89bf37272d8 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:43:28 +0100 Subject: [PATCH 118/163] Upgrade to Spring Integration 5.5.18 Closes gh-35498 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index c3dd406c49d2..6cea51c9f3b4 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1730,7 +1730,7 @@ bom { ] } } - library("Spring Integration", "5.5.12") { + library("Spring Integration", "5.5.18") { group("org.springframework.integration") { imports = [ "spring-integration-bom" From 917bb230cedc32f8a11f046ab562aaa116220a35 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:43:32 +0100 Subject: [PATCH 119/163] Upgrade to Spring RESTDocs 2.0.7.RELEASE Closes gh-35499 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 6cea51c9f3b4..24ca0657a047 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1757,7 +1757,7 @@ bom { ] } } - library("Spring RESTDocs", "2.0.6.RELEASE") { + library("Spring RESTDocs", "2.0.7.RELEASE") { group("org.springframework.restdocs") { modules = [ "spring-restdocs-asciidoctor", From 1f490c7f79ad98e883f22cc4dfecb0f1952057db Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:43:37 +0100 Subject: [PATCH 120/163] Upgrade to Spring Retry 1.3.4 Closes gh-35500 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 24ca0657a047..47882ae7b666 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1768,7 +1768,7 @@ bom { ] } } - library("Spring Retry", "1.3.3") { + library("Spring Retry", "1.3.4") { group("org.springframework.retry") { modules = [ "spring-retry" From d73a6cc3feef8c2d1e4e74cea612d33e00ff23d4 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:43:41 +0100 Subject: [PATCH 121/163] Upgrade to Spring WS 3.1.6 Closes gh-35501 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 47882ae7b666..4fada84ad095 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1794,7 +1794,7 @@ bom { ] } } - library("Spring WS", "3.1.3") { + library("Spring WS", "3.1.6") { group("org.springframework.ws") { modules = [ "spring-ws-core", From 6967a641ab17dddd31f89e8187029ec5a073ba0b Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:43:46 +0100 Subject: [PATCH 122/163] Upgrade to Thymeleaf Extras SpringSecurity 3.0.5.RELEASE Closes gh-35502 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 4fada84ad095..57b27038e110 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1844,7 +1844,7 @@ bom { ] } } - library("Thymeleaf Extras SpringSecurity", "3.0.4.RELEASE") { + library("Thymeleaf Extras SpringSecurity", "3.0.5.RELEASE") { group("org.thymeleaf.extras") { modules = [ "thymeleaf-extras-springsecurity5" From 93d571b0169840353e28ea8f543d43f29606f00a Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:43:51 +0100 Subject: [PATCH 123/163] Upgrade to Tomcat 9.0.75 Closes gh-35503 --- gradle.properties | 2 +- .../boot/autoconfigure/web/ServerProperties.java | 9 +++++++-- .../TomcatWebServerFactoryCustomizerTests.java | 7 ++++++- .../boot/web/embedded/tomcat/TldPatterns.java | 13 ++++++++++--- 4 files changed, 24 insertions(+), 7 deletions(-) diff --git a/gradle.properties b/gradle.properties index de8119e44547..6bb265d9b8b7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,6 +5,6 @@ org.gradle.parallel=true org.gradle.jvmargs=-Xmx2g -Dfile.encoding=UTF-8 kotlinVersion=1.5.32 -tomcatVersion=9.0.63 +tomcatVersion=9.0.75 kotlin.stdlib.default.dependency=false diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java index 1b5456129d6d..f39618dbc1da 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -900,8 +900,13 @@ public static class Remoteip { + "192\\.168\\.\\d{1,3}\\.\\d{1,3}|" // 192.168/16 + "169\\.254\\.\\d{1,3}\\.\\d{1,3}|" // 169.254/16 + "127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|" // 127/8 + + "100\\.6[4-9]{1}\\.\\d{1,3}\\.\\d{1,3}|" // 100.64.0.0/10 + + "100\\.[7-9]{1}\\d{1}\\.\\d{1,3}\\.\\d{1,3}|" // 100.64.0.0/10 + + "100\\.1[0-1]{1}\\d{1}\\.\\d{1,3}\\.\\d{1,3}|" // 100.64.0.0/10 + + "100\\.12[0-7]{1}\\.\\d{1,3}\\.\\d{1,3}|" // 100.64.0.0/10 + "172\\.1[6-9]{1}\\.\\d{1,3}\\.\\d{1,3}|" // 172.16/12 - + "172\\.2[0-9]{1}\\.\\d{1,3}\\.\\d{1,3}|172\\.3[0-1]{1}\\.\\d{1,3}\\.\\d{1,3}|" // + + "172\\.2[0-9]{1}\\.\\d{1,3}\\.\\d{1,3}|" // 172.16/12 + + "172\\.3[0-1]{1}\\.\\d{1,3}\\.\\d{1,3}|" // 172.16/12 + "0:0:0:0:0:0:0:1|::1"; /** diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizerTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizerTests.java index 5e3015b81114..b99c79b21bc0 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizerTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizerTests.java @@ -318,8 +318,13 @@ private void testRemoteIpValveConfigured() { + "192\\.168\\.\\d{1,3}\\.\\d{1,3}|" // 192.168/16 + "169\\.254\\.\\d{1,3}\\.\\d{1,3}|" // 169.254/16 + "127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|" // 127/8 + + "100\\.6[4-9]{1}\\.\\d{1,3}\\.\\d{1,3}|" // 100.64.0.0/10 + + "100\\.[7-9]{1}\\d{1}\\.\\d{1,3}\\.\\d{1,3}|" // 100.64.0.0/10 + + "100\\.1[0-1]{1}\\d{1}\\.\\d{1,3}\\.\\d{1,3}|" // 100.64.0.0/10 + + "100\\.12[0-7]{1}\\.\\d{1,3}\\.\\d{1,3}|" // 100.64.0.0/10 + "172\\.1[6-9]{1}\\.\\d{1,3}\\.\\d{1,3}|" // 172.16/12 - + "172\\.2[0-9]{1}\\.\\d{1,3}\\.\\d{1,3}|172\\.3[0-1]{1}\\.\\d{1,3}\\.\\d{1,3}|" // + + "172\\.2[0-9]{1}\\.\\d{1,3}\\.\\d{1,3}|" // 172.16/12 + + "172\\.3[0-1]{1}\\.\\d{1,3}\\.\\d{1,3}|" // 172.16/12 + "0:0:0:0:0:0:0:1|::1"; assertThat(remoteIpValve.getInternalProxies()).isEqualTo(expectedInternalProxies); } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TldPatterns.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TldPatterns.java index fd1b8f4f60cf..8b61d67dfcc7 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TldPatterns.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TldPatterns.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,10 +35,12 @@ final class TldPatterns { Set skipPatterns = new LinkedHashSet<>(); skipPatterns.add("annotations-api.jar"); skipPatterns.add("ant-junit*.jar"); - skipPatterns.add("ant-launcher.jar"); - skipPatterns.add("ant.jar"); + skipPatterns.add("ant-launcher*.jar"); + skipPatterns.add("ant*.jar"); skipPatterns.add("asm-*.jar"); skipPatterns.add("aspectj*.jar"); + skipPatterns.add("bcel*.jar"); + skipPatterns.add("biz.aQute.bnd*.jar"); skipPatterns.add("bootstrap.jar"); skipPatterns.add("catalina-ant.jar"); skipPatterns.add("catalina-ha.jar"); @@ -51,6 +53,7 @@ final class TldPatterns { skipPatterns.add("commons-beanutils*.jar"); skipPatterns.add("commons-codec*.jar"); skipPatterns.add("commons-collections*.jar"); + skipPatterns.add("commons-compress*.jar"); skipPatterns.add("commons-daemon.jar"); skipPatterns.add("commons-dbcp*.jar"); skipPatterns.add("commons-digester*.jar"); @@ -92,6 +95,8 @@ final class TldPatterns { skipPatterns.add("mail*.jar"); skipPatterns.add("objenesis-*.jar"); skipPatterns.add("oraclepki.jar"); + skipPatterns.add("org.hamcrest.core_*.jar"); + skipPatterns.add("org.junit_*.jar"); skipPatterns.add("oro-*.jar"); skipPatterns.add("servlet-api-*.jar"); skipPatterns.add("servlet-api.jar"); @@ -110,6 +115,7 @@ final class TldPatterns { skipPatterns.add("tomcat-util.jar"); skipPatterns.add("tomcat-websocket.jar"); skipPatterns.add("tools.jar"); + skipPatterns.add("unboundid-ldapsdk-*.jar"); skipPatterns.add("websocket-api.jar"); skipPatterns.add("wsdl4j*.jar"); skipPatterns.add("xercesImpl.jar"); @@ -117,6 +123,7 @@ final class TldPatterns { skipPatterns.add("xmlParserAPIs-*.jar"); skipPatterns.add("xmlParserAPIs.jar"); skipPatterns.add("xom-*.jar"); + TOMCAT_SKIP = Collections.unmodifiableSet(skipPatterns); } From e1663e209756dad33dfe61faae66178e5a7fe6da Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 18:43:56 +0100 Subject: [PATCH 124/163] Upgrade to Undertow 2.2.24.Final Closes gh-35504 --- .../web/embedded/UndertowWebServerFactoryCustomizer.java | 3 ++- .../web/embedded/UndertowWebServerFactoryCustomizerTests.java | 1 + spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/UndertowWebServerFactoryCustomizer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/UndertowWebServerFactoryCustomizer.java index 8f291b1a220c..f8bca9b75468 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/UndertowWebServerFactoryCustomizer.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/UndertowWebServerFactoryCustomizer.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -85,6 +85,7 @@ public void customize(ConfigurableUndertowWebServerFactory factory) { map.from(this::getOrDeduceUseForwardHeaders).to(factory::setUseForwardHeaders); } + @SuppressWarnings("deprecation") private void mapUndertowProperties(ConfigurableUndertowWebServerFactory factory, ServerOptions serverOptions) { PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); Undertow properties = this.serverProperties.getUndertow(); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/UndertowWebServerFactoryCustomizerTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/UndertowWebServerFactoryCustomizerTests.java index 7b544fb3e6ba..1e070451e42c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/UndertowWebServerFactoryCustomizerTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/UndertowWebServerFactoryCustomizerTests.java @@ -150,6 +150,7 @@ void customizeWorkerThreads() { } @Test + @SuppressWarnings("deprecation") void allowEncodedSlashes() { bind("server.undertow.allow-encoded-slash=true"); assertThat(boundServerOption(UndertowOptions.ALLOW_ENCODED_SLASH)).isTrue(); diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 57b27038e110..cf0088274697 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1885,7 +1885,7 @@ bom { ] } } - library("Undertow", "2.2.17.Final") { + library("Undertow", "2.2.24.Final") { group("io.undertow") { modules = [ "undertow-core", From 61d836012964f664e5f95fb6747f27e2b6c5bdf2 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 21:23:06 +0100 Subject: [PATCH 125/163] Upgrade to ActiveMQ 5.16.6 Closes gh-35507 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 27d8b623638f..9bfda9211b7e 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -14,7 +14,7 @@ bom { issueLabels = ["type: dependency-upgrade"] } } - library("ActiveMQ", "5.16.5") { + library("ActiveMQ", "5.16.6") { group("org.apache.activemq") { modules = [ "activemq-amqp", From c1d7d5031dafb0689dfe7f866079659b602d9c19 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 21:23:11 +0100 Subject: [PATCH 126/163] Upgrade to Dropwizard Metrics 4.2.18 Closes gh-35508 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 9bfda9211b7e..96f752922e1a 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -258,7 +258,7 @@ bom { ] } } - library("Dropwizard Metrics", "4.2.13") { + library("Dropwizard Metrics", "4.2.18") { group("io.dropwizard.metrics") { imports = [ "metrics-bom" From d0c4eb7fb691b4ae24386c07c21fc7763e35c463 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 21:23:16 +0100 Subject: [PATCH 127/163] Upgrade to FreeMarker 2.3.32 Closes gh-35509 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 96f752922e1a..5419eae6172d 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -329,7 +329,7 @@ bom { ] } } - library("FreeMarker", "2.3.31") { + library("FreeMarker", "2.3.32") { group("org.freemarker") { modules = [ "freemarker" From b034ea28253689b6c1c422220a254a8e52517a53 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 21:23:20 +0100 Subject: [PATCH 128/163] Upgrade to Glassfish JAXB 2.3.8 Closes gh-35510 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 5419eae6172d..63b9dce94478 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -356,7 +356,7 @@ bom { ] } } - library("Glassfish JAXB", "2.3.7") { + library("Glassfish JAXB", "2.3.8") { prohibit("[3.0.0-M1,)") { because "it uses the jakarta.* namespace" } From 6ca20b87f77ac4a57ee6fe4bdb33e4dadd6677ae Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 21:23:26 +0100 Subject: [PATCH 129/163] Upgrade to Groovy 3.0.17 Closes gh-35511 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 63b9dce94478..1f0618227441 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -380,7 +380,7 @@ bom { ] } } - library("Groovy", "3.0.13") { + library("Groovy", "3.0.17") { group("org.codehaus.groovy") { imports = [ "groovy-bom" From 5921106b94d2449666afbe2529abe66f2d2670ec Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 21:23:30 +0100 Subject: [PATCH 130/163] Upgrade to Hazelcast 4.2.7 Closes gh-35512 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 1f0618227441..7d8f214b7442 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -410,7 +410,7 @@ bom { ] } } - library("Hazelcast", "4.2.5") { + library("Hazelcast", "4.2.7") { group("com.hazelcast") { modules = [ "hazelcast", From 67677370c2da340dbcd316acaa7450090d7083a2 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 21:23:35 +0100 Subject: [PATCH 131/163] Upgrade to Hibernate 5.6.15.Final Closes gh-35513 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 7d8f214b7442..443486d27787 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -426,7 +426,7 @@ bom { ] } } - library("Hibernate", "5.6.14.Final") { + library("Hibernate", "5.6.15.Final") { prohibit("[6.0.0.Alpha2,)") { because "it uses the jakarta.* namespace" } From 408e6f35b52c20f2ecf06399f97d7171ffd5c281 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 21:23:40 +0100 Subject: [PATCH 132/163] Upgrade to HttpClient 4.5.14 Closes gh-35514 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 443486d27787..5ce38849f901 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -498,7 +498,7 @@ bom { ] } } - library("HttpClient", "4.5.13") { + library("HttpClient", "4.5.14") { group("org.apache.httpcomponents") { modules = [ "fluent-hc", From 922409efd183e444fe24d91bbed452acb8f43463 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 21:23:45 +0100 Subject: [PATCH 133/163] Upgrade to HttpCore 4.4.16 Closes gh-35515 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 5ce38849f901..273e33bbdbcc 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -522,7 +522,7 @@ bom { ] } } - library("HttpCore", "4.4.15") { + library("HttpCore", "4.4.16") { group("org.apache.httpcomponents") { modules = [ "httpcore", From e4a72813114187ec001c80ddd4810016e4e6df4b Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 21:23:49 +0100 Subject: [PATCH 134/163] Upgrade to Infinispan 12.1.14.Final Closes gh-35516 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 273e33bbdbcc..42d2f5738e38 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -539,7 +539,7 @@ bom { ] } } - library("Infinispan", "12.1.12.Final") { + library("Infinispan", "12.1.14.Final") { group("org.infinispan") { imports = [ "infinispan-bom" From 8396e96f60807dae599c72cc85192241fcc32497 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 21:23:54 +0100 Subject: [PATCH 135/163] Upgrade to Jackson Bom 2.13.5 Closes gh-35517 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 42d2f5738e38..80e09b03fd70 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -553,7 +553,7 @@ bom { ] } } - library("Jackson Bom", "2.13.4.20221013") { + library("Jackson Bom", "2.13.5") { group("com.fasterxml.jackson") { imports = [ "jackson-bom" From 169072afdde66f444715ce24396427e6da671f00 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 21:23:59 +0100 Subject: [PATCH 136/163] Upgrade to Jaybird 4.0.9.java8 Closes gh-35518 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 80e09b03fd70..4622816d0e05 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -846,7 +846,7 @@ bom { ] } } - library("Jaybird", "4.0.7.java8") { + library("Jaybird", "4.0.9.java8") { group("org.firebirdsql.jdbc") { modules = [ "jaybird", From e6bea54696b5d4dfd1aebc21000651e7cb94cd8d Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 21:24:03 +0100 Subject: [PATCH 137/163] Upgrade to Jetty Reactive HTTPClient 1.1.14 Closes gh-35519 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 4622816d0e05..9efbaec32def 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -902,7 +902,7 @@ bom { ] } } - library("Jetty Reactive HTTPClient", "1.1.13") { + library("Jetty Reactive HTTPClient", "1.1.14") { prohibit("[2,)") { because "it uses the jakarta.* namespace" } From 176309f14cb45d55238f56b52d2764d7aaf6beb4 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 21:24:08 +0100 Subject: [PATCH 138/163] Upgrade to Jetty 9.4.51.v20230217 Closes gh-35520 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 9efbaec32def..8f6ebe99283a 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -912,7 +912,7 @@ bom { ] } } - library("Jetty", "9.4.49.v20220914") { + library("Jetty", "9.4.51.v20230217") { prohibit("[10.0.0-alpha0,)") { because "it requires Java 11" } From 788c3b6c2554cb44b9aaaab1d5fa73dcada79d69 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 21:24:13 +0100 Subject: [PATCH 139/163] Upgrade to Johnzon 1.2.20 Closes gh-35521 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 8f6ebe99283a..a195e6b40107 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -932,7 +932,7 @@ bom { ] } } - library("Johnzon", "1.2.19") { + library("Johnzon", "1.2.20") { group("org.apache.johnzon") { modules = [ "johnzon-core", From dbda252e29934397d4f6b7af5787d588a42a4901 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 21:24:18 +0100 Subject: [PATCH 140/163] Upgrade to Jolokia 1.7.2 Closes gh-35522 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index a195e6b40107..cac5ba122c18 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -948,7 +948,7 @@ bom { ] } } - library("Jolokia", "1.7.1") { + library("Jolokia", "1.7.2") { group("org.jolokia") { modules = [ "jolokia-core" From 57082451084be515943212f30bae87a71648c939 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 21:24:23 +0100 Subject: [PATCH 141/163] Upgrade to Json-smart 2.4.10 Closes gh-35523 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index cac5ba122c18..4ab26b7f6c86 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -979,7 +979,7 @@ bom { ] } } - library("Json-smart", "2.4.8") { + library("Json-smart", "2.4.10") { group("net.minidev") { modules = [ "json-smart" From 2ba3c874dd9d4ece432a589d64c8efe45175da41 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 21:24:28 +0100 Subject: [PATCH 142/163] Upgrade to Logback 1.2.12 Closes gh-35524 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 4ab26b7f6c86..b5f23cddf034 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1104,7 +1104,7 @@ bom { ] } } - library("Logback", "1.2.11") { + library("Logback", "1.2.12") { group("ch.qos.logback") { modules = [ "logback-access", From 462b2a2178aef835f7d1a9bf6768c77d9d749862 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 21:24:33 +0100 Subject: [PATCH 143/163] Upgrade to Lombok 1.18.26 Closes gh-35525 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index b5f23cddf034..f5a7461577a0 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1113,7 +1113,7 @@ bom { ] } } - library("Lombok", "1.18.24") { + library("Lombok", "1.18.26") { group("org.projectlombok") { modules = [ "lombok" From cb15f35dbf196ce6131ffa45e2e3c9170688eafd Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 21:24:38 +0100 Subject: [PATCH 144/163] Upgrade to MariaDB 2.7.9 Closes gh-35526 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index f5a7461577a0..dbbb872ec7ba 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1120,7 +1120,7 @@ bom { ] } } - library("MariaDB", "2.7.7") { + library("MariaDB", "2.7.9") { group("org.mariadb.jdbc") { modules = [ "mariadb-java-client" From a58763d0f3721b43e5c0c0657d94ce73530e0af5 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 21:24:43 +0100 Subject: [PATCH 145/163] Upgrade to Micrometer 1.8.13 Closes gh-35527 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index dbbb872ec7ba..8fb37572c963 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1253,7 +1253,7 @@ bom { ] } } - library("Micrometer", "1.8.12") { + library("Micrometer", "1.8.13") { group("io.micrometer") { modules = [ "micrometer-registry-stackdriver" { From 8d38bae1c3c4f0415e68ec75c70c14b0c380fc19 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 21:24:47 +0100 Subject: [PATCH 146/163] Upgrade to MySQL 8.0.33 Closes gh-35528 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 8fb37572c963..5c121c5ebef7 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1299,7 +1299,7 @@ bom { ] } } - library("MySQL", "8.0.31") { + library("MySQL", "8.0.33") { group("com.mysql") { modules = [ "mysql-connector-j" { From 63ced46171dd9fa9d7c8e3de64c893ead065da9e Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 21:24:53 +0100 Subject: [PATCH 147/163] Upgrade to Neo4j Java Driver 4.4.11 Closes gh-35529 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 5c121c5ebef7..e3ee4949d89e 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1322,7 +1322,7 @@ bom { ] } } - library("Neo4j Java Driver", "4.4.9") { + library("Neo4j Java Driver", "4.4.11") { group("org.neo4j.driver") { modules = [ "neo4j-java-driver" From 87aed1fafee5a6d8cffb8f8c5c4bc0bc6c408e2f Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 21:24:57 +0100 Subject: [PATCH 148/163] Upgrade to Netty 4.1.92.Final Closes gh-35530 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index e3ee4949d89e..158f8b6da471 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1329,7 +1329,7 @@ bom { ] } } - library("Netty", "4.1.85.Final") { + library("Netty", "4.1.92.Final") { group("io.netty") { imports = [ "netty-bom" From 09ce82b5a6222e732ff9b7ca21c4490e7caec48b Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 21:25:02 +0100 Subject: [PATCH 149/163] Upgrade to Netty tcNative 2.0.61.Final Closes gh-35531 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 158f8b6da471..37c6dbdb58bf 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1336,7 +1336,7 @@ bom { ] } } - library("Netty tcNative", "2.0.54.Final") { + library("Netty tcNative", "2.0.61.Final") { group("io.netty") { modules = [ "netty-tcnative", From d0bbf8433a10f018f5fe309acc35aafe668b44c3 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 21:25:07 +0100 Subject: [PATCH 150/163] Upgrade to Reactor Bom 2020.0.32 Closes gh-35532 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 37c6dbdb58bf..c4704aec4a45 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1467,7 +1467,7 @@ bom { ] } } - library("Reactor Bom", "2020.0.25") { + library("Reactor Bom", "2020.0.32") { group("io.projectreactor") { imports = [ "reactor-bom" From e5ef0682fba5e6e696a4346f02f0f7421c745e16 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 21:25:12 +0100 Subject: [PATCH 151/163] Upgrade to Spring AMQP 2.4.12 Closes gh-35533 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index c4704aec4a45..3a65dca05681 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1690,7 +1690,7 @@ bom { ] } } - library("Spring AMQP", "2.4.8") { + library("Spring AMQP", "2.4.12") { group("org.springframework.amqp") { modules = [ "spring-amqp", From e2cd60b213a0bec4497173e2703033df75e8667e Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 21:25:17 +0100 Subject: [PATCH 152/163] Upgrade to Spring Batch 4.3.8 Closes gh-35534 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 3a65dca05681..e5c220f7da05 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1701,7 +1701,7 @@ bom { ] } } - library("Spring Batch", "4.3.7") { + library("Spring Batch", "4.3.8") { group("org.springframework.batch") { modules = [ "spring-batch-core", From fa9a5a3a73548c6e463edec72cef18e9f84ea42f Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 21:25:22 +0100 Subject: [PATCH 153/163] Upgrade to Spring Framework 5.3.27 Closes gh-35535 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index e5c220f7da05..744126630088 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1718,7 +1718,7 @@ bom { ] } } - library("Spring Framework", "5.3.24") { + library("Spring Framework", "5.3.27") { group("org.springframework") { imports = [ "spring-framework-bom" From 83cbe3fc2ca75c00feeb37005a66a228047c4ffc Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 21:25:27 +0100 Subject: [PATCH 154/163] Upgrade to Spring Integration 5.5.18 Closes gh-35536 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 744126630088..b5c2ff7f3aa6 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1732,7 +1732,7 @@ bom { ] } } - library("Spring Integration", "5.5.15") { + library("Spring Integration", "5.5.18") { group("org.springframework.integration") { imports = [ "spring-integration-bom" From 1e5797f3502f9e26bb3b7f76ad48f016fa7816e9 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 21:25:32 +0100 Subject: [PATCH 155/163] Upgrade to Spring Security 5.6.10 Closes gh-35537 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index b5c2ff7f3aa6..633c10ce5601 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1777,7 +1777,7 @@ bom { ] } } - library("Spring Security", "5.6.9") { + library("Spring Security", "5.6.10") { group("org.springframework.security") { imports = [ "spring-security-bom" From ba7485bf48743beea994c9e70e542fbd8b0d3590 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 21:25:37 +0100 Subject: [PATCH 156/163] Upgrade to Spring WS 3.1.6 Closes gh-35538 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 633c10ce5601..638aee896e31 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1791,7 +1791,7 @@ bom { ] } } - library("Spring WS", "3.1.4") { + library("Spring WS", "3.1.6") { group("org.springframework.ws") { modules = [ "spring-ws-core", From 2e8ec62cd43a95d66672cf9ff793ad781536ddff Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 21:25:42 +0100 Subject: [PATCH 157/163] Upgrade to Thymeleaf Extras SpringSecurity 3.0.5.RELEASE Closes gh-35539 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 638aee896e31..321bbd3506c0 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1841,7 +1841,7 @@ bom { ] } } - library("Thymeleaf Extras SpringSecurity", "3.0.4.RELEASE") { + library("Thymeleaf Extras SpringSecurity", "3.0.5.RELEASE") { group("org.thymeleaf.extras") { modules = [ "thymeleaf-extras-springsecurity5" From 47f1fc57d9a34cb3da6ddc0157fba13c379a075f Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 21:25:47 +0100 Subject: [PATCH 158/163] Upgrade to Tomcat 9.0.75 Closes gh-35540 --- gradle.properties | 2 +- .../boot/autoconfigure/web/ServerProperties.java | 9 +++++++-- .../embedded/TomcatWebServerFactoryCustomizer.java | 1 + .../TomcatWebServerFactoryCustomizerTests.java | 8 +++++++- .../boot/web/embedded/tomcat/TldPatterns.java | 13 ++++++++++--- 5 files changed, 26 insertions(+), 7 deletions(-) diff --git a/gradle.properties b/gradle.properties index 94bb7995376e..52cf15dbd612 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,6 +5,6 @@ org.gradle.parallel=true org.gradle.jvmargs=-Xmx2g -Dfile.encoding=UTF-8 kotlinVersion=1.6.21 -tomcatVersion=9.0.69 +tomcatVersion=9.0.75 kotlin.stdlib.default.dependency=false diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java index e47c6adba615..41e633d12cf2 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -959,8 +959,13 @@ public static class Remoteip { + "192\\.168\\.\\d{1,3}\\.\\d{1,3}|" // 192.168/16 + "169\\.254\\.\\d{1,3}\\.\\d{1,3}|" // 169.254/16 + "127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|" // 127/8 + + "100\\.6[4-9]{1}\\.\\d{1,3}\\.\\d{1,3}|" // 100.64.0.0/10 + + "100\\.[7-9]{1}\\d{1}\\.\\d{1,3}\\.\\d{1,3}|" // 100.64.0.0/10 + + "100\\.1[0-1]{1}\\d{1}\\.\\d{1,3}\\.\\d{1,3}|" // 100.64.0.0/10 + + "100\\.12[0-7]{1}\\.\\d{1,3}\\.\\d{1,3}|" // 100.64.0.0/10 + "172\\.1[6-9]{1}\\.\\d{1,3}\\.\\d{1,3}|" // 172.16/12 - + "172\\.2[0-9]{1}\\.\\d{1,3}\\.\\d{1,3}|172\\.3[0-1]{1}\\.\\d{1,3}\\.\\d{1,3}|" // + + "172\\.2[0-9]{1}\\.\\d{1,3}\\.\\d{1,3}|" // 172.16/12 + + "172\\.3[0-1]{1}\\.\\d{1,3}\\.\\d{1,3}|" // 172.16/12 + "0:0:0:0:0:0:0:1|::1"; /** diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizer.java index deb41dff1476..db5b3ac13187 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizer.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizer.java @@ -201,6 +201,7 @@ private void customizeRelaxedQueryChars(ConfigurableTomcatWebServerFactory facto factory.addConnectorCustomizers((connector) -> connector.setProperty("relaxedQueryChars", relaxedChars)); } + @SuppressWarnings("deprecation") private void customizeRejectIllegalHeader(ConfigurableTomcatWebServerFactory factory, boolean rejectIllegalHeader) { factory.addConnectorCustomizers((connector) -> { ProtocolHandler handler = connector.getProtocolHandler(); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizerTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizerTests.java index a12d66738b07..cacd7a841478 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizerTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizerTests.java @@ -331,8 +331,13 @@ private void testRemoteIpValveConfigured() { + "192\\.168\\.\\d{1,3}\\.\\d{1,3}|" // 192.168/16 + "169\\.254\\.\\d{1,3}\\.\\d{1,3}|" // 169.254/16 + "127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|" // 127/8 + + "100\\.6[4-9]{1}\\.\\d{1,3}\\.\\d{1,3}|" // 100.64.0.0/10 + + "100\\.[7-9]{1}\\d{1}\\.\\d{1,3}\\.\\d{1,3}|" // 100.64.0.0/10 + + "100\\.1[0-1]{1}\\d{1}\\.\\d{1,3}\\.\\d{1,3}|" // 100.64.0.0/10 + + "100\\.12[0-7]{1}\\.\\d{1,3}\\.\\d{1,3}|" // 100.64.0.0/10 + "172\\.1[6-9]{1}\\.\\d{1,3}\\.\\d{1,3}|" // 172.16/12 - + "172\\.2[0-9]{1}\\.\\d{1,3}\\.\\d{1,3}|172\\.3[0-1]{1}\\.\\d{1,3}\\.\\d{1,3}|" // + + "172\\.2[0-9]{1}\\.\\d{1,3}\\.\\d{1,3}|" // 172.16/12 + + "172\\.3[0-1]{1}\\.\\d{1,3}\\.\\d{1,3}|" // 172.16/12 + "0:0:0:0:0:0:0:1|::1"; assertThat(remoteIpValve.getInternalProxies()).isEqualTo(expectedInternalProxies); } @@ -351,6 +356,7 @@ void disableRemoteIpValve() { } @Test + @SuppressWarnings("deprecation") void testCustomizeRejectIllegalHeader() { bind("server.tomcat.reject-illegal-header=false"); customizeAndRunServer((server) -> assertThat( diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TldPatterns.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TldPatterns.java index fd1b8f4f60cf..8b61d67dfcc7 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TldPatterns.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TldPatterns.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,10 +35,12 @@ final class TldPatterns { Set skipPatterns = new LinkedHashSet<>(); skipPatterns.add("annotations-api.jar"); skipPatterns.add("ant-junit*.jar"); - skipPatterns.add("ant-launcher.jar"); - skipPatterns.add("ant.jar"); + skipPatterns.add("ant-launcher*.jar"); + skipPatterns.add("ant*.jar"); skipPatterns.add("asm-*.jar"); skipPatterns.add("aspectj*.jar"); + skipPatterns.add("bcel*.jar"); + skipPatterns.add("biz.aQute.bnd*.jar"); skipPatterns.add("bootstrap.jar"); skipPatterns.add("catalina-ant.jar"); skipPatterns.add("catalina-ha.jar"); @@ -51,6 +53,7 @@ final class TldPatterns { skipPatterns.add("commons-beanutils*.jar"); skipPatterns.add("commons-codec*.jar"); skipPatterns.add("commons-collections*.jar"); + skipPatterns.add("commons-compress*.jar"); skipPatterns.add("commons-daemon.jar"); skipPatterns.add("commons-dbcp*.jar"); skipPatterns.add("commons-digester*.jar"); @@ -92,6 +95,8 @@ final class TldPatterns { skipPatterns.add("mail*.jar"); skipPatterns.add("objenesis-*.jar"); skipPatterns.add("oraclepki.jar"); + skipPatterns.add("org.hamcrest.core_*.jar"); + skipPatterns.add("org.junit_*.jar"); skipPatterns.add("oro-*.jar"); skipPatterns.add("servlet-api-*.jar"); skipPatterns.add("servlet-api.jar"); @@ -110,6 +115,7 @@ final class TldPatterns { skipPatterns.add("tomcat-util.jar"); skipPatterns.add("tomcat-websocket.jar"); skipPatterns.add("tools.jar"); + skipPatterns.add("unboundid-ldapsdk-*.jar"); skipPatterns.add("websocket-api.jar"); skipPatterns.add("wsdl4j*.jar"); skipPatterns.add("xercesImpl.jar"); @@ -117,6 +123,7 @@ final class TldPatterns { skipPatterns.add("xmlParserAPIs-*.jar"); skipPatterns.add("xmlParserAPIs.jar"); skipPatterns.add("xom-*.jar"); + TOMCAT_SKIP = Collections.unmodifiableSet(skipPatterns); } From 7f9fd042fb38a390d9835bae119c8764d2066c18 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 17 May 2023 21:25:52 +0100 Subject: [PATCH 159/163] Upgrade to Undertow 2.2.24.Final Closes gh-35541 --- .../web/embedded/UndertowWebServerFactoryCustomizer.java | 3 ++- .../web/embedded/UndertowWebServerFactoryCustomizerTests.java | 1 + spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/UndertowWebServerFactoryCustomizer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/UndertowWebServerFactoryCustomizer.java index 8f291b1a220c..f8bca9b75468 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/UndertowWebServerFactoryCustomizer.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/UndertowWebServerFactoryCustomizer.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -85,6 +85,7 @@ public void customize(ConfigurableUndertowWebServerFactory factory) { map.from(this::getOrDeduceUseForwardHeaders).to(factory::setUseForwardHeaders); } + @SuppressWarnings("deprecation") private void mapUndertowProperties(ConfigurableUndertowWebServerFactory factory, ServerOptions serverOptions) { PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); Undertow properties = this.serverProperties.getUndertow(); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/UndertowWebServerFactoryCustomizerTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/UndertowWebServerFactoryCustomizerTests.java index 7b544fb3e6ba..1e070451e42c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/UndertowWebServerFactoryCustomizerTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/UndertowWebServerFactoryCustomizerTests.java @@ -150,6 +150,7 @@ void customizeWorkerThreads() { } @Test + @SuppressWarnings("deprecation") void allowEncodedSlashes() { bind("server.undertow.allow-encoded-slash=true"); assertThat(boundServerOption(UndertowOptions.ALLOW_ENCODED_SLASH)).isTrue(); diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 321bbd3506c0..71066ce8b4c7 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1882,7 +1882,7 @@ bom { ] } } - library("Undertow", "2.2.20.Final") { + library("Undertow", "2.2.24.Final") { group("io.undertow") { modules = [ "undertow-core", From c0797eea1d286d621687ce0820a40b225223b907 Mon Sep 17 00:00:00 2001 From: Scott Frederick Date: Wed, 17 May 2023 16:55:10 -0500 Subject: [PATCH 160/163] Upgrade CI to Docker 24.0.0 Closes gh-35506 --- ci/images/get-docker-url.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/images/get-docker-url.sh b/ci/images/get-docker-url.sh index 67445b9d2f57..d139cd8c4a46 100755 --- a/ci/images/get-docker-url.sh +++ b/ci/images/get-docker-url.sh @@ -1,5 +1,5 @@ #!/bin/bash set -e -version="23.0.6" +version="24.0.0" echo "https://download.docker.com/linux/static/stable/x86_64/docker-$version.tgz"; From cc2bb7cade622873d353be2c675ee6407fee4a94 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 18 May 2023 08:06:09 +0100 Subject: [PATCH 161/163] Upgrade to Json-smart 2.4.11 Closes gh-35549 --- spring-boot-project/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index ead8f25305e8..2c0583655e3a 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1050,7 +1050,7 @@ bom { ] } } - library("Json-smart", "2.4.10") { + library("Json-smart", "2.4.11") { group("net.minidev") { modules = [ "json-smart" From 418dd1ba5bdad79b55a043000164bfcbda2acd78 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Mon, 15 May 2023 13:49:43 -0700 Subject: [PATCH 162/163] Return 406 status code if welcome page is not accepted Add `WelcomePageNotAcceptableHandlerMapping` which will return an HTTP 406 status if a suitable welcome page is found but cannot be accepted for the request. An additional mapper is used so that we don't need to change the order of the `WelcomePageHandlerMapping`. It's possible that users may have additional root handler mappings registered to run after the `WelcomePageHandlerMapping` and we still need to respect those. Fixes gh-35552 --- .../web/servlet/WebMvcAutoConfiguration.java | 51 +++++-- .../web/servlet/WelcomePage.java | 79 ++++++++++ .../servlet/WelcomePageHandlerMapping.java | 48 +++--- ...elcomePageNotAcceptableHandlerMapping.java | 58 +++++++ .../servlet/WebMvcAutoConfigurationTests.java | 6 +- .../WelcomePageHandlerMappingTests.java | 1 - .../servlet/WelcomePageIntegrationTests.java | 11 ++ ...ePageNotAcceptableHandlerMappingTests.java | 144 ++++++++++++++++++ 8 files changed, 356 insertions(+), 42 deletions(-) create mode 100644 spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePage.java create mode 100644 spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageNotAcceptableHandlerMapping.java create mode 100644 spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageNotAcceptableHandlerMappingTests.java diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration.java index f7ffc9f23dd6..ea5ea442620f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration.java @@ -108,6 +108,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver; +import org.springframework.web.servlet.handler.AbstractUrlHandlerMapping; import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver; import org.springframework.web.servlet.i18n.FixedLocaleResolver; import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver; @@ -437,12 +438,29 @@ protected RequestMappingHandlerAdapter createRequestMappingHandlerAdapter() { @Bean public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext, FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) { - WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping( - new TemplateAvailabilityProviders(applicationContext), applicationContext, getWelcomePage(), - this.mvcProperties.getStaticPathPattern()); - welcomePageHandlerMapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider)); - welcomePageHandlerMapping.setCorsConfigurations(getCorsConfigurations()); - return welcomePageHandlerMapping; + return createWelcomePageHandlerMapping(applicationContext, mvcConversionService, mvcResourceUrlProvider, + WelcomePageHandlerMapping::new); + } + + @Bean + public WelcomePageNotAcceptableHandlerMapping welcomePageNotAcceptableHandlerMapping( + ApplicationContext applicationContext, FormattingConversionService mvcConversionService, + ResourceUrlProvider mvcResourceUrlProvider) { + return createWelcomePageHandlerMapping(applicationContext, mvcConversionService, mvcResourceUrlProvider, + WelcomePageNotAcceptableHandlerMapping::new); + } + + private T createWelcomePageHandlerMapping( + ApplicationContext applicationContext, FormattingConversionService mvcConversionService, + ResourceUrlProvider mvcResourceUrlProvider, WelcomePageHandlerMappingFactory factory) { + TemplateAvailabilityProviders templateAvailabilityProviders = new TemplateAvailabilityProviders( + applicationContext); + String staticPathPattern = this.mvcProperties.getStaticPathPattern(); + T handlerMapping = factory.create(templateAvailabilityProviders, applicationContext, getIndexHtmlResource(), + staticPathPattern); + handlerMapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider)); + handlerMapping.setCorsConfigurations(getCorsConfigurations()); + return handlerMapping; } @Override @@ -471,25 +489,25 @@ public FlashMapManager flashMapManager() { return super.flashMapManager(); } - private Resource getWelcomePage() { + private Resource getIndexHtmlResource() { for (String location : this.resourceProperties.getStaticLocations()) { - Resource indexHtml = getIndexHtml(location); + Resource indexHtml = getIndexHtmlResource(location); if (indexHtml != null) { return indexHtml; } } ServletContext servletContext = getServletContext(); if (servletContext != null) { - return getIndexHtml(new ServletContextResource(servletContext, SERVLET_LOCATION)); + return getIndexHtmlResource(new ServletContextResource(servletContext, SERVLET_LOCATION)); } return null; } - private Resource getIndexHtml(String location) { - return getIndexHtml(this.resourceLoader.getResource(location)); + private Resource getIndexHtmlResource(String location) { + return getIndexHtmlResource(this.resourceLoader.getResource(location)); } - private Resource getIndexHtml(Resource location) { + private Resource getIndexHtmlResource(Resource location) { try { Resource resource = location.createRelative("index.html"); if (resource.exists() && (resource.getURL() != null)) { @@ -603,6 +621,15 @@ ResourceChainResourceHandlerRegistrationCustomizer resourceHandlerRegistrationCu } + @FunctionalInterface + interface WelcomePageHandlerMappingFactory { + + T create(TemplateAvailabilityProviders templateAvailabilityProviders, ApplicationContext applicationContext, + Resource indexHtmlResource, String staticPathPattern); + + } + + @FunctionalInterface interface ResourceHandlerRegistrationCustomizer { void customize(ResourceHandlerRegistration registration); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePage.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePage.java new file mode 100644 index 000000000000..1adad3cea9bf --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePage.java @@ -0,0 +1,79 @@ +/* + * Copyright 2012-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.web.servlet; + +import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProviders; +import org.springframework.context.ApplicationContext; +import org.springframework.core.io.Resource; + +/** + * Details for a welcome page resolved from a resource or a template. + * + * @author Phillip Webb + */ +final class WelcomePage { + + /** + * Value used for an unresolved welcome page. + */ + static final WelcomePage UNRESOLVED = new WelcomePage(null, false); + + private final String viewName; + + private final boolean templated; + + private WelcomePage(String viewName, boolean templated) { + this.viewName = viewName; + this.templated = templated; + } + + /** + * Return the view name of the welcome page. + * @return the view name + */ + String getViewName() { + return this.viewName; + } + + /** + * Return if the welcome page is from a template. + * @return if the welcome page is templated + */ + boolean isTemplated() { + return this.templated; + } + + /** + * Resolve the {@link WelcomePage} to use. + * @param templateAvailabilityProviders the template availability providers + * @param applicationContext the application context + * @param indexHtmlResource the index HTML resource to use or {@code null} + * @param staticPathPattern the static path pattern being used + * @return a resolved {@link WelcomePage} instance or {@link #UNRESOLVED} + */ + static WelcomePage resolve(TemplateAvailabilityProviders templateAvailabilityProviders, + ApplicationContext applicationContext, Resource indexHtmlResource, String staticPathPattern) { + if (indexHtmlResource != null && "/**".equals(staticPathPattern)) { + return new WelcomePage("forward:index.html", false); + } + if (templateAvailabilityProviders.getProvider("index", applicationContext) != null) { + return new WelcomePage("index", true); + } + return UNRESOLVED; + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageHandlerMapping.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageHandlerMapping.java index 2f33cbb3e9dc..8872c5f8a411 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageHandlerMapping.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageHandlerMapping.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,6 +27,7 @@ import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProviders; import org.springframework.context.ApplicationContext; import org.springframework.core.io.Resource; +import org.springframework.core.log.LogMessage; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.util.StringUtils; @@ -34,12 +35,13 @@ import org.springframework.web.servlet.mvc.ParameterizableViewController; /** - * An {@link AbstractUrlHandlerMapping} for an application's welcome page. Supports both - * static and templated files. If both a static and templated index page are available, - * the static page is preferred. + * An {@link AbstractUrlHandlerMapping} for an application's HTML welcome page. Supports + * both static and templated files. If both a static and templated index page are + * available, the static page is preferred. * * @author Andy Wilkinson * @author Bruce Brouwer + * @see WelcomePageNotAcceptableHandlerMapping */ final class WelcomePageHandlerMapping extends AbstractUrlHandlerMapping { @@ -48,37 +50,31 @@ final class WelcomePageHandlerMapping extends AbstractUrlHandlerMapping { private static final List MEDIA_TYPES_ALL = Collections.singletonList(MediaType.ALL); WelcomePageHandlerMapping(TemplateAvailabilityProviders templateAvailabilityProviders, - ApplicationContext applicationContext, Resource welcomePage, String staticPathPattern) { - if (welcomePage != null && "/**".equals(staticPathPattern)) { - logger.info("Adding welcome page: " + welcomePage); - setRootViewName("forward:index.html"); - } - else if (welcomeTemplateExists(templateAvailabilityProviders, applicationContext)) { - logger.info("Adding welcome page template: index"); - setRootViewName("index"); - } - } - - private boolean welcomeTemplateExists(TemplateAvailabilityProviders templateAvailabilityProviders, - ApplicationContext applicationContext) { - return templateAvailabilityProviders.getProvider("index", applicationContext) != null; - } - - private void setRootViewName(String viewName) { - ParameterizableViewController controller = new ParameterizableViewController(); - controller.setViewName(viewName); - setRootHandler(controller); + ApplicationContext applicationContext, Resource indexHtmlResource, String staticPathPattern) { setOrder(2); + WelcomePage welcomePage = WelcomePage.resolve(templateAvailabilityProviders, applicationContext, + indexHtmlResource, staticPathPattern); + if (welcomePage != WelcomePage.UNRESOLVED) { + logger.info(LogMessage.of(() -> (!welcomePage.isTemplated()) ? "Adding welcome page: " + indexHtmlResource + : "Adding welcome page template: index")); + ParameterizableViewController controller = new ParameterizableViewController(); + controller.setViewName(welcomePage.getViewName()); + setRootHandler(controller); + } } @Override public Object getHandlerInternal(HttpServletRequest request) throws Exception { + return (!isHtmlTextAccepted(request)) ? null : super.getHandlerInternal(request); + } + + private boolean isHtmlTextAccepted(HttpServletRequest request) { for (MediaType mediaType : getAcceptedMediaTypes(request)) { if (mediaType.includes(MediaType.TEXT_HTML)) { - return super.getHandlerInternal(request); + return true; } } - return null; + return false; } private List getAcceptedMediaTypes(HttpServletRequest request) { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageNotAcceptableHandlerMapping.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageNotAcceptableHandlerMapping.java new file mode 100644 index 000000000000..7b7154df9dad --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageNotAcceptableHandlerMapping.java @@ -0,0 +1,58 @@ +/* + * Copyright 2012-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.web.servlet; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProviders; +import org.springframework.context.ApplicationContext; +import org.springframework.core.io.Resource; +import org.springframework.http.HttpStatus; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.handler.AbstractUrlHandlerMapping; +import org.springframework.web.servlet.mvc.Controller; + +/** + * An {@link AbstractUrlHandlerMapping} for an application's welcome page that was + * ultimately not accepted. + * + * @author Phillip Webb + */ +class WelcomePageNotAcceptableHandlerMapping extends AbstractUrlHandlerMapping { + + WelcomePageNotAcceptableHandlerMapping(TemplateAvailabilityProviders templateAvailabilityProviders, + ApplicationContext applicationContext, Resource indexHtmlResource, String staticPathPattern) { + setOrder(LOWEST_PRECEDENCE - 10); // Before ResourceHandlerRegistry + WelcomePage welcomePage = WelcomePage.resolve(templateAvailabilityProviders, applicationContext, + indexHtmlResource, staticPathPattern); + if (welcomePage != WelcomePage.UNRESOLVED) { + setRootHandler((Controller) this::handleRequest); + } + } + + private ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) { + response.setStatus(HttpStatus.NOT_ACCEPTABLE.value()); + return null; + } + + @Override + protected Object getHandlerInternal(HttpServletRequest request) throws Exception { + return super.getHandlerInternal(request); + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfigurationTests.java index c68b98837ee5..613acf51cc2a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfigurationTests.java @@ -169,7 +169,7 @@ void handlerAdaptersCreated() { @Test void handlerMappingsCreated() { - this.contextRunner.run((context) -> assertThat(context).getBeans(HandlerMapping.class).hasSize(5)); + this.contextRunner.run((context) -> assertThat(context).getBeans(HandlerMapping.class).hasSize(6)); } @Test @@ -687,8 +687,8 @@ void welcomePageHandlerMappingIsAutoConfigured() { this.contextRunner.withPropertyValues("spring.web.resources.static-locations:classpath:/welcome-page/") .run((context) -> { assertThat(context).hasSingleBean(WelcomePageHandlerMapping.class); - WelcomePageHandlerMapping bean = context.getBean(WelcomePageHandlerMapping.class); - assertThat(bean.getRootHandler()).isNotNull(); + assertThat(context.getBean(WelcomePageHandlerMapping.class).getRootHandler()).isNotNull(); + assertThat(context.getBean(WelcomePageNotAcceptableHandlerMapping.class).getRootHandler()).isNotNull(); }); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageHandlerMappingTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageHandlerMappingTests.java index fbc3f1ea483d..f5c249e6a8e5 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageHandlerMappingTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageHandlerMappingTests.java @@ -116,7 +116,6 @@ void handlesRequestWithEmptyAcceptHeader() { .perform(get("/").header(HttpHeaders.ACCEPT, "")) .andExpect(status().isOk()) .andExpect(forwardedUrl("index.html"))); - } @Test diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageIntegrationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageIntegrationTests.java index 6a894afbdb5a..327f29d708a6 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageIntegrationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageIntegrationTests.java @@ -29,6 +29,7 @@ import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; +import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.RequestEntity; import org.springframework.http.ResponseEntity; @@ -57,6 +58,16 @@ void contentStrategyWithWelcomePage() throws Exception { .build(); ResponseEntity content = this.template.exchange(entity, String.class); assertThat(content.getBody()).contains("/custom-"); + assertThat(content.getStatusCode()).isEqualTo(HttpStatus.OK); + } + + @Test + void notAcceptableWelcomePage() throws Exception { + RequestEntity entity = RequestEntity.get(new URI("http://localhost:" + this.port + "/")) + .header("Accept", "spring/boot") + .build(); + ResponseEntity content = this.template.exchange(entity, String.class); + assertThat(content.getStatusCode()).isEqualTo(HttpStatus.NOT_ACCEPTABLE); } @Configuration diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageNotAcceptableHandlerMappingTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageNotAcceptableHandlerMappingTests.java new file mode 100644 index 000000000000..3011f29b4a90 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageNotAcceptableHandlerMappingTests.java @@ -0,0 +1,144 @@ +/* + * Copyright 2012-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.web.servlet; + +import org.junit.jupiter.api.Test; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; +import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProviders; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.Ordered; +import org.springframework.core.io.FileSystemResource; +import org.springframework.core.io.Resource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.test.util.ReflectionTestUtils; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +/** + * Tests for {@link WelcomePageNotAcceptableHandlerMapping}. + * + * @author Phillip Webb + */ +class WelcomePageNotAcceptableHandlerMappingTests { + + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withUserConfiguration(HandlerMappingConfiguration.class) + .withConfiguration(AutoConfigurations.of(PropertyPlaceholderAutoConfiguration.class)); + + @Test + void isOrderedAtLowPriorityButAboveResourceHandlerRegistry() { + this.contextRunner.withUserConfiguration(StaticResourceConfiguration.class).run((context) -> { + WelcomePageNotAcceptableHandlerMapping handler = context + .getBean(WelcomePageNotAcceptableHandlerMapping.class); + ResourceHandlerRegistry registry = new ResourceHandlerRegistry(context, null); + Integer resourceOrder = (Integer) ReflectionTestUtils.getField(registry, "order"); + assertThat(handler.getOrder()).isEqualTo(Ordered.LOWEST_PRECEDENCE - 10); + assertThat(handler.getOrder()).isLessThan(resourceOrder); + }); + } + + @Test + void handlesRequestForStaticPageThatAcceptsTextHtml() { + this.contextRunner.withUserConfiguration(StaticResourceConfiguration.class) + .run((context) -> MockMvcBuilders.webAppContextSetup(context) + .build() + .perform(get("/").accept(MediaType.TEXT_HTML)) + .andExpect(status().isNotAcceptable())); + } + + @Test + void handlesRequestForStaticPagetThatDoesNotAcceptTextHtml() { + this.contextRunner.withUserConfiguration(StaticResourceConfiguration.class) + .run((context) -> MockMvcBuilders.webAppContextSetup(context) + .build() + .perform(get("/").accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isNotAcceptable())); + } + + @Test + void handlesRequestWithNoAcceptHeader() { + this.contextRunner.withUserConfiguration(StaticResourceConfiguration.class) + .run((context) -> MockMvcBuilders.webAppContextSetup(context) + .build() + .perform(get("/")) + .andExpect(status().isNotAcceptable())); + } + + @Test + void handlesRequestWithEmptyAcceptHeader() { + this.contextRunner.withUserConfiguration(StaticResourceConfiguration.class) + .run((context) -> MockMvcBuilders.webAppContextSetup(context) + .build() + .perform(get("/").header(HttpHeaders.ACCEPT, "")) + .andExpect(status().isNotAcceptable())); + } + + @Test + void rootHandlerIsNotRegisteredWhenStaticPathPatternIsNotSlashStarStar() { + this.contextRunner.withUserConfiguration(StaticResourceConfiguration.class) + .withPropertyValues("static-path-pattern=/foo/**") + .run((context) -> assertThat(context.getBean(WelcomePageNotAcceptableHandlerMapping.class).getRootHandler()) + .isNull()); + } + + @Test + void producesNotFoundResponseWhenThereIsNoWelcomePage() { + this.contextRunner.run((context) -> MockMvcBuilders.webAppContextSetup(context) + .build() + .perform(get("/").accept(MediaType.TEXT_HTML)) + .andExpect(status().isNotFound())); + } + + @Configuration(proxyBeanMethods = false) + static class HandlerMappingConfiguration { + + @Bean + WelcomePageNotAcceptableHandlerMapping handlerMapping(ApplicationContext applicationContext, + ObjectProvider templateAvailabilityProviders, + ObjectProvider staticIndexPage, + @Value("${static-path-pattern:/**}") String staticPathPattern) { + return new WelcomePageNotAcceptableHandlerMapping( + templateAvailabilityProviders + .getIfAvailable(() -> new TemplateAvailabilityProviders(applicationContext)), + applicationContext, staticIndexPage.getIfAvailable(), staticPathPattern); + } + + } + + @Configuration(proxyBeanMethods = false) + static class StaticResourceConfiguration { + + @Bean + Resource staticIndexPage() { + return new FileSystemResource("src/test/resources/welcome-page/index.html"); + } + + } + +} From 64157f2afc1a9e89da4148c62844fe7d5618b412 Mon Sep 17 00:00:00 2001 From: Spring Builds Date: Thu, 18 May 2023 08:38:41 +0000 Subject: [PATCH 163/163] Release v2.7.12 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index eb6c2eb76fb1..ee7bc2b73e0b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -version=2.7.12-SNAPSHOT +version=2.7.12 org.gradle.caching=true org.gradle.parallel=true