Perform NullAway build-time checks in spring-webflux
See gh-32475
This commit is contained in:
parent
637aa9f71f
commit
0a50854e1a
|
@ -117,7 +117,8 @@ tasks.withType(JavaCompile).configureEach {
|
||||||
options.errorprone {
|
options.errorprone {
|
||||||
disableAllChecks = true
|
disableAllChecks = true
|
||||||
option("NullAway:CustomContractAnnotations", "org.springframework.lang.Contract")
|
option("NullAway:CustomContractAnnotations", "org.springframework.lang.Contract")
|
||||||
option("NullAway:AnnotatedPackages", "org.springframework.core,org.springframework.expression")
|
option("NullAway:AnnotatedPackages", "org.springframework.core,org.springframework.expression," +
|
||||||
|
"org.springframework.web.reactive")
|
||||||
option("NullAway:UnannotatedSubPackages", "org.springframework.instrument,org.springframework.context.index," +
|
option("NullAway:UnannotatedSubPackages", "org.springframework.instrument,org.springframework.context.index," +
|
||||||
"org.springframework.asm,org.springframework.cglib,org.springframework.objenesis," +
|
"org.springframework.asm,org.springframework.cglib,org.springframework.objenesis," +
|
||||||
"org.springframework.javapoet,org.springframework.aot.nativex.substitution")
|
"org.springframework.javapoet,org.springframework.aot.nativex.substitution")
|
||||||
|
|
|
@ -171,9 +171,10 @@ public class DispatcherHandler implements WebHandler, PreFlightRequestHandler, A
|
||||||
}
|
}
|
||||||
return resultMono.flatMap(result -> {
|
return resultMono.flatMap(result -> {
|
||||||
Mono<Void> voidMono = handleResult(exchange, result, "Handler " + result.getHandler());
|
Mono<Void> voidMono = handleResult(exchange, result, "Handler " + result.getHandler());
|
||||||
if (result.getExceptionHandler() != null) {
|
DispatchExceptionHandler exceptionHandler = result.getExceptionHandler();
|
||||||
|
if (exceptionHandler != null) {
|
||||||
voidMono = voidMono.onErrorResume(ex ->
|
voidMono = voidMono.onErrorResume(ex ->
|
||||||
result.getExceptionHandler().handleError(exchange, ex).flatMap(result2 ->
|
exceptionHandler.handleError(exchange, ex).flatMap(result2 ->
|
||||||
handleResult(exchange, result2, "Exception handler " +
|
handleResult(exchange, result2, "Exception handler " +
|
||||||
result2.getHandler() + ", error=\"" + ex.getMessage() + "\"")));
|
result2.getHandler() + ", error=\"" + ex.getMessage() + "\"")));
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,6 +64,7 @@ public class ResourceChainRegistration {
|
||||||
this(cacheResources, cacheResources ? new ConcurrentMapCache(DEFAULT_CACHE_NAME) : null);
|
this(cacheResources, cacheResources ? new ConcurrentMapCache(DEFAULT_CACHE_NAME) : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("NullAway")
|
||||||
public ResourceChainRegistration(boolean cacheResources, @Nullable Cache cache) {
|
public ResourceChainRegistration(boolean cacheResources, @Nullable Cache cache) {
|
||||||
Assert.isTrue(!cacheResources || cache != null, "'cache' is required when cacheResources=true");
|
Assert.isTrue(!cacheResources || cache != null, "'cache' is required when cacheResources=true");
|
||||||
if (cacheResources) {
|
if (cacheResources) {
|
||||||
|
|
|
@ -137,7 +137,7 @@ final class DefaultClientResponseBuilder implements ClientResponse.Builder {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("ConstantConditions")
|
@SuppressWarnings({"ConstantConditions", "NullAway"})
|
||||||
private HttpHeaders getHeaders() {
|
private HttpHeaders getHeaders() {
|
||||||
if (this.headers == null) {
|
if (this.headers == null) {
|
||||||
this.headers = new HttpHeaders(this.originalResponse.headers().asHttpHeaders());
|
this.headers = new HttpHeaders(this.originalResponse.headers().asHttpHeaders());
|
||||||
|
@ -159,7 +159,7 @@ final class DefaultClientResponseBuilder implements ClientResponse.Builder {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("ConstantConditions")
|
@SuppressWarnings({"ConstantConditions", "NullAway"})
|
||||||
private MultiValueMap<String, ResponseCookie> getCookies() {
|
private MultiValueMap<String, ResponseCookie> getCookies() {
|
||||||
if (this.cookies == null) {
|
if (this.cookies == null) {
|
||||||
this.cookies = new LinkedMultiValueMap<>(this.originalResponse.cookies());
|
this.cookies = new LinkedMultiValueMap<>(this.originalResponse.cookies());
|
||||||
|
@ -256,13 +256,13 @@ final class DefaultClientResponseBuilder implements ClientResponse.Builder {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("ConstantConditions")
|
@SuppressWarnings({"ConstantConditions", "NullAway"})
|
||||||
public HttpHeaders getHeaders() {
|
public HttpHeaders getHeaders() {
|
||||||
return (this.headers != null ? this.headers : this.originalResponse.headers().asHttpHeaders());
|
return (this.headers != null ? this.headers : this.originalResponse.headers().asHttpHeaders());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("ConstantConditions")
|
@SuppressWarnings({"ConstantConditions", "NullAway"})
|
||||||
public MultiValueMap<String, ResponseCookie> getCookies() {
|
public MultiValueMap<String, ResponseCookie> getCookies() {
|
||||||
return (this.cookies != null ? this.cookies : this.originalResponse.cookies());
|
return (this.cookies != null ? this.cookies : this.originalResponse.cookies());
|
||||||
}
|
}
|
||||||
|
|
|
@ -334,6 +334,7 @@ public class ResourceWebHandler implements WebHandler, InitializingBean {
|
||||||
* @param mediaTypes media type mappings
|
* @param mediaTypes media type mappings
|
||||||
* @since 5.3.2
|
* @since 5.3.2
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("NullAway")
|
||||||
public void setMediaTypes(Map<String, MediaType> mediaTypes) {
|
public void setMediaTypes(Map<String, MediaType> mediaTypes) {
|
||||||
if (this.mediaTypes == null) {
|
if (this.mediaTypes == null) {
|
||||||
this.mediaTypes = new HashMap<>(mediaTypes.size());
|
this.mediaTypes = new HashMap<>(mediaTypes.size());
|
||||||
|
@ -483,6 +484,7 @@ public class ResourceWebHandler implements WebHandler, InitializingBean {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("NullAway")
|
||||||
protected Mono<Resource> getResource(ServerWebExchange exchange) {
|
protected Mono<Resource> getResource(ServerWebExchange exchange) {
|
||||||
String rawPath = getResourcePath(exchange);
|
String rawPath = getResourcePath(exchange);
|
||||||
String path = processPath(rawPath);
|
String path = processPath(rawPath);
|
||||||
|
|
|
@ -361,6 +361,7 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("NullAway")
|
||||||
private void addMatchingMappings(Collection<T> mappings, List<Match> matches, ServerWebExchange exchange) {
|
private void addMatchingMappings(Collection<T> mappings, List<Match> matches, ServerWebExchange exchange) {
|
||||||
for (T mapping : mappings) {
|
for (T mapping : mappings) {
|
||||||
T match = getMatchingMapping(mapping, exchange);
|
T match = getMatchingMapping(mapping, exchange);
|
||||||
|
|
|
@ -46,6 +46,7 @@ import org.springframework.core.ReactiveAdapter;
|
||||||
import org.springframework.core.ReactiveAdapterRegistry;
|
import org.springframework.core.ReactiveAdapterRegistry;
|
||||||
import org.springframework.http.HttpStatusCode;
|
import org.springframework.http.HttpStatusCode;
|
||||||
import org.springframework.http.server.reactive.ServerHttpResponse;
|
import org.springframework.http.server.reactive.ServerHttpResponse;
|
||||||
|
import org.springframework.lang.Contract;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
|
@ -161,7 +162,7 @@ public class InvocableHandlerMethod extends HandlerMethod {
|
||||||
* @param providedArgs optional list of argument values to match by type
|
* @param providedArgs optional list of argument values to match by type
|
||||||
* @return a Mono with a {@link HandlerResult}
|
* @return a Mono with a {@link HandlerResult}
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings({"unchecked", "NullAway"})
|
||||||
public Mono<HandlerResult> invoke(
|
public Mono<HandlerResult> invoke(
|
||||||
ServerWebExchange exchange, BindingContext bindingContext, Object... providedArgs) {
|
ServerWebExchange exchange, BindingContext bindingContext, Object... providedArgs) {
|
||||||
|
|
||||||
|
@ -261,6 +262,7 @@ public class InvocableHandlerMethod extends HandlerMethod {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Contract("_, null -> false")
|
||||||
private static boolean isAsyncVoidReturnType(MethodParameter returnType, @Nullable ReactiveAdapter adapter) {
|
private static boolean isAsyncVoidReturnType(MethodParameter returnType, @Nullable ReactiveAdapter adapter) {
|
||||||
if (adapter != null && adapter.supportsEmpty()) {
|
if (adapter != null && adapter.supportsEmpty()) {
|
||||||
if (adapter.isNoValue()) {
|
if (adapter.isNoValue()) {
|
||||||
|
|
|
@ -165,7 +165,7 @@ public abstract class AbstractMessageWriterResultHandler extends HandlerResultHa
|
||||||
* @return indicates completion or error
|
* @return indicates completion or error
|
||||||
* @since 5.0.2
|
* @since 5.0.2
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({"rawtypes", "unchecked", "ConstantConditions"})
|
@SuppressWarnings({"rawtypes", "unchecked", "ConstantConditions", "NullAway"})
|
||||||
protected Mono<Void> writeBody(@Nullable Object body, MethodParameter bodyParameter,
|
protected Mono<Void> writeBody(@Nullable Object body, MethodParameter bodyParameter,
|
||||||
@Nullable MethodParameter actualParam, ServerWebExchange exchange) {
|
@Nullable MethodParameter actualParam, ServerWebExchange exchange) {
|
||||||
|
|
||||||
|
|
|
@ -375,6 +375,7 @@ class ControllerMethodResolver {
|
||||||
* if {@code null}, check only {@code @ControllerAdvice} classes.
|
* if {@code null}, check only {@code @ControllerAdvice} classes.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@SuppressWarnings("NullAway")
|
||||||
public InvocableHandlerMethod getExceptionHandlerMethod(Throwable ex, @Nullable HandlerMethod handlerMethod) {
|
public InvocableHandlerMethod getExceptionHandlerMethod(Throwable ex, @Nullable HandlerMethod handlerMethod) {
|
||||||
|
|
||||||
Class<?> handlerType = (handlerMethod != null ? handlerMethod.getBeanType() : null);
|
Class<?> handlerType = (handlerMethod != null ? handlerMethod.getBeanType() : null);
|
||||||
|
|
|
@ -128,7 +128,7 @@ public class ResponseEntityResultHandler extends AbstractMessageWriterResultHand
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("ConstantConditions")
|
@SuppressWarnings({"ConstantConditions", "NullAway"})
|
||||||
public Mono<Void> handleResult(ServerWebExchange exchange, HandlerResult result) {
|
public Mono<Void> handleResult(ServerWebExchange exchange, HandlerResult result) {
|
||||||
|
|
||||||
Mono<?> returnValueMono;
|
Mono<?> returnValueMono;
|
||||||
|
|
|
@ -28,6 +28,7 @@ import io.netty5.handler.codec.http.websocketx.WebSocketFrame;
|
||||||
|
|
||||||
import org.springframework.core.io.buffer.DataBuffer;
|
import org.springframework.core.io.buffer.DataBuffer;
|
||||||
import org.springframework.core.io.buffer.Netty5DataBufferFactory;
|
import org.springframework.core.io.buffer.Netty5DataBufferFactory;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
import org.springframework.web.reactive.socket.HandshakeInfo;
|
import org.springframework.web.reactive.socket.HandshakeInfo;
|
||||||
import org.springframework.web.reactive.socket.WebSocketMessage;
|
import org.springframework.web.reactive.socket.WebSocketMessage;
|
||||||
|
@ -76,7 +77,9 @@ public abstract class Netty5WebSocketSessionSupport<T> extends AbstractWebSocket
|
||||||
|
|
||||||
protected WebSocketMessage toMessage(WebSocketFrame frame) {
|
protected WebSocketMessage toMessage(WebSocketFrame frame) {
|
||||||
DataBuffer payload = bufferFactory().wrap(frame.binaryData());
|
DataBuffer payload = bufferFactory().wrap(frame.binaryData());
|
||||||
return new WebSocketMessage(messageTypes.get(frame.getClass()), payload, frame);
|
WebSocketMessage.Type messageType = messageTypes.get(frame.getClass());
|
||||||
|
Assert.state(messageType != null, "Unexpected message type");
|
||||||
|
return new WebSocketMessage(messageType, payload, frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected WebSocketFrame toFrame(WebSocketMessage message) {
|
protected WebSocketFrame toFrame(WebSocketMessage message) {
|
||||||
|
|
|
@ -28,6 +28,7 @@ import io.netty.handler.codec.http.websocketx.WebSocketFrame;
|
||||||
|
|
||||||
import org.springframework.core.io.buffer.DataBuffer;
|
import org.springframework.core.io.buffer.DataBuffer;
|
||||||
import org.springframework.core.io.buffer.NettyDataBufferFactory;
|
import org.springframework.core.io.buffer.NettyDataBufferFactory;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
import org.springframework.web.reactive.socket.HandshakeInfo;
|
import org.springframework.web.reactive.socket.HandshakeInfo;
|
||||||
import org.springframework.web.reactive.socket.WebSocketMessage;
|
import org.springframework.web.reactive.socket.WebSocketMessage;
|
||||||
|
@ -74,7 +75,9 @@ public abstract class NettyWebSocketSessionSupport<T> extends AbstractWebSocketS
|
||||||
|
|
||||||
protected WebSocketMessage toMessage(WebSocketFrame frame) {
|
protected WebSocketMessage toMessage(WebSocketFrame frame) {
|
||||||
DataBuffer payload = bufferFactory().wrap(frame.content());
|
DataBuffer payload = bufferFactory().wrap(frame.content());
|
||||||
return new WebSocketMessage(messageTypes.get(frame.getClass()), payload, frame);
|
WebSocketMessage.Type messageType = messageTypes.get(frame.getClass());
|
||||||
|
Assert.state(messageType != null, "Unexpected message type");
|
||||||
|
return new WebSocketMessage(messageType, payload, frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected WebSocketFrame toFrame(WebSocketMessage message) {
|
protected WebSocketFrame toFrame(WebSocketMessage message) {
|
||||||
|
|
|
@ -65,6 +65,7 @@ public class StandardWebSocketHandlerAdapter extends Endpoint {
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@SuppressWarnings("NullAway")
|
||||||
public void onOpen(Session session, EndpointConfig config) {
|
public void onOpen(Session session, EndpointConfig config) {
|
||||||
this.delegateSession = this.sessionFactory.apply(session);
|
this.delegateSession = this.sessionFactory.apply(session);
|
||||||
Assert.state(this.delegateSession != null, "No delegate session");
|
Assert.state(this.delegateSession != null, "No delegate session");
|
||||||
|
|
|
@ -244,6 +244,7 @@ public class HandshakeWebSocketService implements WebSocketService, Lifecycle {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("NullAway")
|
||||||
private Mono<Map<String, Object>> initAttributes(ServerWebExchange exchange) {
|
private Mono<Map<String, Object>> initAttributes(ServerWebExchange exchange) {
|
||||||
if (this.sessionAttributePredicate == null) {
|
if (this.sessionAttributePredicate == null) {
|
||||||
return EMPTY_ATTRIBUTES;
|
return EMPTY_ATTRIBUTES;
|
||||||
|
|
Loading…
Reference in New Issue