Browse Source

Merge branch '3.5.x'

pull/48068/head
Andy Wilkinson 1 month ago
parent
commit
0e44f1de42
  1. 15
      build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootZipCopyAction.java
  2. 10
      buildpack/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/configuration/DockerRegistryConfigAuthenticationTests.java
  3. 2
      module/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/security/GraphQlWebMvcSecurityAutoConfigurationTests.java
  4. 3
      module/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseyWebEndpointManagementContextConfiguration.java
  5. 22
      module/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/JettyVirtualThreadsWebServerFactoryCustomizer.java
  6. 12
      module/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/JettyWebServerConfiguration.java
  7. 4
      module/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/autoconfigure/JettyVirtualThreadsWebServerFactoryCustomizerTests.java
  8. 4
      module/spring-boot-webflux-test/src/test/java/org/springframework/boot/webflux/test/autoconfigure/WebFluxTestJsonComponentIntegrationTests.java
  9. 3
      module/spring-boot-webflux-test/src/test/java/org/springframework/boot/webflux/test/autoconfigure/WebFluxTypeExcludeFilterTests.java
  10. 3
      module/spring-boot-webmvc-test/src/test/java/org/springframework/boot/webmvc/test/autoconfigure/WebMvcTypeExcludeFilterTests.java
  11. 4
      test-support/spring-boot-docker-test-support/src/main/java/org/springframework/boot/testsupport/container/TestImage.java

15
build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootZipCopyAction.java

@ -64,6 +64,7 @@ import org.springframework.boot.loader.tools.ReachabilityMetadataProperties;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.StreamUtils; import org.springframework.util.StreamUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.util.function.ThrowingSupplier;
/** /**
* A {@link CopyAction} for creating a Spring Boot zip archive (typically a jar or war). * A {@link CopyAction} for creating a Spring Boot zip archive (typically a jar or war).
@ -325,7 +326,7 @@ class BootZipCopyAction implements CopyAction {
private void writeJarModeLibrary(String location, JarModeLibrary library) throws IOException { private void writeJarModeLibrary(String location, JarModeLibrary library) throws IOException {
String name = location + library.getName(); String name = location + library.getName();
writeEntry(name, ZipEntryContentWriter.fromInputStream(library.openStream()), false, writeEntry(name, ZipEntryContentWriter.fromInputStream(library.openStream()), false,
(entry) -> prepareStoredEntry(library.openStream(), false, entry)); (entry) -> prepareStoredEntry(library::openStream, false, entry));
if (BootZipCopyAction.this.layerResolver != null) { if (BootZipCopyAction.this.layerResolver != null) {
Layer layer = BootZipCopyAction.this.layerResolver.getLayer(library); Layer layer = BootZipCopyAction.this.layerResolver.getLayer(library);
Assert.state(this.layerIndex != null, "'layerIndex' must not be null"); Assert.state(this.layerIndex != null, "'layerIndex' must not be null");
@ -429,12 +430,12 @@ class BootZipCopyAction implements CopyAction {
} }
private void prepareStoredEntry(FileCopyDetails details, ZipArchiveEntry archiveEntry) throws IOException { private void prepareStoredEntry(FileCopyDetails details, ZipArchiveEntry archiveEntry) throws IOException {
prepareStoredEntry(details.open(), BootZipCopyAction.this.requiresUnpack.isSatisfiedBy(details), prepareStoredEntry(details::open, BootZipCopyAction.this.requiresUnpack.isSatisfiedBy(details),
archiveEntry); archiveEntry);
} }
private void prepareStoredEntry(InputStream input, boolean unpack, ZipArchiveEntry archiveEntry) private void prepareStoredEntry(ThrowingSupplier<InputStream> input, boolean unpack,
throws IOException { ZipArchiveEntry archiveEntry) throws IOException {
new StoredEntryPreparator(input, unpack).prepareStoredEntry(archiveEntry); new StoredEntryPreparator(input, unpack).prepareStoredEntry(archiveEntry);
} }
@ -564,10 +565,10 @@ class BootZipCopyAction implements CopyAction {
private long size; private long size;
StoredEntryPreparator(InputStream inputStream, boolean unpack) throws IOException { StoredEntryPreparator(ThrowingSupplier<InputStream> input, boolean unpack) throws IOException {
this.unpack = unpack; this.unpack = unpack;
try (inputStream) { try (InputStream stream = input.get()) {
load(inputStream); load(stream);
} }
} }

10
buildpack/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/configuration/DockerRegistryConfigAuthenticationTests.java

@ -76,7 +76,7 @@ class DockerRegistryConfigAuthenticationTests {
} }
""") """)
@Test @Test
void getAuthHeaderWhenAuthForDockerDomain(@ResourcesRoot Path directory) throws Exception { void getAuthHeaderWhenAuthForDockerDomain(@ResourcesRoot Path directory) {
this.environment.put("DOCKER_CONFIG", directory.toString()); this.environment.put("DOCKER_CONFIG", directory.toString());
ImageReference imageReference = ImageReference.of("docker.io/ubuntu:latest"); ImageReference imageReference = ImageReference.of("docker.io/ubuntu:latest");
String authHeader = getAuthHeader(imageReference); String authHeader = getAuthHeader(imageReference);
@ -99,7 +99,7 @@ class DockerRegistryConfigAuthenticationTests {
} }
""") """)
@Test @Test
void getAuthHeaderWhenAuthForLegacyDockerDomain(@ResourcesRoot Path directory) throws Exception { void getAuthHeaderWhenAuthForLegacyDockerDomain(@ResourcesRoot Path directory) {
this.environment.put("DOCKER_CONFIG", directory.toString()); this.environment.put("DOCKER_CONFIG", directory.toString());
ImageReference imageReference = ImageReference.of("index.docker.io/ubuntu:latest"); ImageReference imageReference = ImageReference.of("index.docker.io/ubuntu:latest");
String authHeader = getAuthHeader(imageReference); String authHeader = getAuthHeader(imageReference);
@ -121,7 +121,7 @@ class DockerRegistryConfigAuthenticationTests {
} }
""") """)
@Test @Test
void getAuthHeaderWhenAuthForCustomDomain(@ResourcesRoot Path directory) throws Exception { void getAuthHeaderWhenAuthForCustomDomain(@ResourcesRoot Path directory) {
this.environment.put("DOCKER_CONFIG", directory.toString()); this.environment.put("DOCKER_CONFIG", directory.toString());
ImageReference imageReference = ImageReference.of("my-registry.example.com/ubuntu:latest"); ImageReference imageReference = ImageReference.of("my-registry.example.com/ubuntu:latest");
String authHeader = getAuthHeader(imageReference); String authHeader = getAuthHeader(imageReference);
@ -143,7 +143,7 @@ class DockerRegistryConfigAuthenticationTests {
} }
""") """)
@Test @Test
void getAuthHeaderWhenAuthForCustomDomainWithLegacyFormat(@ResourcesRoot Path directory) throws Exception { void getAuthHeaderWhenAuthForCustomDomainWithLegacyFormat(@ResourcesRoot Path directory) {
this.environment.put("DOCKER_CONFIG", directory.toString()); this.environment.put("DOCKER_CONFIG", directory.toString());
ImageReference imageReference = ImageReference.of("my-registry.example.com/ubuntu:latest"); ImageReference imageReference = ImageReference.of("my-registry.example.com/ubuntu:latest");
String authHeader = getAuthHeader(imageReference); String authHeader = getAuthHeader(imageReference);
@ -160,7 +160,7 @@ class DockerRegistryConfigAuthenticationTests {
} }
""") """)
@Test @Test
void getAuthHeaderWhenEmptyConfigDirectoryReturnsFallback(@ResourcesRoot Path directory) throws Exception { void getAuthHeaderWhenEmptyConfigDirectoryReturnsFallback(@ResourcesRoot Path directory) {
this.environment.put("DOCKER_CONFIG", directory.toString()); this.environment.put("DOCKER_CONFIG", directory.toString());
ImageReference imageReference = ImageReference.of("docker.io/ubuntu:latest"); ImageReference imageReference = ImageReference.of("docker.io/ubuntu:latest");
String authHeader = getAuthHeader(imageReference, DockerRegistryAuthentication.EMPTY_USER); String authHeader = getAuthHeader(imageReference, DockerRegistryAuthentication.EMPTY_USER);

2
module/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/security/GraphQlWebMvcSecurityAutoConfigurationTests.java

@ -173,7 +173,7 @@ class GraphQlWebMvcSecurityAutoConfigurationTests {
static class SecurityConfig { static class SecurityConfig {
@Bean @Bean
DefaultSecurityFilterChain springWebFilterChain(HttpSecurity http) throws Exception { DefaultSecurityFilterChain springWebFilterChain(HttpSecurity http) {
return http.csrf(CsrfConfigurer::disable) return http.csrf(CsrfConfigurer::disable)
// Demonstrate that method security works // Demonstrate that method security works
// Best practice to use both for defense in depth // Best practice to use both for defense in depth

3
module/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseyWebEndpointManagementContextConfiguration.java

@ -41,7 +41,6 @@ import org.springframework.boot.actuate.endpoint.EndpointId;
import org.springframework.boot.actuate.endpoint.ExposableEndpoint; import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
import org.springframework.boot.actuate.endpoint.OperationResponseBody; import org.springframework.boot.actuate.endpoint.OperationResponseBody;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint; import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.jackson.EndpointJackson2ObjectMapper;
import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver; import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver;
import org.springframework.boot.actuate.endpoint.web.EndpointMapping; import org.springframework.boot.actuate.endpoint.web.EndpointMapping;
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes; import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
@ -109,7 +108,7 @@ class JerseyWebEndpointManagementContextConfiguration {
} }
@Bean @Bean
@ConditionalOnBean(EndpointJackson2ObjectMapper.class) @ConditionalOnBean(org.springframework.boot.actuate.endpoint.jackson.EndpointJackson2ObjectMapper.class)
@SuppressWarnings("removal") @SuppressWarnings("removal")
ResourceConfigCustomizer endpointJackson2ObjectMapperResourceConfigCustomizer( ResourceConfigCustomizer endpointJackson2ObjectMapperResourceConfigCustomizer(
org.springframework.boot.actuate.endpoint.jackson.EndpointJackson2ObjectMapper endpointJackson2ObjectMapper) { org.springframework.boot.actuate.endpoint.jackson.EndpointJackson2ObjectMapper endpointJackson2ObjectMapper) {

22
module/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/JettyVirtualThreadsWebServerFactoryCustomizer.java

@ -19,13 +19,9 @@ package org.springframework.boot.jetty.autoconfigure;
import org.eclipse.jetty.util.VirtualThreads; import org.eclipse.jetty.util.VirtualThreads;
import org.eclipse.jetty.util.thread.VirtualThreadPool; import org.eclipse.jetty.util.thread.VirtualThreadPool;
import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.boot.jetty.ConfigurableJettyWebServerFactory; import org.springframework.boot.jetty.ConfigurableJettyWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer; import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.Ordered; import org.springframework.core.Ordered;
import org.springframework.core.env.Environment;
import org.springframework.util.Assert; import org.springframework.util.Assert;
/** /**
@ -36,16 +32,7 @@ import org.springframework.util.Assert;
* @since 4.0.0 * @since 4.0.0
*/ */
public class JettyVirtualThreadsWebServerFactoryCustomizer public class JettyVirtualThreadsWebServerFactoryCustomizer
implements WebServerFactoryCustomizer<ConfigurableJettyWebServerFactory>, Ordered, EnvironmentAware { implements WebServerFactoryCustomizer<ConfigurableJettyWebServerFactory>, Ordered {
private final JettyServerProperties jettyProperties;
private final boolean bind;
public JettyVirtualThreadsWebServerFactoryCustomizer(JettyServerProperties jettyProperties) {
this.jettyProperties = jettyProperties;
this.bind = false;
}
@Override @Override
public void customize(ConfigurableJettyWebServerFactory factory) { public void customize(ConfigurableJettyWebServerFactory factory) {
@ -60,11 +47,4 @@ public class JettyVirtualThreadsWebServerFactoryCustomizer
return JettyWebServerFactoryCustomizer.ORDER + 1; return JettyWebServerFactoryCustomizer.ORDER + 1;
} }
@Override
public void setEnvironment(Environment environment) {
if (this.bind) {
Binder.get(environment).bind("server.jetty", Bindable.ofInstance(this.jettyProperties));
}
}
} }

12
module/spring-boot-jetty/src/main/java/org/springframework/boot/jetty/autoconfigure/JettyWebServerConfiguration.java

@ -38,22 +38,16 @@ import org.springframework.core.env.Environment;
@Configuration(proxyBeanMethods = false) @Configuration(proxyBeanMethods = false)
public class JettyWebServerConfiguration { public class JettyWebServerConfiguration {
private final JettyServerProperties jettyProperties;
JettyWebServerConfiguration(JettyServerProperties jettyProperties) {
this.jettyProperties = jettyProperties;
}
@Bean @Bean
JettyWebServerFactoryCustomizer jettyWebServerFactoryCustomizer(Environment environment, JettyWebServerFactoryCustomizer jettyWebServerFactoryCustomizer(Environment environment,
ServerProperties serverProperties) { ServerProperties serverProperties, JettyServerProperties jettyProperties) {
return new JettyWebServerFactoryCustomizer(environment, serverProperties, this.jettyProperties); return new JettyWebServerFactoryCustomizer(environment, serverProperties, jettyProperties);
} }
@Bean @Bean
@ConditionalOnThreading(Threading.VIRTUAL) @ConditionalOnThreading(Threading.VIRTUAL)
JettyVirtualThreadsWebServerFactoryCustomizer jettyVirtualThreadsWebServerFactoryCustomizer() { JettyVirtualThreadsWebServerFactoryCustomizer jettyVirtualThreadsWebServerFactoryCustomizer() {
return new JettyVirtualThreadsWebServerFactoryCustomizer(this.jettyProperties); return new JettyVirtualThreadsWebServerFactoryCustomizer();
} }
} }

4
module/spring-boot-jetty/src/test/java/org/springframework/boot/jetty/autoconfigure/JettyVirtualThreadsWebServerFactoryCustomizerTests.java

@ -38,9 +38,7 @@ class JettyVirtualThreadsWebServerFactoryCustomizerTests {
@Test @Test
@EnabledForJreRange(min = JRE.JAVA_21) @EnabledForJreRange(min = JRE.JAVA_21)
void shouldConfigureVirtualThreads() { void shouldConfigureVirtualThreads() {
JettyServerProperties properties = new JettyServerProperties(); JettyVirtualThreadsWebServerFactoryCustomizer customizer = new JettyVirtualThreadsWebServerFactoryCustomizer();
JettyVirtualThreadsWebServerFactoryCustomizer customizer = new JettyVirtualThreadsWebServerFactoryCustomizer(
properties);
ConfigurableJettyWebServerFactory factory = mock(ConfigurableJettyWebServerFactory.class); ConfigurableJettyWebServerFactory factory = mock(ConfigurableJettyWebServerFactory.class);
customizer.customize(factory); customizer.customize(factory);
then(factory).should().setThreadPool(assertArg((threadPool) -> { then(factory).should().setThreadPool(assertArg((threadPool) -> {

4
module/spring-boot-webflux-test/src/test/java/org/springframework/boot/webflux/test/autoconfigure/WebFluxTestJsonComponentIntegrationTests.java

@ -19,7 +19,6 @@ package org.springframework.boot.webflux.test.autoconfigure;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.test.json.JsonCompareMode; import org.springframework.test.json.JsonCompareMode;
import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.test.web.reactive.server.WebTestClient;
@ -35,9 +34,6 @@ class WebFluxTestJsonComponentIntegrationTests {
@Autowired @Autowired
private WebTestClient webClient; private WebTestClient webClient;
@Autowired
private ConfigurableApplicationContext context;
@Test @Test
void shouldFindJsonComponent() { void shouldFindJsonComponent() {
this.webClient.post() this.webClient.post()

3
module/spring-boot-webflux-test/src/test/java/org/springframework/boot/webflux/test/autoconfigure/WebFluxTypeExcludeFilterTests.java

@ -23,7 +23,6 @@ import reactor.core.publisher.Mono;
import tools.jackson.databind.module.SimpleModule; import tools.jackson.databind.module.SimpleModule;
import org.springframework.boot.jackson.JacksonComponent; import org.springframework.boot.jackson.JacksonComponent;
import org.springframework.boot.jackson2.JsonComponent;
import org.springframework.context.annotation.ComponentScan.Filter; import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.FilterType; import org.springframework.context.annotation.FilterType;
import org.springframework.core.type.classreading.MetadataReader; import org.springframework.core.type.classreading.MetadataReader;
@ -209,7 +208,7 @@ class WebFluxTypeExcludeFilterTests {
} }
@JsonComponent @org.springframework.boot.jackson2.JsonComponent
@SuppressWarnings("removal") @SuppressWarnings("removal")
static class ExampleJsonComponent { static class ExampleJsonComponent {

3
module/spring-boot-webmvc-test/src/test/java/org/springframework/boot/webmvc/test/autoconfigure/WebMvcTypeExcludeFilterTests.java

@ -22,7 +22,6 @@ import org.junit.jupiter.api.Test;
import tools.jackson.databind.module.SimpleModule; import tools.jackson.databind.module.SimpleModule;
import org.springframework.boot.jackson.JacksonComponent; import org.springframework.boot.jackson.JacksonComponent;
import org.springframework.boot.jackson2.JsonComponent;
import org.springframework.boot.webmvc.autoconfigure.WebMvcRegistrations; import org.springframework.boot.webmvc.autoconfigure.WebMvcRegistrations;
import org.springframework.context.annotation.ComponentScan.Filter; import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.FilterType; import org.springframework.context.annotation.FilterType;
@ -224,7 +223,7 @@ class WebMvcTypeExcludeFilterTests {
} }
@JsonComponent @org.springframework.boot.jackson2.JsonComponent
@SuppressWarnings("removal") @SuppressWarnings("removal")
static class ExampleJsonComponent { static class ExampleJsonComponent {

4
test-support/spring-boot-docker-test-support/src/main/java/org/springframework/boot/testsupport/container/TestImage.java

@ -165,6 +165,7 @@ public enum TestImage {
* {@link org.testcontainers.containers.MongoDBContainer}. * {@link org.testcontainers.containers.MongoDBContainer}.
* @deprecated since 4.0.0 for removal in 4.2.0 in favor of {@link #MONGODB} * @deprecated since 4.0.0 for removal in 4.2.0 in favor of {@link #MONGODB}
*/ */
@SuppressWarnings("deprecation")
@Deprecated(since = "3.4.0", forRemoval = true) @Deprecated(since = "3.4.0", forRemoval = true)
MONGODB_DEPRECATED("mongo", "5.0.17", () -> org.testcontainers.containers.MongoDBContainer.class, MONGODB_DEPRECATED("mongo", "5.0.17", () -> org.testcontainers.containers.MongoDBContainer.class,
(container) -> ((org.testcontainers.containers.MongoDBContainer) container).withStartupAttempts(5) (container) -> ((org.testcontainers.containers.MongoDBContainer) container).withStartupAttempts(5)
@ -194,6 +195,7 @@ public enum TestImage {
* {@link org.testcontainers.containers.Neo4jContainer}. * {@link org.testcontainers.containers.Neo4jContainer}.
* @deprecated since 4.0.0 for removal in 4.2.0 in favor of {@link #NEO4J} * @deprecated since 4.0.0 for removal in 4.2.0 in favor of {@link #NEO4J}
*/ */
@SuppressWarnings({ "deprecation", "rawtypes" })
@Deprecated(since = "3.4.0", forRemoval = true) @Deprecated(since = "3.4.0", forRemoval = true)
NEO4J_DEPRECATED("neo4j", "5.26.11", () -> org.testcontainers.containers.Neo4jContainer.class, NEO4J_DEPRECATED("neo4j", "5.26.11", () -> org.testcontainers.containers.Neo4jContainer.class,
(container) -> ((org.testcontainers.containers.Neo4jContainer) container).withStartupAttempts(5) (container) -> ((org.testcontainers.containers.Neo4jContainer) container).withStartupAttempts(5)
@ -236,6 +238,7 @@ public enum TestImage {
* {@link org.testcontainers.containers.PulsarContainer}. * {@link org.testcontainers.containers.PulsarContainer}.
* @deprecated since 4.0.0 for removal in 4.2.0 in favor of {@link #PULSAR} * @deprecated since 4.0.0 for removal in 4.2.0 in favor of {@link #PULSAR}
*/ */
@SuppressWarnings("deprecation")
@Deprecated(since = "3.4.0", forRemoval = true) @Deprecated(since = "3.4.0", forRemoval = true)
PULSAR_DEPRECATED("apachepulsar/pulsar", "3.3.3", () -> org.testcontainers.containers.PulsarContainer.class, PULSAR_DEPRECATED("apachepulsar/pulsar", "3.3.3", () -> org.testcontainers.containers.PulsarContainer.class,
(container) -> ((org.testcontainers.containers.PulsarContainer) container).withStartupAttempts(2) (container) -> ((org.testcontainers.containers.PulsarContainer) container).withStartupAttempts(2)
@ -252,6 +255,7 @@ public enum TestImage {
* {@link org.testcontainers.containers.RabbitMQContainer}. * {@link org.testcontainers.containers.RabbitMQContainer}.
* @deprecated since 4.0.0 for removal in 4.2.0 in favor of {@link #RABBITMQ} * @deprecated since 4.0.0 for removal in 4.2.0 in favor of {@link #RABBITMQ}
*/ */
@SuppressWarnings("deprecation")
@Deprecated(since = "3.4.0", forRemoval = true) @Deprecated(since = "3.4.0", forRemoval = true)
RABBITMQ_DEPRECATED("rabbitmq", "3.11-alpine", () -> org.testcontainers.containers.RabbitMQContainer.class, RABBITMQ_DEPRECATED("rabbitmq", "3.11-alpine", () -> org.testcontainers.containers.RabbitMQContainer.class,
(container) -> ((org.testcontainers.containers.RabbitMQContainer) container) (container) -> ((org.testcontainers.containers.RabbitMQContainer) container)

Loading…
Cancel
Save