diff --git a/build.gradle b/build.gradle index f85b7774680..81c20d59b41 100644 --- a/build.gradle +++ b/build.gradle @@ -39,7 +39,7 @@ ext { junit5Version = "5.5.1" kotlinVersion = "1.3.41" log4jVersion = "2.12.0" - nettyVersion = "4.1.37.Final" + nettyVersion = "4.1.38.Final" reactorVersion = "Dysprosium-M3" rsocketVersion = "0.12.2-RC4" rxjavaVersion = "1.3.8" @@ -149,7 +149,7 @@ configure(allprojects) { project -> } checkstyle { - toolVersion = "8.22" + toolVersion = "8.23" configDir = rootProject.file("src/checkstyle") } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/DependencyDescriptor.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/DependencyDescriptor.java index 5e20b8ad136..92e902d458e 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/DependencyDescriptor.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/DependencyDescriptor.java @@ -430,7 +430,7 @@ public class DependencyDescriptor extends InjectionPoint implements Serializable @Override public int hashCode() { - return 31 * super.hashCode() + ObjectUtils.nullSafeHashCode(this.containingClass); + return (31 * super.hashCode() + ObjectUtils.nullSafeHashCode(this.containingClass)); } diff --git a/spring-context/src/main/java/org/springframework/validation/ObjectError.java b/spring-context/src/main/java/org/springframework/validation/ObjectError.java index bd1c1ff7e24..227cd083952 100644 --- a/spring-context/src/main/java/org/springframework/validation/ObjectError.java +++ b/spring-context/src/main/java/org/springframework/validation/ObjectError.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -144,7 +144,7 @@ public class ObjectError extends DefaultMessageSourceResolvable { @Override public int hashCode() { - return super.hashCode() * 29 + getObjectName().hashCode(); + return (29 * super.hashCode() + getObjectName().hashCode()); } @Override diff --git a/spring-core/src/main/java/org/springframework/core/MethodParameter.java b/spring-core/src/main/java/org/springframework/core/MethodParameter.java index 059660d08e7..b8eba8a3ef6 100644 --- a/spring-core/src/main/java/org/springframework/core/MethodParameter.java +++ b/spring-core/src/main/java/org/springframework/core/MethodParameter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -39,6 +39,7 @@ import kotlin.reflect.jvm.ReflectJvmMapping; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; +import org.springframework.util.ObjectUtils; /** * Helper class that encapsulates the specification of a method parameter, i.e. a {@link Method} @@ -61,6 +62,7 @@ public class MethodParameter { private static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0]; + private final Executable executable; private final int parameterIndex; @@ -68,7 +70,7 @@ public class MethodParameter { @Nullable private volatile Parameter parameter; - private int nestingLevel = 1; + private int nestingLevel; /** Map from Integer level to Integer type index. */ @Nullable @@ -662,12 +664,16 @@ public class MethodParameter { return false; } MethodParameter otherParam = (MethodParameter) other; - return (this.parameterIndex == otherParam.parameterIndex && getExecutable().equals(otherParam.getExecutable())); + return (this.containingClass == otherParam.containingClass && + ObjectUtils.nullSafeEquals(this.typeIndexesPerLevel, otherParam.typeIndexesPerLevel) && + this.nestingLevel == otherParam.nestingLevel && + this.parameterIndex == otherParam.parameterIndex && + this.executable.equals(otherParam.executable)); } @Override public int hashCode() { - return (getExecutable().hashCode() * 31 + this.parameterIndex); + return (31 * this.executable.hashCode() + this.parameterIndex); } @Override diff --git a/spring-core/src/test/java/org/springframework/core/MethodParameterTests.java b/spring-core/src/test/java/org/springframework/core/MethodParameterTests.java index ab412ede15c..6353a797e57 100644 --- a/spring-core/src/test/java/org/springframework/core/MethodParameterTests.java +++ b/spring-core/src/test/java/org/springframework/core/MethodParameterTests.java @@ -22,6 +22,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.lang.reflect.Constructor; import java.lang.reflect.Method; +import java.util.ArrayList; import java.util.concurrent.Callable; import org.junit.Before; @@ -149,6 +150,44 @@ public class MethodParameterTests { assertThat(methodParameter.getGenericParameterType()).isEqualTo(ResolvableType.forClassWithGenerics(Callable.class, Integer.class).getType()); } + @Test + public void multipleResolveParameterTypeCalls() throws Exception { + Method method = ArrayList.class.getMethod("get", int.class); + MethodParameter methodParameter = MethodParameter.forExecutable(method, -1); + assertEquals(Object.class, methodParameter.getParameterType()); + GenericTypeResolver.resolveParameterType(methodParameter, StringList.class); + assertEquals(String.class, methodParameter.getParameterType()); + GenericTypeResolver.resolveParameterType(methodParameter, IntegerList.class); + assertEquals(Integer.class, methodParameter.getParameterType()); + } + + @Test + public void equalsAndHashCodeConsidersContainingClass() throws Exception { + Method method = ArrayList.class.getMethod("get", int.class); + MethodParameter m1 = MethodParameter.forExecutable(method, -1); + MethodParameter m2 = MethodParameter.forExecutable(method, -1); + MethodParameter m3 = MethodParameter.forExecutable(method, -1).nested(); + assertEquals(m1, m2); + assertNotEquals(m1, m3); + assertEquals(m1.hashCode(), m2.hashCode()); + } + + @Test + public void equalsAndHashCodeConsidersNesting() throws Exception { + Method method = ArrayList.class.getMethod("get", int.class); + MethodParameter m1 = MethodParameter.forExecutable(method, -1); + GenericTypeResolver.resolveParameterType(m1, StringList.class); + MethodParameter m2 = MethodParameter.forExecutable(method, -1); + GenericTypeResolver.resolveParameterType(m2, StringList.class); + MethodParameter m3 = MethodParameter.forExecutable(method, -1); + GenericTypeResolver.resolveParameterType(m3, IntegerList.class); + MethodParameter m4 = MethodParameter.forExecutable(method, -1); + assertEquals(m1, m2); + assertNotEquals(m1, m3); + assertNotEquals(m1, m4); + assertEquals(m1.hashCode(), m2.hashCode()); + } + public int method(String p1, long p2) { return 42; @@ -173,4 +212,12 @@ public class MethodParameterTests { private @interface Param { } + @SuppressWarnings("serial") + private static class StringList extends ArrayList { + } + + @SuppressWarnings("serial") + private static class IntegerList extends ArrayList { + } + } diff --git a/spring-jms/src/main/java/org/springframework/jms/connection/CachingConnectionFactory.java b/spring-jms/src/main/java/org/springframework/jms/connection/CachingConnectionFactory.java index 36c160948ad..c2fb05e6181 100644 --- a/spring-jms/src/main/java/org/springframework/jms/connection/CachingConnectionFactory.java +++ b/spring-jms/src/main/java/org/springframework/jms/connection/CachingConnectionFactory.java @@ -591,7 +591,7 @@ public class CachingConnectionFactory extends SingleConnectionFactory { @Override public int hashCode() { - return 31 * super.hashCode() + ObjectUtils.nullSafeHashCode(this.selector); + return (31 * super.hashCode() + ObjectUtils.nullSafeHashCode(this.selector)); } @Override diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/HandlerMethodArgumentResolverComposite.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/HandlerMethodArgumentResolverComposite.java index cd0a7ed0219..89ecd7b5253 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/HandlerMethodArgumentResolverComposite.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/HandlerMethodArgumentResolverComposite.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -110,9 +110,8 @@ public class HandlerMethodArgumentResolverComposite implements HandlerMethodArgu public Object resolveArgument(MethodParameter parameter, Message message) throws Exception { HandlerMethodArgumentResolver resolver = getArgumentResolver(parameter); if (resolver == null) { - throw new IllegalStateException( - "Unsupported parameter type [" + parameter.getParameterType().getName() + "]." + - " supportsParameter should be called first."); + throw new IllegalArgumentException("Unsupported parameter type [" + + parameter.getParameterType().getName() + "]. supportsParameter should be called first."); } return resolver.resolveArgument(parameter, message); } diff --git a/spring-test/src/main/java/org/springframework/test/context/web/WebMergedContextConfiguration.java b/spring-test/src/main/java/org/springframework/test/context/web/WebMergedContextConfiguration.java index dbc4e1184a2..c0d2819afa7 100644 --- a/spring-test/src/main/java/org/springframework/test/context/web/WebMergedContextConfiguration.java +++ b/spring-test/src/main/java/org/springframework/test/context/web/WebMergedContextConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2019 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. @@ -178,7 +178,7 @@ public class WebMergedContextConfiguration extends MergedContextConfiguration { */ @Override public int hashCode() { - return super.hashCode() * 31 + this.resourceBasePath.hashCode(); + return (31 * super.hashCode() + this.resourceBasePath.hashCode()); } /** diff --git a/spring-web/src/main/java/org/springframework/http/ResponseEntity.java b/spring-web/src/main/java/org/springframework/http/ResponseEntity.java index 5ac6bfdba93..1f71b7957fc 100644 --- a/spring-web/src/main/java/org/springframework/http/ResponseEntity.java +++ b/spring-web/src/main/java/org/springframework/http/ResponseEntity.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -169,7 +169,7 @@ public class ResponseEntity extends HttpEntity { @Override public int hashCode() { - return (super.hashCode() * 29 + ObjectUtils.nullSafeHashCode(this.status)); + return (29 * super.hashCode() + ObjectUtils.nullSafeHashCode(this.status)); } @Override diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractServerHttpResponse.java b/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractServerHttpResponse.java index 7207213fb6a..a94afe08f9e 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractServerHttpResponse.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractServerHttpResponse.java @@ -108,7 +108,7 @@ public abstract class AbstractServerHttpResponse implements ServerHttpResponse { @Override @Nullable public HttpStatus getStatusCode() { - return this.statusCode != null ? HttpStatus.resolve(this.statusCode) : null; + return (this.statusCode != null ? HttpStatus.resolve(this.statusCode) : null); } /** diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/ReactorServerHttpResponse.java b/spring-web/src/main/java/org/springframework/http/server/reactive/ReactorServerHttpResponse.java index 4eedad0c2bf..4675d517045 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/ReactorServerHttpResponse.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/ReactorServerHttpResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -19,7 +19,6 @@ package org.springframework.http.server.reactive; import java.nio.file.Path; import io.netty.buffer.ByteBuf; -import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.cookie.Cookie; import io.netty.handler.codec.http.cookie.DefaultCookie; import org.reactivestreams.Publisher; @@ -62,14 +61,9 @@ class ReactorServerHttpResponse extends AbstractServerHttpResponse implements Ze } @Override - @SuppressWarnings("ConstantConditions") public HttpStatus getStatusCode() { HttpStatus httpStatus = super.getStatusCode(); - if (httpStatus == null) { - HttpResponseStatus status = this.response.status(); - httpStatus = status != null ? HttpStatus.resolve(status.code()) : null; - } - return httpStatus; + return (httpStatus != null ? httpStatus : HttpStatus.resolve(this.response.status().code())); } diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpResponse.java b/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpResponse.java index f8bc23d9df6..ffcddb680fa 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpResponse.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -100,7 +100,7 @@ class ServletServerHttpResponse extends AbstractListenerServerHttpResponse { @Override public HttpStatus getStatusCode() { HttpStatus httpStatus = super.getStatusCode(); - return httpStatus != null ? httpStatus : HttpStatus.resolve(this.response.getStatus()); + return (httpStatus != null ? httpStatus : HttpStatus.resolve(this.response.getStatus())); } @Override diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowServerHttpResponse.java b/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowServerHttpResponse.java index ba4f5109c22..1fb094b5b08 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowServerHttpResponse.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowServerHttpResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -69,8 +69,7 @@ class UndertowServerHttpResponse extends AbstractListenerServerHttpResponse impl } private static HttpHeaders createHeaders(HttpServerExchange exchange) { - UndertowHeadersAdapter headersMap = - new UndertowHeadersAdapter(exchange.getResponseHeaders()); + UndertowHeadersAdapter headersMap = new UndertowHeadersAdapter(exchange.getResponseHeaders()); return new HttpHeaders(headersMap); } @@ -84,7 +83,7 @@ class UndertowServerHttpResponse extends AbstractListenerServerHttpResponse impl @Override public HttpStatus getStatusCode() { HttpStatus httpStatus = super.getStatusCode(); - return httpStatus != null ? httpStatus : HttpStatus.resolve(this.exchange.getStatusCode()); + return (httpStatus != null ? httpStatus : HttpStatus.resolve(this.exchange.getStatusCode())); } diff --git a/spring-web/src/main/java/org/springframework/web/method/support/HandlerMethodArgumentResolverComposite.java b/spring-web/src/main/java/org/springframework/web/method/support/HandlerMethodArgumentResolverComposite.java index 3bcb69d12c0..1f567865750 100644 --- a/spring-web/src/main/java/org/springframework/web/method/support/HandlerMethodArgumentResolverComposite.java +++ b/spring-web/src/main/java/org/springframework/web/method/support/HandlerMethodArgumentResolverComposite.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -119,9 +119,8 @@ public class HandlerMethodArgumentResolverComposite implements HandlerMethodArgu HandlerMethodArgumentResolver resolver = getArgumentResolver(parameter); if (resolver == null) { - throw new IllegalArgumentException( - "Unsupported parameter type [" + parameter.getParameterType().getName() + "]." + - " supportsParameter should be called first."); + throw new IllegalArgumentException("Unsupported parameter type [" + + parameter.getParameterType().getName() + "]. supportsParameter should be called first."); } return resolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory); } diff --git a/spring-web/src/test/java/org/springframework/web/method/support/HandlerMethodArgumentResolverCompositeTests.java b/spring-web/src/test/java/org/springframework/web/method/support/HandlerMethodArgumentResolverCompositeTests.java index 17043120c15..a5137a1d859 100644 --- a/spring-web/src/test/java/org/springframework/web/method/support/HandlerMethodArgumentResolverCompositeTests.java +++ b/spring-web/src/test/java/org/springframework/web/method/support/HandlerMethodArgumentResolverCompositeTests.java @@ -41,7 +41,7 @@ public class HandlerMethodArgumentResolverCompositeTests { @Before - public void setUp() throws Exception { + public void setup() throws Exception { this.resolverComposite = new HandlerMethodArgumentResolverComposite(); Method method = getClass().getDeclaredMethod("handle", Integer.class, String.class); @@ -51,7 +51,7 @@ public class HandlerMethodArgumentResolverCompositeTests { @Test - public void supportsParameter() { + public void supportsParameter() throws Exception { this.resolverComposite.addResolver(new StubArgumentResolver(Integer.class)); assertThat(this.resolverComposite.supportsParameter(paramInt)).isTrue(); diff --git a/spring-web/src/test/java/org/springframework/web/method/support/HandlerMethodReturnValueHandlerCompositeTests.java b/spring-web/src/test/java/org/springframework/web/method/support/HandlerMethodReturnValueHandlerCompositeTests.java index d23581c5b39..3870e1b8877 100644 --- a/spring-web/src/test/java/org/springframework/web/method/support/HandlerMethodReturnValueHandlerCompositeTests.java +++ b/spring-web/src/test/java/org/springframework/web/method/support/HandlerMethodReturnValueHandlerCompositeTests.java @@ -30,6 +30,7 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; /** * Test fixture with {@link HandlerMethodReturnValueHandlerComposite}. + * * @author Rossen Stoyanchev */ @SuppressWarnings("unused") @@ -47,8 +48,7 @@ public class HandlerMethodReturnValueHandlerCompositeTests { @Before - public void setUp() throws Exception { - + public void setup() throws Exception { this.integerType = new MethodParameter(getClass().getDeclaredMethod("handleInteger"), -1); this.stringType = new MethodParameter(getClass().getDeclaredMethod("handleString"), -1); @@ -61,6 +61,7 @@ public class HandlerMethodReturnValueHandlerCompositeTests { mavContainer = new ModelAndViewContainer(); } + @Test public void supportsReturnType() throws Exception { assertThat(this.handlers.supportsReturnType(this.integerType)).isTrue(); @@ -84,9 +85,8 @@ public class HandlerMethodReturnValueHandlerCompositeTests { verifyNoMoreInteractions(anotherIntegerHandler); } - @Test // SPR-13083 + @Test // SPR-13083 public void handleReturnValueWithAsyncHandler() throws Exception { - Promise promise = new Promise<>(); MethodParameter promiseType = new MethodParameter(getClass().getDeclaredMethod("handlePromise"), -1);