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

@@ -19,7 +19,6 @@ package org.springframework.core;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Objects;
import kotlin.Unit;
import kotlin.coroutines.CoroutineContext;
@@ -112,7 +111,8 @@ public abstract class CoroutinesUtils {
public static Publisher<?> invokeSuspendingFunction(CoroutineContext context, Method method, Object target,
Object... args) {
Assert.isTrue(KotlinDetector.isSuspendingFunction(method), "'method' must be a suspending function");
KFunction<?> function = Objects.requireNonNull(ReflectJvmMapping.getKotlinFunction(method));
KFunction<?> function = ReflectJvmMapping.getKotlinFunction(method);
Assert.notNull(function, () -> "Failed to get Kotlin function for method: " + method);
if (method.isAccessible() && !KCallablesJvm.isAccessible(function)) {
KCallablesJvm.setAccessible(function, true);
}

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.
@@ -16,7 +16,6 @@
package org.springframework.core;
import java.util.Objects;
import java.util.function.Supplier;
import org.springframework.util.Assert;
@@ -76,7 +75,8 @@ public class NamedThreadLocal<T> extends ThreadLocal<T> {
SuppliedNamedThreadLocal(String name, Supplier<? extends T> supplier) {
super(name);
this.supplier = Objects.requireNonNull(supplier);
Assert.notNull(supplier, "Supplier must not be null");
this.supplier = supplier;
}
@Override

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.
@@ -19,7 +19,6 @@ package org.springframework.core;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
@@ -383,8 +382,8 @@ public class ReactiveAdapterRegistry {
Method multiPublisher = ClassUtils.getMethod(
io.smallrye.mutiny.groups.MultiCreate.class, "publisher", Flow.Publisher.class);
registry.registerReactiveType(uniDesc,
uni -> FlowAdapters.toPublisher((Flow.Publisher<Object>) Objects.requireNonNull(
ReflectionUtils.invokeMethod(uniToPublisher, ((io.smallrye.mutiny.Uni<?>) uni).convert()))),
uni -> FlowAdapters.toPublisher((Flow.Publisher<Object>)
ReflectionUtils.invokeMethod(uniToPublisher, ((io.smallrye.mutiny.Uni<?>) uni).convert())),
publisher -> ReflectionUtils.invokeMethod(uniPublisher, io.smallrye.mutiny.Uni.createFrom(),
FlowAdapters.toFlowPublisher(publisher)));
registry.registerReactiveType(multiDesc,

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.
@@ -66,6 +66,8 @@ final class OutputStreamPublisher implements Publisher<DataBuffer> {
@Override
public void subscribe(Subscriber<? super DataBuffer> 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 subscription = new OutputStreamSubscription(