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 disableAllChecks = true
option("NullAway:CustomContractAnnotations", "org.springframework.lang.Contract") option("NullAway:CustomContractAnnotations", "org.springframework.lang.Contract")
option("NullAway:AnnotatedPackages", "org.springframework.core,org.springframework.expression," + 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," + option("NullAway:UnannotatedSubPackages", "org.springframework.instrument,org.springframework.context.index," +
"org.springframework.asm,org.springframework.cglib,org.springframework.objenesis," + "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 { 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) * @param ex the exception thrown by the method execution (may be null)
* @return the empty array if there are no arguments * @return the empty array if there are no arguments
*/ */
@SuppressWarnings("NullAway")
protected Object[] argBinding(JoinPoint jp, @Nullable JoinPointMatch jpMatch, protected Object[] argBinding(JoinPoint jp, @Nullable JoinPointMatch jpMatch,
@Nullable Object returnValue, @Nullable Throwable ex) { @Nullable Object returnValue, @Nullable Throwable ex) {

View File

@ -77,7 +77,7 @@ public class BeanFactoryAspectInstanceFactory implements MetadataAwareAspectInst
this.beanFactory = beanFactory; this.beanFactory = beanFactory;
this.name = name; this.name = name;
Class<?> resolvedType = type; Class<?> resolvedType = type;
if (type == null) { if (resolvedType == null) {
resolvedType = beanFactory.getType(name); resolvedType = beanFactory.getType(name);
Assert.notNull(resolvedType, "Unresolvable bean type - explicitly specify the aspect class"); 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 * @return the list of {@link org.springframework.aop.Advisor} beans
* @see #isEligibleBean * @see #isEligibleBean
*/ */
@SuppressWarnings("NullAway")
public List<Advisor> buildAspectJAdvisors() { public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = this.aspectBeanNames; List<String> aspectNames = this.aspectBeanNames;

View File

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

View File

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

View File

@ -54,6 +54,7 @@ class ScopedProxyBeanRegistrationAotProcessor implements BeanRegistrationAotProc
@Override @Override
@Nullable @Nullable
@SuppressWarnings("NullAway")
public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) { public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) {
Class<?> beanClass = registeredBean.getBeanClass(); Class<?> beanClass = registeredBean.getBeanClass();
if (beanClass.equals(ScopedProxyFactoryBean.class)) { 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.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.lang.Contract;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -128,6 +129,7 @@ public abstract class ScopedProxyUtils {
* the target bean within a scoped proxy. * the target bean within a scoped proxy.
* @since 4.1.4 * @since 4.1.4
*/ */
@Contract("null -> false")
public static boolean isScopedTarget(@Nullable String beanName) { public static boolean isScopedTarget(@Nullable String beanName) {
return (beanName != null && beanName.startsWith(TARGET_NAME_PREFIX)); 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.CoroutinesUtils;
import org.springframework.core.KotlinDetector; import org.springframework.core.KotlinDetector;
import org.springframework.core.MethodIntrospector; import org.springframework.core.MethodIntrospector;
import org.springframework.lang.Contract;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
@ -73,6 +74,7 @@ public abstract class AopUtils {
* @see #isJdkDynamicProxy * @see #isJdkDynamicProxy
* @see #isCglibProxy * @see #isCglibProxy
*/ */
@Contract("null -> false")
public static boolean isAopProxy(@Nullable Object object) { public static boolean isAopProxy(@Nullable Object object) {
return (object instanceof SpringProxy && (Proxy.isProxyClass(object.getClass()) || return (object instanceof SpringProxy && (Proxy.isProxyClass(object.getClass()) ||
object.getClass().getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR))); object.getClass().getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)));
@ -86,6 +88,7 @@ public abstract class AopUtils {
* @param object the object to check * @param object the object to check
* @see java.lang.reflect.Proxy#isProxyClass * @see java.lang.reflect.Proxy#isProxyClass
*/ */
@Contract("null -> false")
public static boolean isJdkDynamicProxy(@Nullable Object object) { public static boolean isJdkDynamicProxy(@Nullable Object object) {
return (object instanceof SpringProxy && Proxy.isProxyClass(object.getClass())); return (object instanceof SpringProxy && Proxy.isProxyClass(object.getClass()));
} }
@ -98,6 +101,7 @@ public abstract class AopUtils {
* @param object the object to check * @param object the object to check
* @see ClassUtils#isCglibProxy(Object) * @see ClassUtils#isCglibProxy(Object)
*/ */
@Contract("null -> false")
public static boolean isCglibProxy(@Nullable Object object) { public static boolean isCglibProxy(@Nullable Object object) {
return (object instanceof SpringProxy && return (object instanceof SpringProxy &&
object.getClass().getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)); 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 AnnotationClassFilter#AnnotationClassFilter(Class, boolean)
* @see AnnotationMethodMatcher#AnnotationMethodMatcher(Class, boolean) * @see AnnotationMethodMatcher#AnnotationMethodMatcher(Class, boolean)
*/ */
@SuppressWarnings("NullAway")
public AnnotationMatchingPointcut(@Nullable Class<? extends Annotation> classAnnotationType, public AnnotationMatchingPointcut(@Nullable Class<? extends Annotation> classAnnotationType,
@Nullable Class<? extends Annotation> methodAnnotationType, boolean checkInherited) { @Nullable Class<? extends Annotation> methodAnnotationType, boolean checkInherited) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -167,6 +167,7 @@ public class FieldRetrievingFactoryBean
@Override @Override
@SuppressWarnings("NullAway")
public void afterPropertiesSet() throws ClassNotFoundException, NoSuchFieldException { public void afterPropertiesSet() throws ClassNotFoundException, NoSuchFieldException {
if (this.targetClass != null && this.targetObject != null) { if (this.targetClass != null && this.targetObject != null) {
throw new IllegalArgumentException("Specify either targetClass or targetObject, not both"); 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; this.beanFactory = beanFactory;
} }
@SuppressWarnings("NullAway")
protected void doProcessProperties(ConfigurableListableBeanFactory beanFactoryToProcess, protected void doProcessProperties(ConfigurableListableBeanFactory beanFactoryToProcess,
StringValueResolver valueResolver) { StringValueResolver valueResolver) {

View File

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

View File

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

View File

@ -130,6 +130,7 @@ class ConstructorResolver {
* or {@code null} if none (-> use constructor argument values from bean definition) * or {@code null} if none (-> use constructor argument values from bean definition)
* @return a BeanWrapper for the new instance * @return a BeanWrapper for the new instance
*/ */
@SuppressWarnings("NullAway")
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd, public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) { @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) * method, or {@code null} if none (-> use constructor argument values from bean definition)
* @return a BeanWrapper for the new instance * @return a BeanWrapper for the new instance
*/ */
@SuppressWarnings("NullAway")
public BeanWrapper instantiateUsingFactoryMethod( public BeanWrapper instantiateUsingFactoryMethod(
String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) { 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.annotation.MergedAnnotations.SearchStrategy;
import org.springframework.core.log.LogMessage; import org.springframework.core.log.LogMessage;
import org.springframework.core.metrics.StartupStep; import org.springframework.core.metrics.StartupStep;
import org.springframework.lang.Contract;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
@ -1487,6 +1488,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
} }
@Nullable @Nullable
@SuppressWarnings("NullAway")
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName, public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException { @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 * i.e. whether the candidate points back to the original bean or to a factory method
* on the original bean. * on the original bean.
*/ */
@Contract("null, _ -> false;_, null -> false;")
private boolean isSelfReference(@Nullable String beanName, @Nullable String candidateName) { private boolean isSelfReference(@Nullable String beanName, @Nullable String candidateName) {
return (beanName != null && candidateName != null && return (beanName != null && candidateName != null &&
(beanName.equals(candidateName) || (containsBeanDefinition(candidateName) && (beanName.equals(candidateName) || (containsBeanDefinition(candidateName) &&

View File

@ -238,6 +238,7 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
* with, if necessary * with, if necessary
* @return the registered singleton object * @return the registered singleton object
*/ */
@SuppressWarnings("NullAway")
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null"); 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 * Match the given dependency type with its generic type information against the given
* candidate bean definition. * candidate bean definition.
*/ */
@SuppressWarnings("NullAway")
protected boolean checkGenericTypeMatch(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) { protected boolean checkGenericTypeMatch(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
ResolvableType dependencyType = descriptor.getResolvableType(); ResolvableType dependencyType = descriptor.getResolvableType();
if (dependencyType.getType() instanceof Class) { if (dependencyType.getType() instanceof Class) {

View File

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

View File

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

View File

@ -46,6 +46,7 @@ public class ArgumentTypePreparedStatementSetter implements PreparedStatementSet
* @param args the arguments to set * @param args the arguments to set
* @param argTypes the corresponding SQL types of the arguments * @param argTypes the corresponding SQL types of the arguments
*/ */
@SuppressWarnings("NullAway")
public ArgumentTypePreparedStatementSetter(@Nullable Object[] args, @Nullable int[] argTypes) { public ArgumentTypePreparedStatementSetter(@Nullable Object[] args, @Nullable int[] argTypes) {
if ((args != null && argTypes == null) || (args == null && argTypes != null) || if ((args != null && argTypes == null) || (args == null && argTypes != null) ||
(args != null && args.length != argTypes.length)) { (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.RowMapper;
import org.springframework.jdbc.core.SqlParameter; import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.core.namedparam.SqlParameterSource; import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.lang.Nullable;
/** /**
* A SimpleJdbcCall is a multithreaded, reusable object representing a call * A SimpleJdbcCall is a multithreaded, reusable object representing a call
@ -148,36 +149,42 @@ public class SimpleJdbcCall extends AbstractJdbcCall implements SimpleJdbcCallOp
} }
@Override @Override
@Nullable
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T> T executeFunction(Class<T> returnType, Object... args) { public <T> T executeFunction(Class<T> returnType, Object... args) {
return (T) doExecute(args).get(getScalarOutParameterName()); return (T) doExecute(args).get(getScalarOutParameterName());
} }
@Override @Override
@Nullable
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T> T executeFunction(Class<T> returnType, Map<String, ?> args) { public <T> T executeFunction(Class<T> returnType, Map<String, ?> args) {
return (T) doExecute(args).get(getScalarOutParameterName()); return (T) doExecute(args).get(getScalarOutParameterName());
} }
@Override @Override
@Nullable
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T> T executeFunction(Class<T> returnType, SqlParameterSource args) { public <T> T executeFunction(Class<T> returnType, SqlParameterSource args) {
return (T) doExecute(args).get(getScalarOutParameterName()); return (T) doExecute(args).get(getScalarOutParameterName());
} }
@Override @Override
@Nullable
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T> T executeObject(Class<T> returnType, Object... args) { public <T> T executeObject(Class<T> returnType, Object... args) {
return (T) doExecute(args).get(getScalarOutParameterName()); return (T) doExecute(args).get(getScalarOutParameterName());
} }
@Override @Override
@Nullable
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T> T executeObject(Class<T> returnType, Map<String, ?> args) { public <T> T executeObject(Class<T> returnType, Map<String, ?> args) {
return (T) doExecute(args).get(getScalarOutParameterName()); return (T) doExecute(args).get(getScalarOutParameterName());
} }
@Override @Override
@Nullable
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T> T executeObject(Class<T> returnType, SqlParameterSource args) { public <T> T executeObject(Class<T> returnType, SqlParameterSource args) {
return (T) doExecute(args).get(getScalarOutParameterName()); 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.RowMapper;
import org.springframework.jdbc.core.SqlParameter; import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.core.namedparam.SqlParameterSource; 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}. * 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 * Parameter values must be provided in the same order as the parameters are defined
* for the stored procedure. * for the stored procedure.
*/ */
@Nullable
<T> T executeFunction(Class<T> returnType, Object... args); <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 returnType the type of the value to return
* @param args a Map containing the parameter values to be used in the call * @param args a Map containing the parameter values to be used in the call
*/ */
@Nullable
<T> T executeFunction(Class<T> returnType, Map<String, ?> args); <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 returnType the type of the value to return
* @param args the MapSqlParameterSource containing the parameter values to be used in the call * @param args the MapSqlParameterSource containing the parameter values to be used in the call
*/ */
@Nullable
<T> T executeFunction(Class<T> returnType, SqlParameterSource args); <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 * Parameter values must be provided in the same order as the parameters are defined for
* the stored procedure. * the stored procedure.
*/ */
@Nullable
<T> T executeObject(Class<T> returnType, Object... args); <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 returnType the type of the value to return
* @param args a Map containing the parameter values to be used in the call * @param args a Map containing the parameter values to be used in the call
*/ */
@Nullable
<T> T executeObject(Class<T> returnType, Map<String, ?> args); <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 returnType the type of the value to return
* @param args the MapSqlParameterSource containing the parameter values to be used in the call * @param args the MapSqlParameterSource containing the parameter values to be used in the call
*/ */
@Nullable
<T> T executeObject(Class<T> returnType, SqlParameterSource args); <T> T executeObject(Class<T> returnType, SqlParameterSource args);
/** /**

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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