Skip to content

Commit dc6c96d

Browse files
committed
Merge branch '6.1.x'
# Conflicts: # spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/AbstractFallbackJCacheOperationSource.java # spring-context/src/main/java/org/springframework/cache/interceptor/AbstractFallbackCacheOperationSource.java # spring-tx/src/main/java/org/springframework/transaction/interceptor/AbstractFallbackTransactionAttributeSource.java
2 parents b5ca646 + e9110c0 commit dc6c96d

File tree

13 files changed

+71
-40
lines changed

13 files changed

+71
-40
lines changed

Diff for: spring-aop/src/test/java/org/springframework/aop/support/AopUtilsTests.java

+36
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,19 @@
1717
package org.springframework.aop.support;
1818

1919
import java.lang.reflect.Method;
20+
import java.util.List;
2021

2122
import org.junit.jupiter.api.Test;
2223

2324
import org.springframework.aop.ClassFilter;
2425
import org.springframework.aop.MethodMatcher;
2526
import org.springframework.aop.Pointcut;
27+
import org.springframework.aop.framework.ProxyFactory;
2628
import org.springframework.aop.interceptor.ExposeInvocationInterceptor;
2729
import org.springframework.aop.target.EmptyTargetSource;
2830
import org.springframework.aop.testfixture.interceptor.NopInterceptor;
2931
import org.springframework.beans.testfixture.beans.TestBean;
32+
import org.springframework.core.ResolvableType;
3033
import org.springframework.core.testfixture.io.SerializationTestUtils;
3134
import org.springframework.lang.Nullable;
3235
import org.springframework.util.ReflectionUtils;
@@ -37,6 +40,7 @@
3740
* @author Rod Johnson
3841
* @author Chris Beams
3942
* @author Sebastien Deleuze
43+
* @author Juergen Hoeller
4044
*/
4145
class AopUtilsTests {
4246

@@ -99,4 +103,36 @@ void testInvokeJoinpointUsingReflection() throws Throwable {
99103
assertThat(result).isEqualTo(name);
100104
}
101105

106+
@Test // gh-32365
107+
void mostSpecificMethodBetweenJdkProxyAndTarget() throws Exception {
108+
Class<?> proxyClass = new ProxyFactory(new WithInterface()).getProxyClass(getClass().getClassLoader());
109+
Method specificMethod = AopUtils.getMostSpecificMethod(proxyClass.getMethod("handle", List.class), WithInterface.class);
110+
assertThat(ResolvableType.forMethodParameter(specificMethod, 0).getGeneric().toClass()).isEqualTo(String.class);
111+
}
112+
113+
@Test // gh-32365
114+
void mostSpecificMethodBetweenCglibProxyAndTarget() throws Exception {
115+
Class<?> proxyClass = new ProxyFactory(new WithoutInterface()).getProxyClass(getClass().getClassLoader());
116+
Method specificMethod = AopUtils.getMostSpecificMethod(proxyClass.getMethod("handle", List.class), WithoutInterface.class);
117+
assertThat(ResolvableType.forMethodParameter(specificMethod, 0).getGeneric().toClass()).isEqualTo(String.class);
118+
}
119+
120+
121+
interface ProxyInterface {
122+
123+
void handle(List<String> list);
124+
}
125+
126+
static class WithInterface implements ProxyInterface {
127+
128+
public void handle(List<String> list) {
129+
}
130+
}
131+
132+
static class WithoutInterface {
133+
134+
public void handle(List<String> list) {
135+
}
136+
}
137+
102138
}

Diff for: spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/AnnotationJCacheOperationSource.java

+2-4
Original file line numberDiff line numberDiff line change
@@ -224,10 +224,8 @@ protected String generateDefaultCacheName(Method method) {
224224
for (Class<?> parameterType : parameterTypes) {
225225
parameters.add(parameterType.getName());
226226
}
227-
228-
return method.getDeclaringClass().getName()
229-
+ '.' + method.getName()
230-
+ '(' + StringUtils.collectionToCommaDelimitedString(parameters) + ')';
227+
return method.getDeclaringClass().getName() + '.' + method.getName() +
228+
'(' + StringUtils.collectionToCommaDelimitedString(parameters) + ')';
231229
}
232230

233231
private int countNonNull(Object... instances) {

Diff for: spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncAnnotationBeanPostProcessor.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -98,8 +98,8 @@ public AsyncAnnotationBeanPostProcessor() {
9898
* applying the corresponding default if a supplier is not resolvable.
9999
* @since 5.1
100100
*/
101-
public void configure(
102-
@Nullable Supplier<Executor> executor, @Nullable Supplier<AsyncUncaughtExceptionHandler> exceptionHandler) {
101+
public void configure(@Nullable Supplier<Executor> executor,
102+
@Nullable Supplier<AsyncUncaughtExceptionHandler> exceptionHandler) {
103103

104104
this.executor = executor;
105105
this.exceptionHandler = exceptionHandler;

Diff for: spring-context/src/test/java/org/springframework/validation/DataBinderConstructTests.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
*/
3939
class DataBinderConstructTests {
4040

41-
4241
@Test
4342
void dataClassBinding() {
4443
MapValueResolver valueResolver = new MapValueResolver(Map.of("param1", "value1", "param2", "true"));
@@ -78,7 +77,7 @@ void dataClassBindingWithMissingParameter() {
7877
assertThat(bindingResult.getFieldValue("param3")).isNull();
7978
}
8079

81-
@Test // gh-31821
80+
@Test // gh-31821
8281
void dataClassBindingWithNestedOptionalParameterWithMissingParameter() {
8382
MapValueResolver valueResolver = new MapValueResolver(Map.of("param1", "value1"));
8483
DataBinder binder = initDataBinder(NestedDataClass.class);

Diff for: spring-context/src/test/java/org/springframework/validation/DataBinderTests.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -2055,7 +2055,7 @@ void setAutoGrowCollectionLimitAfterInitialization() {
20552055
.withMessageContaining("DataBinder is already initialized - call setAutoGrowCollectionLimit before other configuration methods");
20562056
}
20572057

2058-
@Test // SPR-15009
2058+
@Test // SPR-15009
20592059
void setCustomMessageCodesResolverBeforeInitializeBindingResultForBeanPropertyAccess() {
20602060
TestBean testBean = new TestBean();
20612061
DataBinder binder = new DataBinder(testBean, "testBean");
@@ -2072,7 +2072,7 @@ void setCustomMessageCodesResolverBeforeInitializeBindingResultForBeanPropertyAc
20722072
assertThat(((BeanWrapper) binder.getInternalBindingResult().getPropertyAccessor()).getAutoGrowCollectionLimit()).isEqualTo(512);
20732073
}
20742074

2075-
@Test // SPR-15009
2075+
@Test // SPR-15009
20762076
void setCustomMessageCodesResolverBeforeInitializeBindingResultForDirectFieldAccess() {
20772077
TestBean testBean = new TestBean();
20782078
DataBinder binder = new DataBinder(testBean, "testBean");
@@ -2126,7 +2126,7 @@ void callSetMessageCodesResolverTwice() {
21262126
.withMessageContaining("DataBinder is already initialized with MessageCodesResolver");
21272127
}
21282128

2129-
@Test // gh-24347
2129+
@Test // gh-24347
21302130
void overrideBindingResultType() {
21312131
TestBean testBean = new TestBean();
21322132
DataBinder binder = new DataBinder(testBean, "testBean");

Diff for: spring-context/src/test/java/org/springframework/validation/beanvalidation/MethodValidationProxyTests.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,7 @@ public void testMethodValidationPostProcessor() {
8383
context.close();
8484
}
8585

86-
@Test // gh-29782
87-
@SuppressWarnings("unchecked")
86+
@Test // gh-29782
8887
public void testMethodValidationPostProcessorForInterfaceOnlyProxy() {
8988
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
9089
context.register(MethodValidationPostProcessor.class);

Diff for: spring-core/src/main/java/org/springframework/core/BridgeMethodResolver.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package org.springframework.core;
1818

1919
import java.lang.reflect.Method;
20+
import java.lang.reflect.Proxy;
2021
import java.lang.reflect.Type;
2122
import java.util.ArrayList;
2223
import java.util.Arrays;
@@ -86,7 +87,10 @@ public static Method findBridgedMethod(Method bridgeMethod) {
8687
* @see org.springframework.util.ClassUtils#getMostSpecificMethod
8788
*/
8889
public static Method getMostSpecificMethod(Method bridgeMethod, @Nullable Class<?> targetClass) {
89-
if (targetClass != null && !bridgeMethod.getDeclaringClass().isAssignableFrom(targetClass)) {
90+
if (targetClass != null &&
91+
!ClassUtils.getUserClass(bridgeMethod.getDeclaringClass()).isAssignableFrom(targetClass) &&
92+
!Proxy.isProxyClass(bridgeMethod.getDeclaringClass())) {
93+
// From a different class hierarchy, and not a JDK or CGLIB proxy either -> return as-is.
9094
return bridgeMethod;
9195
}
9296

Diff for: spring-core/src/main/java/org/springframework/core/ResolvableType.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -710,7 +710,7 @@ public ResolvableType getNested(int nestingLevel) {
710710
* @param nestingLevel the required nesting level, indexed from 1 for the
711711
* current type, 2 for the first nested generic, 3 for the second and so on
712712
* @param typeIndexesPerLevel a map containing the generic index for a given
713-
* nesting level (may be {@code null})
713+
* nesting level (can be {@code null})
714714
* @return a {@code ResolvableType} for the nested level, or {@link #NONE}
715715
*/
716716
public ResolvableType getNested(int nestingLevel, @Nullable Map<Integer, Integer> typeIndexesPerLevel) {
@@ -742,7 +742,7 @@ public ResolvableType getNested(int nestingLevel, @Nullable Map<Integer, Integer
742742
* generic is returned.
743743
* <p>If no generic is available at the specified indexes {@link #NONE} is returned.
744744
* @param indexes the indexes that refer to the generic parameter
745-
* (may be omitted to return the first generic)
745+
* (can be omitted to return the first generic)
746746
* @return a {@code ResolvableType} for the specified generic, or {@link #NONE}
747747
* @see #hasGenerics()
748748
* @see #getGenerics()
@@ -845,7 +845,7 @@ public Class<?>[] resolveGenerics(Class<?> fallback) {
845845
* Convenience method that will {@link #getGeneric(int...) get} and
846846
* {@link #resolve() resolve} a specific generic parameter.
847847
* @param indexes the indexes that refer to the generic parameter
848-
* (may be omitted to return the first generic)
848+
* (can be omitted to return the first generic)
849849
* @return a resolved {@link Class} or {@code null}
850850
* @see #getGeneric(int...)
851851
* @see #resolve()

Diff for: spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebConnectionTests.java

+10-9
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
3232
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
3333

34-
3534
/**
3635
* Integration tests for {@link MockMvcWebConnection}.
3736
*
@@ -64,14 +63,15 @@ public void contextPathExplicit() throws IOException {
6463
public void contextPathEmpty() {
6564
this.webClient.setWebConnection(new MockMvcWebConnection(this.mockMvc, this.webClient, ""));
6665
// Empty context path (root context) should not match to a URL with a context path
67-
assertThatExceptionOfType(FailingHttpStatusCodeException.class).isThrownBy(() ->
68-
this.webClient.getPage("http://localhost/context/a"))
69-
.satisfies(ex -> assertThat(ex.getStatusCode()).isEqualTo(404));
66+
assertThatExceptionOfType(FailingHttpStatusCodeException.class)
67+
.isThrownBy(() -> this.webClient.getPage("http://localhost/context/a"))
68+
.satisfies(ex -> assertThat(ex.getStatusCode()).isEqualTo(404));
69+
7070
this.webClient.setWebConnection(new MockMvcWebConnection(this.mockMvc, this.webClient));
7171
// No context is the same providing an empty context path
72-
assertThatExceptionOfType(FailingHttpStatusCodeException.class).isThrownBy(() ->
73-
this.webClient.getPage("http://localhost/context/a"))
74-
.satisfies(ex -> assertThat(ex.getStatusCode()).isEqualTo(404));
72+
assertThatExceptionOfType(FailingHttpStatusCodeException.class)
73+
.isThrownBy(() -> this.webClient.getPage("http://localhost/context/a"))
74+
.satisfies(ex -> assertThat(ex.getStatusCode()).isEqualTo(404));
7575
}
7676

7777
@Test
@@ -84,8 +84,9 @@ public void forward() throws IOException {
8484
@Test
8585
public void infiniteForward() {
8686
this.webClient.setWebConnection(new MockMvcWebConnection(this.mockMvc, this.webClient, ""));
87-
assertThatIllegalStateException().isThrownBy(() -> this.webClient.getPage("http://localhost/infiniteForward"))
88-
.withMessage("Forwarded 100 times in a row, potential infinite forward loop");
87+
assertThatIllegalStateException()
88+
.isThrownBy(() -> this.webClient.getPage("http://localhost/infiniteForward"))
89+
.withMessage("Forwarded 100 times in a row, potential infinite forward loop");
8990
}
9091

9192
@Test

Diff for: spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/MockWebResponseBuilderTests.java

+3-9
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
import static org.assertj.core.api.Assertions.assertThat;
3333
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
3434

35-
3635
/**
3736
* Tests for {@link MockWebResponseBuilder}.
3837
*
@@ -55,8 +54,6 @@ public void setup() throws Exception {
5554
}
5655

5756

58-
// --- constructor
59-
6057
@Test
6158
public void constructorWithNullWebRequest() {
6259
assertThatIllegalArgumentException().isThrownBy(() ->
@@ -66,12 +63,10 @@ public void constructorWithNullWebRequest() {
6663
@Test
6764
public void constructorWithNullResponse() {
6865
assertThatIllegalArgumentException().isThrownBy(() ->
69-
new MockWebResponseBuilder(0L, new WebRequest(new URL("http://company.example:80/test/this/here")), null));
66+
new MockWebResponseBuilder(0L,
67+
new WebRequest(new URL("http://company.example:80/test/this/here")), null));
7068
}
7169

72-
73-
// --- build
74-
7570
@Test
7671
public void buildContent() throws Exception {
7772
this.response.getWriter().write("expected content");
@@ -124,8 +119,7 @@ public void buildResponseHeaders() throws Exception {
124119
.endsWith("; Secure; HttpOnly");
125120
}
126121

127-
// SPR-14169
128-
@Test
122+
@Test // SPR-14169
129123
public void buildResponseHeadersNullDomainDefaulted() throws Exception {
130124
Cookie cookie = new Cookie("cookieA", "valueA");
131125
this.response.addCookie(cookie);

Diff for: spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/webdriver/MockMvcHtmlUnitDriverBuilderTests.java

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ class MockMvcHtmlUnitDriverBuilderTests {
5050

5151
private HtmlUnitDriver driver;
5252

53+
5354
MockMvcHtmlUnitDriverBuilderTests(WebApplicationContext wac) {
5455
this.mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
5556
}

Diff for: spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/webdriver/WebConnectionHtmlUnitDriverTests.java

+1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ class WebConnectionHtmlUnitDriverTests {
4848
@Mock
4949
private WebConnection connection;
5050

51+
5152
@BeforeEach
5253
void setup() throws Exception {
5354
given(this.connection.getResponse(any(WebRequest.class))).willThrow(new IOException(""));

Diff for: spring-web/src/main/java/org/springframework/http/converter/AbstractHttpMessageConverter.java

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -218,7 +218,6 @@ public void writeTo(OutputStream outputStream) throws IOException {
218218
public OutputStream getBody() {
219219
return outputStream;
220220
}
221-
222221
@Override
223222
public HttpHeaders getHeaders() {
224223
return headers;
@@ -304,8 +303,7 @@ protected Long getContentLength(T t, @Nullable MediaType contentType) throws IOE
304303
* Indicates whether this message converter can
305304
* {@linkplain #write(Object, MediaType, HttpOutputMessage) write} the
306305
* given object multiple times.
307-
*
308-
* <p>Default implementation returns {@code false}.
306+
* <p>The default implementation returns {@code false}.
309307
* @param t the object t
310308
* @return {@code true} if {@code t} can be written repeatedly;
311309
* {@code false} otherwise

0 commit comments

Comments
 (0)