Browse Source

Upgrade to NullAway 0.12.10 and refine nullability

Closes gh-35492
pull/35503/head
Sébastien Deleuze 3 months ago
parent
commit
da0a36bfd6
  1. 3
      gradle/spring-module.gradle
  2. 2
      spring-core/src/main/java/org/springframework/util/function/SingletonSupplier.java
  3. 17
      spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java
  4. 4
      spring-jdbc/src/main/java/org/springframework/jdbc/core/RowMapperResultSetExtractor.java
  5. 2
      spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/NamedParameterJdbcTemplate.java
  6. 1
      spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/AbstractJdbcInsert.java
  7. 5
      spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/DefaultJdbcClient.java
  8. 2
      spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/JdbcClient.java
  9. 15
      spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClient.java
  10. 6
      spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java
  11. 2
      spring-test/src/main/java/org/springframework/test/web/servlet/client/DefaultRestTestClient.java
  12. 2
      spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java
  13. 4
      spring-web/src/main/java/org/springframework/web/client/DefaultRestClient.java
  14. 7
      spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerMapping.java
  15. 7
      spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java

3
gradle/spring-module.gradle

@ -119,3 +119,6 @@ publishing {
components.java.withVariantsFromConfiguration(configurations.testFixturesApiElements) { skip() } components.java.withVariantsFromConfiguration(configurations.testFixturesApiElements) { skip() }
components.java.withVariantsFromConfiguration(configurations.testFixturesRuntimeElements) { skip() } components.java.withVariantsFromConfiguration(configurations.testFixturesRuntimeElements) { skip() }
nullability {
nullAwayVersion = "0.12.10"
}

2
spring-core/src/main/java/org/springframework/util/function/SingletonSupplier.java

@ -39,7 +39,7 @@ import org.springframework.util.Assert;
* @since 5.1 * @since 5.1
* @param <T> the type of results supplied by this supplier * @param <T> the type of results supplied by this supplier
*/ */
public class SingletonSupplier<T> implements Supplier<@Nullable T> { public class SingletonSupplier<T extends @Nullable Object> implements Supplier<T> {
private final @Nullable Supplier<? extends @Nullable T> instanceSupplier; private final @Nullable Supplier<? extends @Nullable T> instanceSupplier;

17
spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java

@ -441,7 +441,6 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
} }
@Override @Override
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
public void execute(String sql) throws DataAccessException { public void execute(String sql) throws DataAccessException {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("Executing SQL statement [" + sql + "]"); logger.debug("Executing SQL statement [" + sql + "]");
@ -464,7 +463,6 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
} }
@Override @Override
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
public <T extends @Nullable Object> T query(String sql, ResultSetExtractor<T> rse) throws DataAccessException { public <T extends @Nullable Object> T query(String sql, ResultSetExtractor<T> rse) throws DataAccessException {
Assert.notNull(sql, "SQL must not be null"); Assert.notNull(sql, "SQL must not be null");
Assert.notNull(rse, "ResultSetExtractor must not be null"); Assert.notNull(rse, "ResultSetExtractor must not be null");
@ -475,7 +473,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
// Callback to execute the query. // Callback to execute the query.
class QueryStatementCallback implements StatementCallback<T>, SqlProvider { class QueryStatementCallback implements StatementCallback<T>, SqlProvider {
@Override @Override
public @Nullable T doInStatement(Statement stmt) throws SQLException { public T doInStatement(Statement stmt) throws SQLException {
ResultSet rs = null; ResultSet rs = null;
try { try {
rs = stmt.executeQuery(sql); rs = stmt.executeQuery(sql);
@ -495,7 +493,6 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
} }
@Override @Override
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
public void query(String sql, RowCallbackHandler rch) throws DataAccessException { public void query(String sql, RowCallbackHandler rch) throws DataAccessException {
query(sql, new RowCallbackHandlerResultSetExtractor(rch, this.maxRows)); query(sql, new RowCallbackHandlerResultSetExtractor(rch, this.maxRows));
} }
@ -544,7 +541,6 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
} }
@Override @Override
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
public <T> List<@Nullable T> queryForList(String sql, Class<T> elementType) throws DataAccessException { public <T> List<@Nullable T> queryForList(String sql, Class<T> elementType) throws DataAccessException {
return query(sql, getSingleColumnRowMapper(elementType)); return query(sql, getSingleColumnRowMapper(elementType));
} }
@ -725,7 +721,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
* @return an arbitrary result object, as returned by the ResultSetExtractor * @return an arbitrary result object, as returned by the ResultSetExtractor
* @throws DataAccessException if there is any problem * @throws DataAccessException if there is any problem
*/ */
public <T> @Nullable T query( public <T extends @Nullable Object> T query(
PreparedStatementCreator psc, @Nullable PreparedStatementSetter pss, ResultSetExtractor<T> rse) PreparedStatementCreator psc, @Nullable PreparedStatementSetter pss, ResultSetExtractor<T> rse)
throws DataAccessException { throws DataAccessException {
@ -751,13 +747,11 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
} }
@Override @Override
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
public <T extends @Nullable Object> T query(PreparedStatementCreator psc, ResultSetExtractor<T> rse) throws DataAccessException { public <T extends @Nullable Object> T query(PreparedStatementCreator psc, ResultSetExtractor<T> rse) throws DataAccessException {
return query(psc, null, rse); return query(psc, null, rse);
} }
@Override @Override
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
public <T extends @Nullable Object> T query(String sql, @Nullable PreparedStatementSetter pss, ResultSetExtractor<T> rse) throws DataAccessException { public <T extends @Nullable Object> T query(String sql, @Nullable PreparedStatementSetter pss, ResultSetExtractor<T> rse) throws DataAccessException {
return query(new SimplePreparedStatementCreator(sql), pss, rse); return query(new SimplePreparedStatementCreator(sql), pss, rse);
} }
@ -779,13 +773,11 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
} }
@Override @Override
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
public void query(PreparedStatementCreator psc, RowCallbackHandler rch) throws DataAccessException { public void query(PreparedStatementCreator psc, RowCallbackHandler rch) throws DataAccessException {
query(psc, new RowCallbackHandlerResultSetExtractor(rch, this.maxRows)); query(psc, new RowCallbackHandlerResultSetExtractor(rch, this.maxRows));
} }
@Override @Override
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
public void query(String sql, @Nullable PreparedStatementSetter pss, RowCallbackHandler rch) throws DataAccessException { public void query(String sql, @Nullable PreparedStatementSetter pss, RowCallbackHandler rch) throws DataAccessException {
query(sql, pss, new RowCallbackHandlerResultSetExtractor(rch, this.maxRows)); query(sql, pss, new RowCallbackHandlerResultSetExtractor(rch, this.maxRows));
} }
@ -930,20 +922,17 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
} }
@Override @Override
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
public <T> List<@Nullable T> queryForList(String sql, @Nullable Object @Nullable [] args, int[] argTypes, Class<T> elementType) throws DataAccessException { public <T> List<@Nullable T> queryForList(String sql, @Nullable Object @Nullable [] args, int[] argTypes, Class<T> elementType) throws DataAccessException {
return query(sql, args, argTypes, getSingleColumnRowMapper(elementType)); return query(sql, args, argTypes, getSingleColumnRowMapper(elementType));
} }
@Deprecated(since = "5.3") @Deprecated(since = "5.3")
@Override @Override
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
public <T> List<@Nullable T> queryForList(String sql, @Nullable Object @Nullable [] args, Class<T> elementType) throws DataAccessException { public <T> List<@Nullable T> queryForList(String sql, @Nullable Object @Nullable [] args, Class<T> elementType) throws DataAccessException {
return query(sql, newArgPreparedStatementSetter(args), getSingleColumnRowMapper(elementType)); return query(sql, newArgPreparedStatementSetter(args), getSingleColumnRowMapper(elementType));
} }
@Override @Override
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
public <T> List<@Nullable T> queryForList(String sql, Class<T> elementType, @Nullable Object @Nullable ... args) throws DataAccessException { public <T> List<@Nullable T> queryForList(String sql, Class<T> elementType, @Nullable Object @Nullable ... args) throws DataAccessException {
return query(sql, newArgPreparedStatementSetter(args), getSingleColumnRowMapper(elementType)); return query(sql, newArgPreparedStatementSetter(args), getSingleColumnRowMapper(elementType));
} }
@ -1413,7 +1402,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
* @return the RowMapper to use * @return the RowMapper to use
* @see SingleColumnRowMapper * @see SingleColumnRowMapper
*/ */
protected <T extends @Nullable Object> RowMapper<T> getSingleColumnRowMapper(Class<T> requiredType) { protected <T> RowMapper<@Nullable T> getSingleColumnRowMapper(Class<T> requiredType) {
return new SingleColumnRowMapper<>(requiredType); return new SingleColumnRowMapper<>(requiredType);
} }

4
spring-jdbc/src/main/java/org/springframework/jdbc/core/RowMapperResultSetExtractor.java

@ -21,8 +21,6 @@ import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
/** /**
@ -61,7 +59,7 @@ import org.springframework.util.Assert;
* @see JdbcTemplate * @see JdbcTemplate
* @see org.springframework.jdbc.object.MappingSqlQuery * @see org.springframework.jdbc.object.MappingSqlQuery
*/ */
public class RowMapperResultSetExtractor<T extends @Nullable Object> implements ResultSetExtractor<List<T>> { public class RowMapperResultSetExtractor<T> implements ResultSetExtractor<List<T>> {
private final RowMapper<T> rowMapper; private final RowMapper<T> rowMapper;

2
spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/NamedParameterJdbcTemplate.java

@ -294,7 +294,6 @@ public class NamedParameterJdbcTemplate implements NamedParameterJdbcOperations
} }
@Override @Override
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
public <T> List<@Nullable T> queryForList(String sql, SqlParameterSource paramSource, Class<T> elementType) public <T> List<@Nullable T> queryForList(String sql, SqlParameterSource paramSource, Class<T> elementType)
throws DataAccessException { throws DataAccessException {
@ -302,7 +301,6 @@ public class NamedParameterJdbcTemplate implements NamedParameterJdbcOperations
} }
@Override @Override
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
public <T> List<@Nullable T> queryForList(String sql, Map<String, ?> paramMap, Class<T> elementType) public <T> List<@Nullable T> queryForList(String sql, Map<String, ?> paramMap, Class<T> elementType)
throws DataAccessException { throws DataAccessException {

1
spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/AbstractJdbcInsert.java

@ -448,7 +448,6 @@ public abstract class AbstractJdbcInsert {
/** /**
* Delegate method to execute the insert, generating any number of keys. * Delegate method to execute the insert, generating any number of keys.
*/ */
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
private KeyHolder executeInsertAndReturnKeyHolderInternal(List<?> values) { private KeyHolder executeInsertAndReturnKeyHolderInternal(List<?> values) {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("The following parameters are used for call " + getInsertString() + " with: " + values); logger.debug("The following parameters are used for call " + getInsertString() + " with: " + values);

5
spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/DefaultJdbcClient.java

@ -240,7 +240,7 @@ final class DefaultJdbcClient implements JdbcClient {
} }
@Override @Override
@SuppressWarnings({"unchecked", "NullAway"}) // See https://github.com/uber/NullAway/issues/1075 @SuppressWarnings("unchecked")
public <T> MappedQuerySpec<@Nullable T> query(Class<T> mappedClass) { public <T> MappedQuerySpec<@Nullable T> query(Class<T> mappedClass) {
RowMapper<?> rowMapper = rowMapperCache.computeIfAbsent(mappedClass, key -> RowMapper<?> rowMapper = rowMapperCache.computeIfAbsent(mappedClass, key ->
BeanUtils.isSimpleProperty(mappedClass) ? BeanUtils.isSimpleProperty(mappedClass) ?
@ -342,7 +342,6 @@ final class DefaultJdbcClient implements JdbcClient {
} }
@Override @Override
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
public List<@Nullable Object> singleColumn() { public List<@Nullable Object> singleColumn() {
return classicOps.queryForList(sql, Object.class, indexedParams.toArray()); return classicOps.queryForList(sql, Object.class, indexedParams.toArray());
} }
@ -362,13 +361,11 @@ final class DefaultJdbcClient implements JdbcClient {
} }
@Override @Override
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
public Map<String, @Nullable Object> singleRow() { public Map<String, @Nullable Object> singleRow() {
return namedParamOps.queryForMap(sql, namedParamSource); return namedParamOps.queryForMap(sql, namedParamSource);
} }
@Override @Override
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
public List<@Nullable Object> singleColumn() { public List<@Nullable Object> singleColumn() {
return namedParamOps.queryForList(sql, namedParamSource, Object.class); return namedParamOps.queryForList(sql, namedParamSource, Object.class);
} }

2
spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/JdbcClient.java

@ -391,7 +391,6 @@ public interface JdbcClient {
* @see #optionalValue() * @see #optionalValue()
* @see DataAccessUtils#requiredSingleResult(Collection) * @see DataAccessUtils#requiredSingleResult(Collection)
*/ */
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
default Object singleValue() { default Object singleValue() {
return DataAccessUtils.requiredSingleResult(singleColumn()); return DataAccessUtils.requiredSingleResult(singleColumn());
} }
@ -403,7 +402,6 @@ public interface JdbcClient {
* @see #singleValue() * @see #singleValue()
* @see DataAccessUtils#optionalResult(Collection) * @see DataAccessUtils#optionalResult(Collection)
*/ */
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
default Optional<Object> optionalValue() { default Optional<Object> optionalValue() {
return DataAccessUtils.optionalResult(singleColumn()); return DataAccessUtils.optionalResult(singleColumn());
} }

15
spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClient.java

@ -596,7 +596,6 @@ class DefaultWebTestClient implements WebTestClient {
} }
@Override @Override
@SuppressWarnings("NullAway") // https://github.com/uber/NullAway/issues/1129
public <T extends S> T value(Consumer<@Nullable B> consumer) { public <T extends S> T value(Consumer<@Nullable B> consumer) {
this.result.assertWithDiagnostics(() -> consumer.accept(this.result.getResponseBody())); this.result.assertWithDiagnostics(() -> consumer.accept(this.result.getResponseBody()));
return self(); return self();
@ -620,7 +619,7 @@ class DefaultWebTestClient implements WebTestClient {
} }
private static class DefaultListBodySpec<E> extends DefaultBodySpec<List<@Nullable E>, ListBodySpec<E>> private static class DefaultListBodySpec<E extends @Nullable Object> extends DefaultBodySpec<List<E>, ListBodySpec<E>>
implements ListBodySpec<E> { implements ListBodySpec<E> {
DefaultListBodySpec(EntityExchangeResult<List<E>> result) { DefaultListBodySpec(EntityExchangeResult<List<E>> result) {
@ -629,7 +628,7 @@ class DefaultWebTestClient implements WebTestClient {
@Override @Override
public ListBodySpec<E> hasSize(int size) { public ListBodySpec<E> hasSize(int size) {
List<@Nullable E> actual = getResult().getResponseBody(); List<E> actual = getResult().getResponseBody();
String message = "Response body does not contain " + size + " elements"; String message = "Response body does not contain " + size + " elements";
getResult().assertWithDiagnostics(() -> getResult().assertWithDiagnostics(() ->
AssertionErrors.assertEquals(message, size, (actual != null ? actual.size() : 0))); AssertionErrors.assertEquals(message, size, (actual != null ? actual.size() : 0)));
@ -638,9 +637,9 @@ class DefaultWebTestClient implements WebTestClient {
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public ListBodySpec<E> contains(@Nullable E... elements) { public ListBodySpec<E> contains(E... elements) {
List<E> expected = Arrays.asList(elements); List<E> expected = Arrays.asList(elements);
List<@Nullable E> actual = getResult().getResponseBody(); List<E> actual = getResult().getResponseBody();
String message = "Response body does not contain " + expected; String message = "Response body does not contain " + expected;
getResult().assertWithDiagnostics(() -> getResult().assertWithDiagnostics(() ->
AssertionErrors.assertTrue(message, (actual != null && actual.containsAll(expected)))); AssertionErrors.assertTrue(message, (actual != null && actual.containsAll(expected))));
@ -649,9 +648,9 @@ class DefaultWebTestClient implements WebTestClient {
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public ListBodySpec<E> doesNotContain(@Nullable E... elements) { public ListBodySpec<E> doesNotContain(E... elements) {
List<E> expected = Arrays.asList(elements); List<E> expected = Arrays.asList(elements);
List<@Nullable E> actual = getResult().getResponseBody(); List<E> actual = getResult().getResponseBody();
String message = "Response body should not have contained " + expected; String message = "Response body should not have contained " + expected;
getResult().assertWithDiagnostics(() -> getResult().assertWithDiagnostics(() ->
AssertionErrors.assertTrue(message, (actual == null || !actual.containsAll(expected)))); AssertionErrors.assertTrue(message, (actual == null || !actual.containsAll(expected))));
@ -659,7 +658,7 @@ class DefaultWebTestClient implements WebTestClient {
} }
@Override @Override
public EntityExchangeResult<List<@Nullable E>> returnResult() { public EntityExchangeResult<List<E>> returnResult() {
return getResult(); return getResult();
} }
} }

6
spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java

@ -975,7 +975,7 @@ public interface WebTestClient {
* *
* @param <E> the body list element type * @param <E> the body list element type
*/ */
interface ListBodySpec<E> extends BodySpec<List<@Nullable E>, ListBodySpec<E>> { interface ListBodySpec<E extends @Nullable Object> extends BodySpec<List<E>, ListBodySpec<E>> {
/** /**
* Assert the extracted list of values is of the given size. * Assert the extracted list of values is of the given size.
@ -988,14 +988,14 @@ public interface WebTestClient {
* @param elements the elements to check * @param elements the elements to check
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
ListBodySpec<E> contains(@Nullable E... elements); ListBodySpec<E> contains(E... elements);
/** /**
* Assert the extracted list of values doesn't contain the given elements. * Assert the extracted list of values doesn't contain the given elements.
* @param elements the elements to check * @param elements the elements to check
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
ListBodySpec<E> doesNotContain(@Nullable E... elements); ListBodySpec<E> doesNotContain(E... elements);
} }

2
spring-test/src/main/java/org/springframework/test/web/servlet/client/DefaultRestTestClient.java

@ -367,7 +367,6 @@ class DefaultRestTestClient implements RestTestClient {
} }
@Override @Override
@SuppressWarnings("NullAway") // https://github.com/uber/NullAway/issues/1129
public <T extends S, R> T value(Function<@Nullable B, @Nullable R> bodyMapper, Matcher<? super @Nullable R> matcher) { public <T extends S, R> T value(Function<@Nullable B, @Nullable R> bodyMapper, Matcher<? super @Nullable R> matcher) {
this.result.assertWithDiagnostics(() -> { this.result.assertWithDiagnostics(() -> {
B body = this.result.getResponseBody(); B body = this.result.getResponseBody();
@ -377,7 +376,6 @@ class DefaultRestTestClient implements RestTestClient {
} }
@Override @Override
@SuppressWarnings("NullAway") // https://github.com/uber/NullAway/issues/1129
public <T extends S> T value(Consumer<@Nullable B> consumer) { public <T extends S> T value(Consumer<@Nullable B> consumer) {
this.result.assertWithDiagnostics(() -> consumer.accept(this.result.getResponseBody())); this.result.assertWithDiagnostics(() -> consumer.accept(this.result.getResponseBody()));
return self(); return self();

2
spring-tx/src/main/java/org/springframework/dao/support/DataAccessUtils.java

@ -116,7 +116,7 @@ public abstract class DataAccessUtils {
* element has been found in the given Collection * element has been found in the given Collection
* @since 6.1 * @since 6.1
*/ */
public static <T extends @Nullable Object> Optional<@NonNull T> optionalResult(@Nullable Collection<T> results) public static <T> Optional<T> optionalResult(@Nullable Collection<? extends @Nullable T> results)
throws IncorrectResultSizeDataAccessException { throws IncorrectResultSizeDataAccessException {
return Optional.ofNullable(singleResult(results)); return Optional.ofNullable(singleResult(results));

4
spring-web/src/main/java/org/springframework/web/client/DefaultRestClient.java

@ -803,13 +803,13 @@ final class DefaultRestClient implements RestClient {
} }
@Override @Override
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075 @SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1290
public <T> @Nullable T body(Class<T> bodyType) { public <T> @Nullable T body(Class<T> bodyType) {
return executeAndExtract((request, response) -> readBody(request, response, bodyType, bodyType, this.hints)); return executeAndExtract((request, response) -> readBody(request, response, bodyType, bodyType, this.hints));
} }
@Override @Override
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075 @SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1290
public <T> @Nullable T body(ParameterizedTypeReference<T> bodyType) { public <T> @Nullable T body(ParameterizedTypeReference<T> bodyType) {
Type type = bodyType.getType(); Type type = bodyType.getType();
Class<T> bodyClass = bodyClass(type); Class<T> bodyClass = bodyClass(type);

7
spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerMapping.java

@ -23,6 +23,7 @@ import java.util.Collections;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -340,14 +341,14 @@ public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMappi
* Resolve placeholder values in the given array of patterns. * Resolve placeholder values in the given array of patterns.
* @return a new array with updated patterns * @return a new array with updated patterns
*/ */
protected @Nullable String[] resolveEmbeddedValuesInPatterns(String[] patterns) { protected String[] resolveEmbeddedValuesInPatterns(String[] patterns) {
if (this.embeddedValueResolver == null) { if (this.embeddedValueResolver == null) {
return patterns; return patterns;
} }
else { else {
@Nullable String[] resolvedPatterns = new String[patterns.length]; String[] resolvedPatterns = new String[patterns.length];
for (int i = 0; i < patterns.length; i++) { for (int i = 0; i < patterns.length; i++) {
resolvedPatterns[i] = this.embeddedValueResolver.resolveStringValue(patterns[i]); resolvedPatterns[i] = Objects.requireNonNull(this.embeddedValueResolver.resolveStringValue(patterns[i]));
} }
return resolvedPatterns; return resolvedPatterns;
} }

7
spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java

@ -23,6 +23,7 @@ import java.util.Collections;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -367,14 +368,14 @@ public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMappi
* Resolve placeholder values in the given array of patterns. * Resolve placeholder values in the given array of patterns.
* @return a new array with updated patterns * @return a new array with updated patterns
*/ */
protected @Nullable String[] resolveEmbeddedValuesInPatterns(String[] patterns) { protected String[] resolveEmbeddedValuesInPatterns(String[] patterns) {
if (this.embeddedValueResolver == null) { if (this.embeddedValueResolver == null) {
return patterns; return patterns;
} }
else { else {
@Nullable String[] resolvedPatterns = new String[patterns.length]; String[] resolvedPatterns = new String[patterns.length];
for (int i = 0; i < patterns.length; i++) { for (int i = 0; i < patterns.length; i++) {
resolvedPatterns[i] = this.embeddedValueResolver.resolveStringValue(patterns[i]); resolvedPatterns[i] = Objects.requireNonNull(this.embeddedValueResolver.resolveStringValue(patterns[i]));
} }
return resolvedPatterns; return resolvedPatterns;
} }

Loading…
Cancel
Save