From 062d701ae1d29ee1a6e62ca0379a7ee9bb6f3d25 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 26 Jun 2023 12:34:54 +0200 Subject: [PATCH 1/3] Consistently use mutable ArrayList for modulesToInstall vs modules Closes gh-30751 --- .../json/Jackson2ObjectMapperBuilder.java | 2 +- .../Jackson2ObjectMapperBuilderTests.java | 71 +++++++++++-------- 2 files changed, 43 insertions(+), 30 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilder.java b/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilder.java index 04a23d6eab..9c11e50b34 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilder.java +++ b/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilder.java @@ -581,7 +581,7 @@ public class Jackson2ObjectMapperBuilder { * @see com.fasterxml.jackson.databind.Module */ public Jackson2ObjectMapperBuilder modulesToInstall(Module... modules) { - this.modules = Arrays.asList(modules); + this.modules = new ArrayList<>(Arrays.asList(modules)); this.findWellKnownModules = true; return this; } diff --git a/spring-web/src/test/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilderTests.java b/spring-web/src/test/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilderTests.java index c11b98ec95..a9beb0d284 100644 --- a/spring-web/src/test/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilderTests.java +++ b/spring-web/src/test/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilderTests.java @@ -228,26 +228,6 @@ class Jackson2ObjectMapperBuilderTests { Jackson2ObjectMapperBuilder.json().timeZone(zoneId).build()); } - @Test - void modules() { - NumberSerializer serializer1 = new NumberSerializer(Integer.class); - SimpleModule module = new SimpleModule(); - module.addSerializer(Integer.class, serializer1); - ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().modules(module).build(); - Serializers serializers = getSerializerFactoryConfig(objectMapper).serializers().iterator().next(); - assertThat(serializers.findSerializer(null, SimpleType.construct(Integer.class), null)).isSameAs(serializer1); - } - - @Test - void modulesWithConsumer() { - NumberSerializer serializer1 = new NumberSerializer(Integer.class); - SimpleModule module = new SimpleModule(); - module.addSerializer(Integer.class, serializer1); - ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().modules(list -> list.add(module) ).build(); - Serializers serializers = getSerializerFactoryConfig(objectMapper).serializers().iterator().next(); - assertThat(serializers.findSerializer(null, SimpleType.construct(Integer.class), null)).isSameAs(serializer1); - } - @Test void modulesToInstallByClass() { ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json() @@ -311,14 +291,15 @@ class Jackson2ObjectMapperBuilderTests { barModule.addSerializer(new BarSerializer()); builder.modulesToInstall(fooModule, barModule); ObjectMapper objectMapper = builder.build(); + assertThat(StreamSupport - .stream(getSerializerFactoryConfig(objectMapper).serializers().spliterator(), false) - .filter(s -> s.findSerializer(null, SimpleType.construct(Foo.class), null) != null) - .count()).isEqualTo(1); + .stream(getSerializerFactoryConfig(objectMapper).serializers().spliterator(), false) + .filter(s -> s.findSerializer(null, SimpleType.construct(Foo.class), null) != null) + .count()).isEqualTo(1); assertThat(StreamSupport - .stream(getSerializerFactoryConfig(objectMapper).serializers().spliterator(), false) - .filter(s -> s.findSerializer(null, SimpleType.construct(Bar.class), null) != null) - .count()).isEqualTo(1); + .stream(getSerializerFactoryConfig(objectMapper).serializers().spliterator(), false) + .filter(s -> s.findSerializer(null, SimpleType.construct(Bar.class), null) != null) + .count()).isEqualTo(1); } private static SerializerFactoryConfig getSerializerFactoryConfig(ObjectMapper objectMapper) { @@ -329,6 +310,38 @@ class Jackson2ObjectMapperBuilderTests { return ((BasicDeserializerFactory) objectMapper.getDeserializationContext().getFactory()).getFactoryConfig(); } + @Test + void modules() { + NumberSerializer serializer1 = new NumberSerializer(Integer.class); + SimpleModule module = new SimpleModule(); + module.addSerializer(Integer.class, serializer1); + ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().modules(module).build(); + Serializers serializers = getSerializerFactoryConfig(objectMapper).serializers().iterator().next(); + assertThat(serializers.findSerializer(null, SimpleType.construct(Integer.class), null)).isSameAs(serializer1); + } + + @Test + void modulesWithConsumer() { + NumberSerializer serializer1 = new NumberSerializer(Integer.class); + SimpleModule module = new SimpleModule(); + module.addSerializer(Integer.class, serializer1); + ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().modules(list -> list.add(module) ).build(); + Serializers serializers = getSerializerFactoryConfig(objectMapper).serializers().iterator().next(); + assertThat(serializers.findSerializer(null, SimpleType.construct(Integer.class), null)).isSameAs(serializer1); + } + + @Test + void modulesWithConsumerAfterModulesToInstall() { + NumberSerializer serializer1 = new NumberSerializer(Integer.class); + SimpleModule module = new SimpleModule(); + module.addSerializer(Integer.class, serializer1); + ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json() + .modulesToInstall(new JavaTimeModule()) + .modules(list -> list.add(module) ).build(); + Serializers serializers = getSerializerFactoryConfig(objectMapper).serializers().iterator().next(); + assertThat(serializers.findSerializer(null, SimpleType.construct(Integer.class), null)).isSameAs(serializer1); + } + @Test void propertyNamingStrategy() { PropertyNamingStrategy strategy = new PropertyNamingStrategy.SnakeCaseStrategy(); @@ -341,7 +354,7 @@ class Jackson2ObjectMapperBuilderTests { void serializerByType() { JsonSerializer serializer = new NumberSerializer(Integer.class); ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json() - .modules(new ArrayList<>()) // Disable well-known modules detection + .modules(new ArrayList<>()) // disable well-known modules detection .serializerByType(Boolean.class, serializer) .build(); assertThat(getSerializerFactoryConfig(objectMapper).hasSerializers()).isTrue(); @@ -353,7 +366,7 @@ class Jackson2ObjectMapperBuilderTests { void deserializerByType() throws JsonMappingException { JsonDeserializer deserializer = new DateDeserializers.DateDeserializer(); ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json() - .modules(new ArrayList<>()) // Disable well-known modules detection + .modules(new ArrayList<>()) // disable well-known modules detection .deserializerByType(Date.class, deserializer) .build(); assertThat(getDeserializerFactoryConfig(objectMapper).hasDeserializers()).isTrue(); @@ -434,7 +447,7 @@ class Jackson2ObjectMapperBuilderTests { JsonSerializer serializer2 = new NumberSerializer(Integer.class); Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.json() - .modules(new ArrayList<>()) // Disable well-known modules detection + .modules(new ArrayList<>()) // disable well-known modules detection .serializers(serializer1) .serializersByType(Collections.singletonMap(Boolean.class, serializer2)) .deserializersByType(deserializerMap) From 9266e6d29e49be8a7e8ecbe6542bc2f66776e867 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 26 Jun 2023 12:34:59 +0200 Subject: [PATCH 2/3] Remove outdated javadoc notes on getMessage and printStackTrace Closes gh-30748 --- .../org/springframework/core/NestedCheckedException.java | 8 ++------ .../org/springframework/core/NestedRuntimeException.java | 8 ++------ 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/NestedCheckedException.java b/spring-core/src/main/java/org/springframework/core/NestedCheckedException.java index d737d9a746..dcf25b5f5c 100644 --- a/spring-core/src/main/java/org/springframework/core/NestedCheckedException.java +++ b/spring-core/src/main/java/org/springframework/core/NestedCheckedException.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-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. @@ -20,11 +20,7 @@ import org.springframework.lang.Nullable; /** * Handy class for wrapping checked {@code Exceptions} with a root cause. - * - *

This class is {@code abstract} to force the programmer to extend - * the class. {@code getMessage} will include nested exception - * information; {@code printStackTrace} and other like methods will - * delegate to the wrapped exception, if any. + * This class is {@code abstract} to force the programmer to extend the class. * *

The similarity between this class and the {@link NestedRuntimeException} * class is unavoidable, as Java forces these two classes to have different diff --git a/spring-core/src/main/java/org/springframework/core/NestedRuntimeException.java b/spring-core/src/main/java/org/springframework/core/NestedRuntimeException.java index a960a5ecb5..ab0eefb213 100644 --- a/spring-core/src/main/java/org/springframework/core/NestedRuntimeException.java +++ b/spring-core/src/main/java/org/springframework/core/NestedRuntimeException.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-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. @@ -20,11 +20,7 @@ import org.springframework.lang.Nullable; /** * Handy class for wrapping runtime {@code Exceptions} with a root cause. - * - *

This class is {@code abstract} to force the programmer to extend - * the class. {@code getMessage} will include nested exception - * information; {@code printStackTrace} and other like methods will - * delegate to the wrapped exception, if any. + * This class is {@code abstract} to force the programmer to extend the class. * *

The similarity between this class and the {@link NestedCheckedException} * class is unavoidable, as Java forces these two classes to have different From 449174c7d4c5925ff54cc4390d33d0d0bd8ad377 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 26 Jun 2023 12:35:09 +0200 Subject: [PATCH 3/3] Polishing --- .../beans/factory/support/DisposableBeanAdapter.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java index 85d6c56346..bd6e62fb46 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java @@ -116,8 +116,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable { if (!this.invokeAutoCloseable) { this.destroyMethodNames = destroyMethodNames; List destroyMethods = new ArrayList<>(destroyMethodNames.length); - for (int i = 0; i < destroyMethodNames.length; i++) { - String destroyMethodName = destroyMethodNames[i]; + for (String destroyMethodName : destroyMethodNames) { Method destroyMethod = determineDestroyMethod(destroyMethodName); if (destroyMethod == null) { if (beanDefinition.isEnforceDestroyMethod()) {