Perform NullAway build-time checks in more modules

This commit enables null-safety build-time checks in:
 - spring-jdbc
 - spring-r2dbc
 - spring-orm
 - spring-beans
 - spring-aop

See gh-32475
This commit is contained in:
Sébastien Deleuze 2024-03-26 09:55:41 +01:00
parent 3b4f8dbb8e
commit 5b660da52d
46 changed files with 78 additions and 12 deletions

View File

@ -118,10 +118,11 @@ tasks.withType(JavaCompile).configureEach {
disableAllChecks = true
option("NullAway:CustomContractAnnotations", "org.springframework.lang.Contract")
option("NullAway:AnnotatedPackages", "org.springframework.core,org.springframework.expression," +
"org.springframework.web,org.springframework.jms,org.springframework.messaging")
"org.springframework.web,org.springframework.jms,org.springframework.messaging,org.springframework.jdbc," +
"org.springframework.r2dbc,org.springframework.orm,org.springframework.beans,org.springframework.aop")
option("NullAway:UnannotatedSubPackages", "org.springframework.instrument,org.springframework.context.index," +
"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,org.springframework.aot.nativex.feature")
}
}
tasks.compileJava {

View File

@ -552,6 +552,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
* @param ex the exception thrown by the method execution (may be null)
* @return the empty array if there are no arguments
*/
@SuppressWarnings("NullAway")
protected Object[] argBinding(JoinPoint jp, @Nullable JoinPointMatch jpMatch,
@Nullable Object returnValue, @Nullable Throwable ex) {

View File

@ -77,7 +77,7 @@ public class BeanFactoryAspectInstanceFactory implements MetadataAwareAspectInst
this.beanFactory = beanFactory;
this.name = name;
Class<?> resolvedType = type;
if (type == null) {
if (resolvedType == null) {
resolvedType = beanFactory.getType(name);
Assert.notNull(resolvedType, "Unresolvable bean type - explicitly specify the aspect class");
}

View File

@ -80,6 +80,7 @@ public class BeanFactoryAspectJAdvisorsBuilder {
* @return the list of {@link org.springframework.aop.Advisor} beans
* @see #isEligibleBean
*/
@SuppressWarnings("NullAway")
public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = this.aspectBeanNames;

View File

@ -195,6 +195,7 @@ final class InstantiationModelAwarePointcutAdvisorImpl
}
@Override
@SuppressWarnings("NullAway")
public boolean isBeforeAdvice() {
if (this.isBeforeAdvice == null) {
determineAdviceType();
@ -203,6 +204,7 @@ final class InstantiationModelAwarePointcutAdvisorImpl
}
@Override
@SuppressWarnings("NullAway")
public boolean isAfterAdvice() {
if (this.isAfterAdvice == null) {
determineAdviceType();

View File

@ -98,6 +98,7 @@ public class AsyncExecutionInterceptor extends AsyncExecutionAspectSupport imple
*/
@Override
@Nullable
@SuppressWarnings("NullAway")
public Object invoke(final MethodInvocation invocation) throws Throwable {
Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
final Method userMethod = BridgeMethodResolver.getMostSpecificMethod(invocation.getMethod(), targetClass);

View File

@ -54,6 +54,7 @@ class ScopedProxyBeanRegistrationAotProcessor implements BeanRegistrationAotProc
@Override
@Nullable
@SuppressWarnings("NullAway")
public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) {
Class<?> beanClass = registeredBean.getBeanClass();
if (beanClass.equals(ScopedProxyFactoryBean.class)) {

View File

@ -22,6 +22,7 @@ import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.lang.Contract;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
@ -128,6 +129,7 @@ public abstract class ScopedProxyUtils {
* the target bean within a scoped proxy.
* @since 4.1.4
*/
@Contract("null -> false")
public static boolean isScopedTarget(@Nullable String beanName) {
return (beanName != null && beanName.startsWith(TARGET_NAME_PREFIX));
}

View File

@ -43,6 +43,7 @@ import org.springframework.core.BridgeMethodResolver;
import org.springframework.core.CoroutinesUtils;
import org.springframework.core.KotlinDetector;
import org.springframework.core.MethodIntrospector;
import org.springframework.lang.Contract;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
@ -73,6 +74,7 @@ public abstract class AopUtils {
* @see #isJdkDynamicProxy
* @see #isCglibProxy
*/
@Contract("null -> false")
public static boolean isAopProxy(@Nullable Object object) {
return (object instanceof SpringProxy && (Proxy.isProxyClass(object.getClass()) ||
object.getClass().getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)));
@ -86,6 +88,7 @@ public abstract class AopUtils {
* @param object the object to check
* @see java.lang.reflect.Proxy#isProxyClass
*/
@Contract("null -> false")
public static boolean isJdkDynamicProxy(@Nullable Object object) {
return (object instanceof SpringProxy && Proxy.isProxyClass(object.getClass()));
}
@ -98,6 +101,7 @@ public abstract class AopUtils {
* @param object the object to check
* @see ClassUtils#isCglibProxy(Object)
*/
@Contract("null -> false")
public static boolean isCglibProxy(@Nullable Object object) {
return (object instanceof SpringProxy &&
object.getClass().getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR));

View File

@ -87,6 +87,7 @@ public class AnnotationMatchingPointcut implements Pointcut {
* @see AnnotationClassFilter#AnnotationClassFilter(Class, boolean)
* @see AnnotationMethodMatcher#AnnotationMethodMatcher(Class, boolean)
*/
@SuppressWarnings("NullAway")
public AnnotationMatchingPointcut(@Nullable Class<? extends Annotation> classAnnotationType,
@Nullable Class<? extends Annotation> methodAnnotationType, boolean checkInherited) {

View File

@ -66,6 +66,7 @@ public abstract class AbstractRefreshableTargetSource implements TargetSource, R
@Override
@SuppressWarnings("NullAway")
public synchronized Class<?> getTargetClass() {
if (this.targetObject == null) {
refresh();

View File

@ -106,9 +106,9 @@ final class GenericTypeAwarePropertyDescriptor extends PropertyDescriptor {
// by the JDK's JavaBeans Introspector...
Set<Method> ambiguousCandidates = new HashSet<>();
for (Method method : beanClass.getMethods()) {
if (method.getName().equals(writeMethodToUse.getName()) &&
!method.equals(writeMethodToUse) && !method.isBridge() &&
method.getParameterCount() == writeMethodToUse.getParameterCount()) {
if (method.getName().equals(this.writeMethod.getName()) &&
!method.equals(this.writeMethod) && !method.isBridge() &&
method.getParameterCount() == this.writeMethod.getParameterCount()) {
ambiguousCandidates.add(method);
}
}

View File

@ -179,6 +179,7 @@ public class PropertyEditorRegistrySupport implements PropertyEditorRegistry {
* @see #registerDefaultEditors
*/
@Nullable
@SuppressWarnings("NullAway")
public PropertyEditor getDefaultEditor(Class<?> requiredType) {
if (!this.defaultEditorsActive) {
return null;

View File

@ -28,6 +28,7 @@ import java.util.Set;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.lang.Contract;
import org.springframework.lang.Nullable;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ReflectionUtils;
@ -182,6 +183,7 @@ public class InjectionMetadata {
* @return {@code true} indicating a refresh, {@code false} otherwise
* @see #needsRefresh(Class)
*/
@Contract("null, _ -> true")
public static boolean needsRefresh(@Nullable InjectionMetadata metadata, Class<?> clazz) {
return (metadata == null || metadata.needsRefresh(clazz));
}

View File

@ -413,9 +413,9 @@ public class DependencyDescriptor extends InjectionPoint implements Serializable
if (!super.equals(other)) {
return false;
}
DependencyDescriptor otherDesc = (DependencyDescriptor) other;
return (this.required == otherDesc.required && this.eager == otherDesc.eager &&
this.nestingLevel == otherDesc.nestingLevel && this.containingClass == otherDesc.containingClass);
return (other instanceof DependencyDescriptor otherDesc && this.required == otherDesc.required &&
this.eager == otherDesc.eager && this.nestingLevel == otherDesc.nestingLevel &&
this.containingClass == otherDesc.containingClass);
}
@Override

View File

@ -167,6 +167,7 @@ public class FieldRetrievingFactoryBean
@Override
@SuppressWarnings("NullAway")
public void afterPropertiesSet() throws ClassNotFoundException, NoSuchFieldException {
if (this.targetClass != null && this.targetObject != null) {
throw new IllegalArgumentException("Specify either targetClass or targetObject, not both");

View File

@ -228,7 +228,7 @@ public abstract class PlaceholderConfigurerSupport extends PropertyResourceConfi
this.beanFactory = beanFactory;
}
@SuppressWarnings("NullAway")
protected void doProcessProperties(ConfigurableListableBeanFactory beanFactoryToProcess,
StringValueResolver valueResolver) {

View File

@ -162,6 +162,7 @@ public class PropertyPathFactoryBean implements FactoryBean<Object>, BeanNameAwa
@Override
@SuppressWarnings("NullAway")
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;

View File

@ -701,6 +701,7 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
}
}
@SuppressWarnings("NullAway")
private GroovyDynamicElementReader createDynamicElementReader(String namespace) {
XmlReaderContext readerContext = this.groovyDslXmlBeanDefinitionReader.createReaderContext(
new DescriptiveResource("Groovy"));

View File

@ -130,6 +130,7 @@ class ConstructorResolver {
* or {@code null} if none (-> use constructor argument values from bean definition)
* @return a BeanWrapper for the new instance
*/
@SuppressWarnings("NullAway")
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
@ -391,6 +392,7 @@ class ConstructorResolver {
* method, or {@code null} if none (-> use constructor argument values from bean definition)
* @return a BeanWrapper for the new instance
*/
@SuppressWarnings("NullAway")
public BeanWrapper instantiateUsingFactoryMethod(
String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {

View File

@ -81,6 +81,7 @@ import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
import org.springframework.core.log.LogMessage;
import org.springframework.core.metrics.StartupStep;
import org.springframework.lang.Contract;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
@ -1487,6 +1488,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
}
@Nullable
@SuppressWarnings("NullAway")
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
@ -2066,6 +2068,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
* i.e. whether the candidate points back to the original bean or to a factory method
* on the original bean.
*/
@Contract("null, _ -> false;_, null -> false;")
private boolean isSelfReference(@Nullable String beanName, @Nullable String candidateName) {
return (beanName != null && candidateName != null &&
(beanName.equals(candidateName) || (containsBeanDefinition(candidateName) &&

View File

@ -238,6 +238,7 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
* with, if necessary
* @return the registered singleton object
*/
@SuppressWarnings("NullAway")
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");

View File

@ -73,6 +73,7 @@ public class GenericTypeAwareAutowireCandidateResolver extends SimpleAutowireCan
* Match the given dependency type with its generic type information against the given
* candidate bean definition.
*/
@SuppressWarnings("NullAway")
protected boolean checkGenericTypeMatch(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
ResolvableType dependencyType = descriptor.getResolvableType();
if (dependencyType.getType() instanceof Class) {

View File

@ -411,6 +411,7 @@ public class BeanDefinitionParserDelegate {
* {@link org.springframework.beans.factory.parsing.ProblemReporter}.
*/
@Nullable
@SuppressWarnings("NullAway")
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
String id = ele.getAttribute(ID_ATTRIBUTE);
String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);

View File

@ -187,6 +187,7 @@ enum InstrumentedMethod {
/**
* {@link Class#getField(String)}.
*/
@SuppressWarnings("NullAway")
CLASS_GETFIELD(Class.class, "getField", HintType.REFLECTION,
invocation -> {
Field field = invocation.getReturnValue();

View File

@ -46,6 +46,7 @@ public class ArgumentTypePreparedStatementSetter implements PreparedStatementSet
* @param args the arguments to set
* @param argTypes the corresponding SQL types of the arguments
*/
@SuppressWarnings("NullAway")
public ArgumentTypePreparedStatementSetter(@Nullable Object[] args, @Nullable int[] argTypes) {
if ((args != null && argTypes == null) || (args == null && argTypes != null) ||
(args != null && args.length != argTypes.length)) {

View File

@ -26,6 +26,7 @@ import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.lang.Nullable;
/**
* A SimpleJdbcCall is a multithreaded, reusable object representing a call
@ -148,36 +149,42 @@ public class SimpleJdbcCall extends AbstractJdbcCall implements SimpleJdbcCallOp
}
@Override
@Nullable
@SuppressWarnings("unchecked")
public <T> T executeFunction(Class<T> returnType, Object... args) {
return (T) doExecute(args).get(getScalarOutParameterName());
}
@Override
@Nullable
@SuppressWarnings("unchecked")
public <T> T executeFunction(Class<T> returnType, Map<String, ?> args) {
return (T) doExecute(args).get(getScalarOutParameterName());
}
@Override
@Nullable
@SuppressWarnings("unchecked")
public <T> T executeFunction(Class<T> returnType, SqlParameterSource args) {
return (T) doExecute(args).get(getScalarOutParameterName());
}
@Override
@Nullable
@SuppressWarnings("unchecked")
public <T> T executeObject(Class<T> returnType, Object... args) {
return (T) doExecute(args).get(getScalarOutParameterName());
}
@Override
@Nullable
@SuppressWarnings("unchecked")
public <T> T executeObject(Class<T> returnType, Map<String, ?> args) {
return (T) doExecute(args).get(getScalarOutParameterName());
}
@Override
@Nullable
@SuppressWarnings("unchecked")
public <T> T executeObject(Class<T> returnType, SqlParameterSource args) {
return (T) doExecute(args).get(getScalarOutParameterName());

View File

@ -21,6 +21,7 @@ import java.util.Map;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.lang.Nullable;
/**
* Interface specifying the API for a Simple JDBC Call implemented by {@link SimpleJdbcCall}.
@ -117,6 +118,7 @@ public interface SimpleJdbcCallOperations {
* Parameter values must be provided in the same order as the parameters are defined
* for the stored procedure.
*/
@Nullable
<T> T executeFunction(Class<T> returnType, Object... args);
/**
@ -125,6 +127,7 @@ public interface SimpleJdbcCallOperations {
* @param returnType the type of the value to return
* @param args a Map containing the parameter values to be used in the call
*/
@Nullable
<T> T executeFunction(Class<T> returnType, Map<String, ?> args);
/**
@ -133,6 +136,7 @@ public interface SimpleJdbcCallOperations {
* @param returnType the type of the value to return
* @param args the MapSqlParameterSource containing the parameter values to be used in the call
*/
@Nullable
<T> T executeFunction(Class<T> returnType, SqlParameterSource args);
/**
@ -144,6 +148,7 @@ public interface SimpleJdbcCallOperations {
* Parameter values must be provided in the same order as the parameters are defined for
* the stored procedure.
*/
@Nullable
<T> T executeObject(Class<T> returnType, Object... args);
/**
@ -153,6 +158,7 @@ public interface SimpleJdbcCallOperations {
* @param returnType the type of the value to return
* @param args a Map containing the parameter values to be used in the call
*/
@Nullable
<T> T executeObject(Class<T> returnType, Map<String, ?> args);
/**
@ -162,6 +168,7 @@ public interface SimpleJdbcCallOperations {
* @param returnType the type of the value to return
* @param args the MapSqlParameterSource containing the parameter values to be used in the call
*/
@Nullable
<T> T executeObject(Class<T> returnType, SqlParameterSource args);
/**

View File

@ -182,6 +182,7 @@ public class SingleConnectionDataSource extends DriverManagerDataSource
@Override
@SuppressWarnings("NullAway")
public Connection getConnection() throws SQLException {
this.connectionLock.lock();
try {

View File

@ -162,6 +162,7 @@ public class EmbeddedDatabaseFactory {
* Factory method that returns the {@linkplain EmbeddedDatabase embedded database}
* instance, which is also a {@link DataSource}.
*/
@SuppressWarnings("NullAway")
public EmbeddedDatabase getDatabase() {
if (this.dataSource == null) {
initDatabase();

View File

@ -134,6 +134,7 @@ public abstract class AbstractRoutingDataSource extends AbstractDataSource imple
* @see #getResolvedDataSources()
* @see #getResolvedDefaultDataSource()
*/
@SuppressWarnings("NullAway")
public void initialize() {
if (this.targetDataSources == null) {
throw new IllegalArgumentException("Property 'targetDataSources' is required");

View File

@ -43,6 +43,7 @@ public abstract class AbstractColumnMaxValueIncrementer extends AbstractDataFiel
* @see #setIncrementerName
* @see #setColumnName
*/
@SuppressWarnings("NullAway")
public AbstractColumnMaxValueIncrementer() {
}

View File

@ -77,6 +77,7 @@ public abstract class AbstractDataFieldMaxValueIncrementer implements DataFieldM
/**
* Return the data source to retrieve the value from.
*/
@SuppressWarnings("NullAway")
public DataSource getDataSource() {
return this.dataSource;
}
@ -91,6 +92,7 @@ public abstract class AbstractDataFieldMaxValueIncrementer implements DataFieldM
/**
* Return the name of the sequence/table.
*/
@SuppressWarnings("NullAway")
public String getIncrementerName() {
return this.incrementerName;
}

View File

@ -53,9 +53,11 @@ public abstract class AbstractIdentityColumnMaxValueIncrementer extends Abstract
* @see #setIncrementerName
* @see #setColumnName
*/
@SuppressWarnings("NullAway")
public AbstractIdentityColumnMaxValueIncrementer() {
}
@SuppressWarnings("NullAway")
public AbstractIdentityColumnMaxValueIncrementer(DataSource dataSource, String incrementerName, String columnName) {
super(dataSource, incrementerName, columnName);
}

View File

@ -42,6 +42,7 @@ public class HibernateJdbcException extends UncategorizedDataAccessException {
/**
* Return the underlying SQLException.
*/
@SuppressWarnings("NullAway")
public SQLException getSQLException() {
return ((JDBCException) getCause()).getSQLException();
}
@ -50,6 +51,7 @@ public class HibernateJdbcException extends UncategorizedDataAccessException {
* Return the SQL that led to the problem.
*/
@Nullable
@SuppressWarnings("NullAway")
public String getSql() {
return ((JDBCException) getCause()).getSQL();
}

View File

@ -40,6 +40,7 @@ public class HibernateQueryException extends InvalidDataAccessResourceUsageExcep
* Return the HQL query string that was invalid.
*/
@Nullable
@SuppressWarnings("NullAway")
public String getQueryString() {
return ((QueryException) getCause()).getQueryString();
}

View File

@ -947,6 +947,7 @@ public class HibernateTemplate implements HibernateOperations, InitializingBean
@Deprecated
@Override
@SuppressWarnings("NullAway")
public List<?> findByNamedQueryAndNamedParam(
String queryName, @Nullable String[] paramNames, @Nullable Object[] values)
throws DataAccessException {

View File

@ -427,7 +427,7 @@ public abstract class AbstractEntityManagerFactoryBean implements
if (cause != null) {
String message = ex.getMessage();
String causeString = cause.toString();
if (!message.endsWith(causeString)) {
if (message != null && !message.endsWith(causeString)) {
ex = new PersistenceException(message + "; nested exception is " + causeString, cause);
}
}

View File

@ -349,7 +349,7 @@ public class LocalContainerEntityManagerFactoryBean extends AbstractEntityManage
@Override
public void afterPropertiesSet() throws PersistenceException {
PersistenceUnitManager managerToUse = this.persistenceUnitManager;
if (this.persistenceUnitManager == null) {
if (managerToUse == null) {
this.internalPersistenceUnitManager.afterPropertiesSet();
managerToUse = this.internalPersistenceUnitManager;
}

View File

@ -452,6 +452,7 @@ public class DefaultPersistenceUnitManager
* @see #obtainDefaultPersistenceUnitInfo()
* @see #obtainPersistenceUnitInfo(String)
*/
@SuppressWarnings("NullAway")
public void preparePersistenceUnitInfos() {
this.persistenceUnitInfoNames.clear();
this.persistenceUnitInfos.clear();

View File

@ -359,6 +359,7 @@ public class PersistenceAnnotationBeanPostProcessor implements InstantiationAwar
}
@Override
@Nullable
public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) {
Class<?> beanClass = registeredBean.getBeanClass();
String beanName = registeredBean.getBeanName();
@ -857,6 +858,7 @@ public class PersistenceAnnotationBeanPostProcessor implements InstantiationAwar
return CodeBlock.of("$L($L)", generatedMethod.getName(), REGISTERED_BEAN_PARAMETER);
}
@SuppressWarnings("NullAway")
private void generateGetEntityManagerMethod(MethodSpec.Builder method, PersistenceElement injectedElement) {
String unitName = injectedElement.unitName;
Properties properties = injectedElement.properties;

View File

@ -36,6 +36,7 @@ import org.hibernate.property.access.spi.PropertyAccess;
final class Target_BytecodeProvider {
@Substitute
@SuppressWarnings("NullAway")
public ReflectionOptimizer getReflectionOptimizer(Class<?> clazz, Map<String, PropertyAccess> propertyAccessMap) {
return null;
}

View File

@ -36,6 +36,7 @@ import org.hibernate.bytecode.spi.BytecodeProvider;
final class Target_BytecodeProviderInitiator {
@Alias
@SuppressWarnings("NullAway")
public static String BYTECODE_PROVIDER_NAME_NONE;
@Alias

View File

@ -142,6 +142,7 @@ public abstract class AbstractRoutingConnectionFactory implements ConnectionFact
* @see #setTargetConnectionFactories(Map)
* @see #setDefaultTargetConnectionFactory(Object)
*/
@SuppressWarnings("NullAway")
public void initialize() {
Assert.notNull(this.targetConnectionFactories, "Property 'targetConnectionFactories' must not be null");
@ -220,6 +221,7 @@ public abstract class AbstractRoutingConnectionFactory implements ConnectionFact
* per {@link #determineCurrentLookupKey()}
* @see #determineCurrentLookupKey()
*/
@SuppressWarnings("NullAway")
protected Mono<ConnectionFactory> determineTargetConnectionFactory() {
Assert.state(this.resolvedConnectionFactories != null, "ConnectionFactory router not initialized");

View File

@ -383,6 +383,7 @@ final class DefaultDatabaseClient implements DatabaseClient {
return fetch().rowsUpdated().then();
}
@SuppressWarnings("NullAway")
private ResultFunction getResultFunction(Supplier<String> sqlSupplier) {
BiFunction<Connection, String, Statement> statementFunction = (connection, sql) -> {
if (logger.isDebugEnabled()) {

View File

@ -75,6 +75,7 @@ class MapBindParameterSource implements BindParameterSource {
}
@Override
@SuppressWarnings("NullAway")
public Parameter getValue(String paramName) throws IllegalArgumentException {
if (!hasValue(paramName)) {
throw new IllegalArgumentException("No value registered for key '" + paramName + "'");