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 { @@ -119,3 +119,6 @@ publishing {
components.java.withVariantsFromConfiguration(configurations.testFixturesApiElements) { 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; @@ -39,7 +39,7 @@ import org.springframework.util.Assert;
* @since 5.1
* @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;

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

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

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

@ -21,8 +21,6 @@ import java.sql.SQLException; @@ -21,8 +21,6 @@ import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
/**
@ -61,7 +59,7 @@ import org.springframework.util.Assert; @@ -61,7 +59,7 @@ import org.springframework.util.Assert;
* @see JdbcTemplate
* @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;

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

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

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

@ -448,7 +448,6 @@ public abstract class AbstractJdbcInsert { @@ -448,7 +448,6 @@ public abstract class AbstractJdbcInsert {
/**
* 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) {
if (logger.isDebugEnabled()) {
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 { @@ -240,7 +240,7 @@ final class DefaultJdbcClient implements JdbcClient {
}
@Override
@SuppressWarnings({"unchecked", "NullAway"}) // See https://github.com/uber/NullAway/issues/1075
@SuppressWarnings("unchecked")
public <T> MappedQuerySpec<@Nullable T> query(Class<T> mappedClass) {
RowMapper<?> rowMapper = rowMapperCache.computeIfAbsent(mappedClass, key ->
BeanUtils.isSimpleProperty(mappedClass) ?
@ -342,7 +342,6 @@ final class DefaultJdbcClient implements JdbcClient { @@ -342,7 +342,6 @@ final class DefaultJdbcClient implements JdbcClient {
}
@Override
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
public List<@Nullable Object> singleColumn() {
return classicOps.queryForList(sql, Object.class, indexedParams.toArray());
}
@ -362,13 +361,11 @@ final class DefaultJdbcClient implements JdbcClient { @@ -362,13 +361,11 @@ final class DefaultJdbcClient implements JdbcClient {
}
@Override
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
public Map<String, @Nullable Object> singleRow() {
return namedParamOps.queryForMap(sql, namedParamSource);
}
@Override
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
public List<@Nullable Object> singleColumn() {
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 { @@ -391,7 +391,6 @@ public interface JdbcClient {
* @see #optionalValue()
* @see DataAccessUtils#requiredSingleResult(Collection)
*/
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
default Object singleValue() {
return DataAccessUtils.requiredSingleResult(singleColumn());
}
@ -403,7 +402,6 @@ public interface JdbcClient { @@ -403,7 +402,6 @@ public interface JdbcClient {
* @see #singleValue()
* @see DataAccessUtils#optionalResult(Collection)
*/
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
default Optional<Object> optionalValue() {
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 { @@ -596,7 +596,6 @@ class DefaultWebTestClient implements WebTestClient {
}
@Override
@SuppressWarnings("NullAway") // https://github.com/uber/NullAway/issues/1129
public <T extends S> T value(Consumer<@Nullable B> consumer) {
this.result.assertWithDiagnostics(() -> consumer.accept(this.result.getResponseBody()));
return self();
@ -620,7 +619,7 @@ class DefaultWebTestClient implements WebTestClient { @@ -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> {
DefaultListBodySpec(EntityExchangeResult<List<E>> result) {
@ -629,7 +628,7 @@ class DefaultWebTestClient implements WebTestClient { @@ -629,7 +628,7 @@ class DefaultWebTestClient implements WebTestClient {
@Override
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";
getResult().assertWithDiagnostics(() ->
AssertionErrors.assertEquals(message, size, (actual != null ? actual.size() : 0)));
@ -638,9 +637,9 @@ class DefaultWebTestClient implements WebTestClient { @@ -638,9 +637,9 @@ class DefaultWebTestClient implements WebTestClient {
@Override
@SuppressWarnings("unchecked")
public ListBodySpec<E> contains(@Nullable E... elements) {
public ListBodySpec<E> contains(E... 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;
getResult().assertWithDiagnostics(() ->
AssertionErrors.assertTrue(message, (actual != null && actual.containsAll(expected))));
@ -649,9 +648,9 @@ class DefaultWebTestClient implements WebTestClient { @@ -649,9 +648,9 @@ class DefaultWebTestClient implements WebTestClient {
@Override
@SuppressWarnings("unchecked")
public ListBodySpec<E> doesNotContain(@Nullable E... elements) {
public ListBodySpec<E> doesNotContain(E... 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;
getResult().assertWithDiagnostics(() ->
AssertionErrors.assertTrue(message, (actual == null || !actual.containsAll(expected))));
@ -659,7 +658,7 @@ class DefaultWebTestClient implements WebTestClient { @@ -659,7 +658,7 @@ class DefaultWebTestClient implements WebTestClient {
}
@Override
public EntityExchangeResult<List<@Nullable E>> returnResult() {
public EntityExchangeResult<List<E>> returnResult() {
return getResult();
}
}

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

@ -975,7 +975,7 @@ public interface WebTestClient { @@ -975,7 +975,7 @@ public interface WebTestClient {
*
* @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.
@ -988,14 +988,14 @@ public interface WebTestClient { @@ -988,14 +988,14 @@ public interface WebTestClient {
* @param elements the elements to check
*/
@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.
* @param elements the elements to check
*/
@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 { @@ -367,7 +367,6 @@ class DefaultRestTestClient implements RestTestClient {
}
@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) {
this.result.assertWithDiagnostics(() -> {
B body = this.result.getResponseBody();
@ -377,7 +376,6 @@ class DefaultRestTestClient implements RestTestClient { @@ -377,7 +376,6 @@ class DefaultRestTestClient implements RestTestClient {
}
@Override
@SuppressWarnings("NullAway") // https://github.com/uber/NullAway/issues/1129
public <T extends S> T value(Consumer<@Nullable B> consumer) {
this.result.assertWithDiagnostics(() -> consumer.accept(this.result.getResponseBody()));
return self();

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

@ -116,7 +116,7 @@ public abstract class DataAccessUtils { @@ -116,7 +116,7 @@ public abstract class DataAccessUtils {
* element has been found in the given Collection
* @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 {
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 { @@ -803,13 +803,13 @@ final class DefaultRestClient implements RestClient {
}
@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) {
return executeAndExtract((request, response) -> readBody(request, response, bodyType, bodyType, this.hints));
}
@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) {
Type type = bodyType.getType();
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; @@ -23,6 +23,7 @@ import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Predicate;
import java.util.stream.Stream;
@ -340,14 +341,14 @@ public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMappi @@ -340,14 +341,14 @@ public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMappi
* Resolve placeholder values in the given array of patterns.
* @return a new array with updated patterns
*/
protected @Nullable String[] resolveEmbeddedValuesInPatterns(String[] patterns) {
protected String[] resolveEmbeddedValuesInPatterns(String[] patterns) {
if (this.embeddedValueResolver == null) {
return patterns;
}
else {
@Nullable String[] resolvedPatterns = new String[patterns.length];
String[] resolvedPatterns = new String[patterns.length];
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;
}

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

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

Loading…
Cancel
Save