Revise use of Objects.requireNonNull()

Historically, we have rarely intentionally thrown a
NullPointerException in the Spring Framework. Instead, we prefer to
throw either an IllegalArgumentException or IllegalStateException
instead of a NullPointerException.

However, changes to the code in recent times have introduced the use of
Objects.requireNonNull(Object) which throws a NullPointerException
without an explicit error message.

The latter ends up providing less context than a NullPointerException
thrown by the JVM (since Java 14) due to actually de-referencing a
null-pointer. See https://openjdk.org/jeps/358.

In light of that, this commit revises our current use of
Objects.requireNonNull(Object) by removing it or replacing it with
Assert.notNull().

However, we still use Objects.requireNonNull(T, String) in a few places
where we are required to throw a NullPointerException in order to
comply with a third-party contract such as Reactive Streams.

Closes gh-32430
This commit is contained in:
Sam Brannen
2024-03-13 14:31:33 +01:00
parent d6422d368a
commit 986c4fd926
11 changed files with 37 additions and 27 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 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.
@@ -150,6 +150,8 @@ final class OutputStreamPublisher<T> implements Flow.Publisher<T> {
@Override
public void subscribe(Flow.Subscriber<? super T> subscriber) {
// We don't use Assert.notNull(), because a NullPointerException is required
// for Reactive Streams compliance.
Objects.requireNonNull(subscriber, "Subscriber must not be null");
OutputStreamSubscription<T> subscription = new OutputStreamSubscription<>(subscriber, this.outputStreamHandler,

View File

@@ -18,7 +18,6 @@ package org.springframework.web.method.annotation;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import jakarta.servlet.ServletException;
@@ -35,6 +34,7 @@ import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.core.KotlinDetector;
import org.springframework.core.MethodParameter;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ValueConstants;
@@ -342,7 +342,8 @@ public abstract class AbstractNamedValueMethodArgumentResolver implements Handle
* or an optional parameter (with a default value in the Kotlin declaration).
*/
public static boolean hasDefaultValue(MethodParameter parameter) {
Method method = Objects.requireNonNull(parameter.getMethod());
Method method = parameter.getMethod();
Assert.notNull(method, () -> "Retrieved null method from MethodParameter: " + parameter);
KFunction<?> function = ReflectJvmMapping.getKotlinFunction(method);
if (function != null) {
int index = 0;