From 435cb0c7d66823c7eed47cec41df620374eade2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Deleuze?= Date: Mon, 13 Jan 2025 20:50:56 +0100 Subject: [PATCH] Specify generic type nullness in spring-context Also in spring-context-support. See gh-34140 --- .../cache/jcache/JCacheCache.java | 18 ++++++++------- .../config/AbstractJCacheConfiguration.java | 5 +++-- .../DefaultJCacheOperationSource.java | 6 ++--- .../interceptor/JCacheAspectSupport.java | 6 ++--- .../jcache/interceptor/JCacheInterceptor.java | 4 ++-- .../AbstractCachingConfiguration.java | 22 ++++++++++--------- .../cache/interceptor/CacheAspectSupport.java | 12 +++++----- .../interceptor/SimpleCacheResolver.java | 4 +++- .../AnnotationBeanNameGenerator.java | 4 ++-- .../annotation/ConditionEvaluator.java | 4 ++-- .../annotation/ConfigurationClassParser.java | 4 ++-- .../ConfigurationClassPostProcessor.java | 6 ++--- .../annotation/ConfigurationClassUtils.java | 6 ++--- .../annotation/MBeanExportConfiguration.java | 4 ++-- .../annotation/ParserStrategyUtils.java | 8 +++---- ...ionContextInitializationCodeGenerator.java | 4 ++-- .../MethodBasedEvaluationContext.java | 4 ++-- .../jmx/access/MBeanClientInterceptor.java | 4 ++-- .../AnnotationJmxAttributeSource.java | 6 ++--- .../AbstractReflectiveMBeanInfoAssembler.java | 5 +++-- .../AbstractAsyncConfiguration.java | 11 +++++----- .../annotation/AsyncAnnotationAdvisor.java | 8 +++---- .../AsyncAnnotationBeanPostProcessor.java | 10 ++++----- .../validation/DataBinder.java | 12 +++++----- .../validation/SmartValidator.java | 4 ++-- .../LocalValidatorFactoryBean.java | 8 +++---- .../MethodValidationAdapter.java | 8 +++---- .../MethodValidationInterceptor.java | 8 +++---- .../SpringValidatorAdapter.java | 4 ++-- .../validation/method/MethodValidator.java | 6 ++--- 30 files changed, 112 insertions(+), 103 deletions(-) diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/JCacheCache.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/JCacheCache.java index 724a66d19a..a465275f4a 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/JCacheCache.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/JCacheCache.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.springframework.cache.jcache; +import java.util.Objects; import java.util.concurrent.Callable; import java.util.function.Function; @@ -134,7 +135,8 @@ public class JCacheCache extends AbstractValueAdaptingCache { private static final PutIfAbsentEntryProcessor INSTANCE = new PutIfAbsentEntryProcessor(); @Override - public @Nullable Object process(MutableEntry entry, Object... arguments) throws EntryProcessorException { + @SuppressWarnings("NullAway") // Overridden method does not define nullness + public @Nullable Object process(MutableEntry entry, @Nullable Object... arguments) throws EntryProcessorException { Object existingValue = entry.getValue(); if (existingValue == null) { entry.setValue(arguments[0]); @@ -146,11 +148,11 @@ public class JCacheCache extends AbstractValueAdaptingCache { private static final class ValueLoaderEntryProcessor implements EntryProcessor { - private final Function fromStoreValue; + private final Function fromStoreValue; private final Function toStoreValue; - private ValueLoaderEntryProcessor(Function fromStoreValue, + private ValueLoaderEntryProcessor(Function fromStoreValue, Function toStoreValue) { this.fromStoreValue = fromStoreValue; @@ -158,16 +160,16 @@ public class JCacheCache extends AbstractValueAdaptingCache { } @Override - @SuppressWarnings("unchecked") - public @Nullable Object process(MutableEntry entry, Object... arguments) throws EntryProcessorException { + @SuppressWarnings({"unchecked","NullAway"}) // Overridden method does not define nullness + public @Nullable Object process(MutableEntry entry, @Nullable Object... arguments) throws EntryProcessorException { Callable valueLoader = (Callable) arguments[0]; if (entry.exists()) { - return this.fromStoreValue.apply(entry.getValue()); + return this.fromStoreValue.apply(Objects.requireNonNull(entry.getValue())); } else { Object value; try { - value = valueLoader.call(); + value = Objects.requireNonNull(valueLoader).call(); } catch (Exception ex) { throw new EntryProcessorException("Value loader '" + valueLoader + "' failed " + diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/config/AbstractJCacheConfiguration.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/config/AbstractJCacheConfiguration.java index 4bcc7ab244..dc31ac838f 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/config/AbstractJCacheConfiguration.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/config/AbstractJCacheConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,10 +41,11 @@ import org.springframework.context.annotation.Role; @Configuration(proxyBeanMethods = false) public abstract class AbstractJCacheConfiguration extends AbstractCachingConfiguration { - protected @Nullable Supplier exceptionCacheResolver; + protected @Nullable Supplier exceptionCacheResolver; @Override + @SuppressWarnings("NullAway") // https://github.com/uber/NullAway/issues/1126 protected void useCachingConfigurer(CachingConfigurerSupplier cachingConfigurerSupplier) { super.useCachingConfigurer(cachingConfigurerSupplier); this.exceptionCacheResolver = cachingConfigurerSupplier.adapt(config -> { diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/DefaultJCacheOperationSource.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/DefaultJCacheOperationSource.java index 850c2d0821..e71381f871 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/DefaultJCacheOperationSource.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/DefaultJCacheOperationSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -79,8 +79,8 @@ public class DefaultJCacheOperationSource extends AnnotationJCacheOperationSourc * @since 5.1 */ public DefaultJCacheOperationSource( - @Nullable Supplier cacheManager, @Nullable Supplier cacheResolver, - @Nullable Supplier exceptionCacheResolver, @Nullable Supplier keyGenerator) { + @Nullable Supplier cacheManager, @Nullable Supplier cacheResolver, + @Nullable Supplier exceptionCacheResolver, @Nullable Supplier keyGenerator) { this.cacheManager = SingletonSupplier.ofNullable(cacheManager); this.cacheResolver = SingletonSupplier.ofNullable(cacheResolver); diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/JCacheAspectSupport.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/JCacheAspectSupport.java index 6517f57bf5..68ae8c8d3d 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/JCacheAspectSupport.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/JCacheAspectSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -96,7 +96,7 @@ public class JCacheAspectSupport extends AbstractCacheInvoker implements Initial } - protected @Nullable Object execute(CacheOperationInvoker invoker, Object target, Method method, Object[] args) { + protected @Nullable Object execute(CacheOperationInvoker invoker, Object target, Method method, @Nullable Object[] args) { // Check whether aspect is enabled to cope with cases where the AJ is pulled in automatically if (this.initialized) { Class targetClass = AopProxyUtils.ultimateTargetClass(target); @@ -113,7 +113,7 @@ public class JCacheAspectSupport extends AbstractCacheInvoker implements Initial @SuppressWarnings("unchecked") private CacheOperationInvocationContext createCacheOperationInvocationContext( - Object target, Object[] args, JCacheOperation operation) { + Object target, @Nullable Object[] args, JCacheOperation operation) { return new DefaultCacheInvocationContext<>( (JCacheOperation) operation, target, args); diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/JCacheInterceptor.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/JCacheInterceptor.java index 79dce59d98..67aa162170 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/JCacheInterceptor.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/JCacheInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -60,7 +60,7 @@ public class JCacheInterceptor extends JCacheAspectSupport implements MethodInte * applying the default error handler if the supplier is not resolvable * @since 5.1 */ - public JCacheInterceptor(@Nullable Supplier errorHandler) { + public JCacheInterceptor(@Nullable Supplier errorHandler) { this.errorHandler = new SingletonSupplier<>(errorHandler, SimpleCacheErrorHandler::new); } diff --git a/spring-context/src/main/java/org/springframework/cache/annotation/AbstractCachingConfiguration.java b/spring-context/src/main/java/org/springframework/cache/annotation/AbstractCachingConfiguration.java index a84df83d3d..b7939d7494 100644 --- a/spring-context/src/main/java/org/springframework/cache/annotation/AbstractCachingConfiguration.java +++ b/spring-context/src/main/java/org/springframework/cache/annotation/AbstractCachingConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -50,13 +50,13 @@ public abstract class AbstractCachingConfiguration implements ImportAware { protected @Nullable AnnotationAttributes enableCaching; - protected @Nullable Supplier cacheManager; + protected @Nullable Supplier cacheManager; - protected @Nullable Supplier cacheResolver; + protected @Nullable Supplier cacheResolver; - protected @Nullable Supplier keyGenerator; + protected @Nullable Supplier keyGenerator; - protected @Nullable Supplier errorHandler; + protected @Nullable Supplier errorHandler; @Override @@ -70,8 +70,9 @@ public abstract class AbstractCachingConfiguration implements ImportAware { } @Autowired + @SuppressWarnings("NullAway") // https://github.com/uber/NullAway/issues/1126 void setConfigurers(ObjectProvider configurers) { - Supplier configurer = () -> { + Supplier configurer = () -> { List candidates = configurers.stream().toList(); if (CollectionUtils.isEmpty(candidates)) { return null; @@ -90,6 +91,7 @@ public abstract class AbstractCachingConfiguration implements ImportAware { /** * Extract the configuration from the nominated {@link CachingConfigurer}. */ + @SuppressWarnings("NullAway") // https://github.com/uber/NullAway/issues/1126 protected void useCachingConfigurer(CachingConfigurerSupplier cachingConfigurerSupplier) { this.cacheManager = cachingConfigurerSupplier.adapt(CachingConfigurer::cacheManager); this.cacheResolver = cachingConfigurerSupplier.adapt(CachingConfigurer::cacheResolver); @@ -100,10 +102,10 @@ public abstract class AbstractCachingConfiguration implements ImportAware { protected static class CachingConfigurerSupplier { - private final Supplier supplier; + private final SingletonSupplier supplier; - public CachingConfigurerSupplier(Supplier supplier) { - this.supplier = SingletonSupplier.of(supplier); + public CachingConfigurerSupplier(Supplier supplier) { + this.supplier = SingletonSupplier.ofNullable(supplier); } /** @@ -115,7 +117,7 @@ public abstract class AbstractCachingConfiguration implements ImportAware { * @param the type of the supplier * @return another supplier mapped by the specified function */ - public @Nullable Supplier adapt(Function provider) { + public Supplier<@Nullable T> adapt(Function provider) { return () -> { CachingConfigurer cachingConfigurer = this.supplier.get(); return (cachingConfigurer != null ? provider.apply(cachingConfigurer) : null); diff --git a/spring-context/src/main/java/org/springframework/cache/interceptor/CacheAspectSupport.java b/spring-context/src/main/java/org/springframework/cache/interceptor/CacheAspectSupport.java index 8928382553..9ca44f1696 100644 --- a/spring-context/src/main/java/org/springframework/cache/interceptor/CacheAspectSupport.java +++ b/spring-context/src/main/java/org/springframework/cache/interceptor/CacheAspectSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -154,8 +154,8 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker * @since 5.1 */ public void configure( - @Nullable Supplier errorHandler, @Nullable Supplier keyGenerator, - @Nullable Supplier cacheResolver, @Nullable Supplier cacheManager) { + @Nullable Supplier errorHandler, @Nullable Supplier keyGenerator, + @Nullable Supplier cacheResolver, @Nullable Supplier cacheManager) { this.errorHandler = new SingletonSupplier<>(errorHandler, SimpleCacheErrorHandler::new); this.keyGenerator = new SingletonSupplier<>(keyGenerator, SimpleKeyGenerator::new); @@ -317,7 +317,7 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker } protected CacheOperationContext getOperationContext( - CacheOperation operation, Method method, Object[] args, Object target, Class targetClass) { + CacheOperation operation, Method method, @Nullable Object[] args, Object target, Class targetClass) { CacheOperationMetadata metadata = getCacheOperationMetadata(operation, method, targetClass); return new CacheOperationContext(metadata, args, target); @@ -391,7 +391,7 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker this.evaluator.clear(); } - protected @Nullable Object execute(CacheOperationInvoker invoker, Object target, Method method, Object[] args) { + protected @Nullable Object execute(CacheOperationInvoker invoker, Object target, Method method, @Nullable Object[] args) { // Check whether aspect is enabled (to cope with cases where the AJ is pulled in automatically) if (this.initialized) { Class targetClass = AopProxyUtils.ultimateTargetClass(target); @@ -726,7 +726,7 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker boolean processed; public CacheOperationContexts(Collection operations, Method method, - Object[] args, Object target, Class targetClass) { + @Nullable Object[] args, Object target, Class targetClass) { this.contexts = new LinkedMultiValueMap<>(operations.size()); for (CacheOperation op : operations) { diff --git a/spring-context/src/main/java/org/springframework/cache/interceptor/SimpleCacheResolver.java b/spring-context/src/main/java/org/springframework/cache/interceptor/SimpleCacheResolver.java index 1edd47cd2a..ef61ca3394 100644 --- a/spring-context/src/main/java/org/springframework/cache/interceptor/SimpleCacheResolver.java +++ b/spring-context/src/main/java/org/springframework/cache/interceptor/SimpleCacheResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ import org.jspecify.annotations.Nullable; import org.springframework.cache.Cache; import org.springframework.cache.CacheManager; +import org.springframework.lang.Contract; /** * A simple {@link CacheResolver} that resolves the {@link Cache} instance(s) @@ -63,6 +64,7 @@ public class SimpleCacheResolver extends AbstractCacheResolver { * @return the SimpleCacheResolver ({@code null} if the CacheManager was {@code null}) * @since 5.1 */ + @Contract("null -> null; !null -> !null") static @Nullable SimpleCacheResolver of(@Nullable CacheManager cacheManager) { return (cacheManager != null ? new SimpleCacheResolver(cacheManager) : null); } diff --git a/spring-context/src/main/java/org/springframework/context/annotation/AnnotationBeanNameGenerator.java b/spring-context/src/main/java/org/springframework/context/annotation/AnnotationBeanNameGenerator.java index 9c51343bc0..8529a4cdf1 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/AnnotationBeanNameGenerator.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/AnnotationBeanNameGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -211,7 +211,7 @@ public class AnnotationBeanNameGenerator implements BeanNameGenerator { * @return whether the annotation qualifies as a stereotype with component name */ protected boolean isStereotypeWithNameValue(String annotationType, - Set metaAnnotationTypes, Map attributes) { + Set metaAnnotationTypes, Map attributes) { boolean isStereotype = metaAnnotationTypes.contains(COMPONENT_ANNOTATION_CLASSNAME) || annotationType.equals("jakarta.inject.Named"); diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ConditionEvaluator.java b/spring-context/src/main/java/org/springframework/context/annotation/ConditionEvaluator.java index 40b007001f..25554c1015 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ConditionEvaluator.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ConditionEvaluator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -129,7 +129,7 @@ class ConditionEvaluator { @SuppressWarnings("unchecked") private List getConditionClasses(AnnotatedTypeMetadata metadata) { - MultiValueMap attributes = metadata.getAllAnnotationAttributes(Conditional.class.getName(), true); + MultiValueMap attributes = metadata.getAllAnnotationAttributes(Conditional.class.getName(), true); Object values = (attributes != null ? attributes.get("value") : null); return (List) (values != null ? values : Collections.emptyList()); } diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java index 06adae67ed..1577432b58 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -1077,7 +1077,7 @@ class ConfigurationClassParser { } public Collection getAnnotationAttributes(String annType, String attribute) throws IOException { - Map annotationAttributes = this.metadata.getAnnotationAttributes(annType, true); + Map annotationAttributes = this.metadata.getAnnotationAttributes(annType, true); if (annotationAttributes == null || !annotationAttributes.containsKey(attribute)) { return Collections.emptySet(); } diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java index 03a0ef2877..cf39cb8038 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -658,9 +658,9 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo private final List descriptors; - private final Function resourceResolver; + private final Function resourceResolver; - PropertySourcesAotContribution(List descriptors, Function resourceResolver) { + PropertySourcesAotContribution(List descriptors, Function resourceResolver) { this.descriptors = descriptors; this.resourceResolver = resourceResolver; } diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassUtils.java b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassUtils.java index 381af86d0b..da17f41407 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassUtils.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -143,7 +143,7 @@ public abstract class ConfigurationClassUtils { } } - Map config = metadata.getAnnotationAttributes(Configuration.class.getName()); + Map config = metadata.getAnnotationAttributes(Configuration.class.getName()); if (config != null && !Boolean.FALSE.equals(config.get("proxyBeanMethods"))) { beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL); } @@ -208,7 +208,7 @@ public abstract class ConfigurationClassUtils { * @since 5.0 */ public static @Nullable Integer getOrder(AnnotationMetadata metadata) { - Map orderAttributes = metadata.getAnnotationAttributes(Order.class.getName()); + Map orderAttributes = metadata.getAnnotationAttributes(Order.class.getName()); return (orderAttributes != null ? ((Integer) orderAttributes.get(AnnotationUtils.VALUE)) : null); } diff --git a/spring-context/src/main/java/org/springframework/context/annotation/MBeanExportConfiguration.java b/spring-context/src/main/java/org/springframework/context/annotation/MBeanExportConfiguration.java index d680e4729b..85ffe5fbb9 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/MBeanExportConfiguration.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/MBeanExportConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -60,7 +60,7 @@ public class MBeanExportConfiguration implements ImportAware, EnvironmentAware, @Override public void setImportMetadata(AnnotationMetadata importMetadata) { - Map map = importMetadata.getAnnotationAttributes(EnableMBeanExport.class.getName()); + Map map = importMetadata.getAnnotationAttributes(EnableMBeanExport.class.getName()); this.enableMBeanExport = AnnotationAttributes.fromMap(map); if (this.enableMBeanExport == null) { throw new IllegalArgumentException( diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ParserStrategyUtils.java b/spring-context/src/main/java/org/springframework/context/annotation/ParserStrategyUtils.java index 20cdd84beb..bc682d476f 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ParserStrategyUtils.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ParserStrategyUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -76,7 +76,7 @@ abstract class ParserStrategyUtils { if (constructors.length == 1 && constructors[0].getParameterCount() > 0) { try { Constructor constructor = constructors[0]; - Object[] args = resolveArgs(constructor.getParameterTypes(), + @Nullable Object[] args = resolveArgs(constructor.getParameterTypes(), environment, resourceLoader, registry, classLoader); return BeanUtils.instantiateClass(constructor, args); } @@ -87,11 +87,11 @@ abstract class ParserStrategyUtils { return BeanUtils.instantiateClass(clazz); } - private static Object[] resolveArgs(Class[] parameterTypes, + private static @Nullable Object[] resolveArgs(Class[] parameterTypes, Environment environment, ResourceLoader resourceLoader, BeanDefinitionRegistry registry, @Nullable ClassLoader classLoader) { - Object[] parameters = new Object[parameterTypes.length]; + @Nullable Object[] parameters = new Object[parameterTypes.length]; for (int i = 0; i < parameterTypes.length; i++) { parameters[i] = resolveParameter(parameterTypes[i], environment, resourceLoader, registry, classLoader); diff --git a/spring-context/src/main/java/org/springframework/context/aot/ApplicationContextInitializationCodeGenerator.java b/spring-context/src/main/java/org/springframework/context/aot/ApplicationContextInitializationCodeGenerator.java index e74a416cf5..6f52e00448 100644 --- a/spring-context/src/main/java/org/springframework/context/aot/ApplicationContextInitializationCodeGenerator.java +++ b/spring-context/src/main/java/org/springframework/context/aot/ApplicationContextInitializationCodeGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -140,7 +140,7 @@ class ApplicationContextInitializationCodeGenerator implements BeanFactoryInitia this.initializers.add(methodReference); } - private static class InitializerMethodArgumentCodeGenerator implements Function { + private static class InitializerMethodArgumentCodeGenerator implements Function { @Override public @Nullable CodeBlock apply(TypeName typeName) { diff --git a/spring-context/src/main/java/org/springframework/context/expression/MethodBasedEvaluationContext.java b/spring-context/src/main/java/org/springframework/context/expression/MethodBasedEvaluationContext.java index 5daf2fe3ea..18c81c4866 100644 --- a/spring-context/src/main/java/org/springframework/context/expression/MethodBasedEvaluationContext.java +++ b/spring-context/src/main/java/org/springframework/context/expression/MethodBasedEvaluationContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -88,7 +88,7 @@ public class MethodBasedEvaluationContext extends StandardEvaluationContext { } // Expose indexed variables as well as parameter names (if discoverable) - String[] paramNames = this.parameterNameDiscoverer.getParameterNames(this.method); + @Nullable String[] paramNames = this.parameterNameDiscoverer.getParameterNames(this.method); int paramCount = (paramNames != null ? paramNames.length : this.method.getParameterCount()); int argsCount = this.arguments.length; diff --git a/spring-context/src/main/java/org/springframework/jmx/access/MBeanClientInterceptor.java b/spring-context/src/main/java/org/springframework/jmx/access/MBeanClientInterceptor.java index f160509d16..4e471f82e6 100644 --- a/spring-context/src/main/java/org/springframework/jmx/access/MBeanClientInterceptor.java +++ b/spring-context/src/main/java/org/springframework/jmx/access/MBeanClientInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -507,7 +507,7 @@ public class MBeanClientInterceptor * @param args the invocation arguments * @return the value returned by the method invocation. */ - private Object invokeOperation(Method method, Object[] args) throws JMException, IOException { + private Object invokeOperation(Method method, @Nullable Object[] args) throws JMException, IOException { Assert.state(this.serverToUse != null, "No MBeanServerConnection available"); MethodCacheKey key = new MethodCacheKey(method.getName(), method.getParameterTypes()); diff --git a/spring-context/src/main/java/org/springframework/jmx/export/annotation/AnnotationJmxAttributeSource.java b/spring-context/src/main/java/org/springframework/jmx/export/annotation/AnnotationJmxAttributeSource.java index b190f21966..e0bd6513b1 100644 --- a/spring-context/src/main/java/org/springframework/jmx/export/annotation/AnnotationJmxAttributeSource.java +++ b/spring-context/src/main/java/org/springframework/jmx/export/annotation/AnnotationJmxAttributeSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -172,10 +172,10 @@ public class AnnotationJmxAttributeSource implements JmxAttributeSource, BeanFac } @SuppressWarnings("unchecked") - private static T[] copyPropertiesToBeanArray( + private static @Nullable T[] copyPropertiesToBeanArray( List> anns, Class beanClass) { - T[] beans = (T[]) Array.newInstance(beanClass, anns.size()); + @Nullable T[] beans = (T[]) Array.newInstance(beanClass, anns.size()); int i = 0; for (MergedAnnotation ann : anns) { beans[i++] = copyPropertiesToBean(ann, beanClass); diff --git a/spring-context/src/main/java/org/springframework/jmx/export/assembler/AbstractReflectiveMBeanInfoAssembler.java b/spring-context/src/main/java/org/springframework/jmx/export/assembler/AbstractReflectiveMBeanInfoAssembler.java index 58b1460de8..564a68f0e9 100644 --- a/spring-context/src/main/java/org/springframework/jmx/export/assembler/AbstractReflectiveMBeanInfoAssembler.java +++ b/spring-context/src/main/java/org/springframework/jmx/export/assembler/AbstractReflectiveMBeanInfoAssembler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -506,9 +506,10 @@ public abstract class AbstractReflectiveMBeanInfoAssembler extends AbstractMBean * of the {@code MBeanExporter} * @return the {@code MBeanParameterInfo} array */ + @SuppressWarnings("NullAway") // https://github.com/uber/NullAway/issues/1127 protected MBeanParameterInfo[] getOperationParameters(Method method, String beanKey) { ParameterNameDiscoverer paramNameDiscoverer = getParameterNameDiscoverer(); - String[] paramNames = (paramNameDiscoverer != null ? paramNameDiscoverer.getParameterNames(method) : null); + @Nullable String[] paramNames = (paramNameDiscoverer != null ? paramNameDiscoverer.getParameterNames(method) : null); if (paramNames == null) { return new MBeanParameterInfo[0]; } diff --git a/spring-context/src/main/java/org/springframework/scheduling/annotation/AbstractAsyncConfiguration.java b/spring-context/src/main/java/org/springframework/scheduling/annotation/AbstractAsyncConfiguration.java index f851696c43..e0245db3da 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/annotation/AbstractAsyncConfiguration.java +++ b/spring-context/src/main/java/org/springframework/scheduling/annotation/AbstractAsyncConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -48,9 +48,9 @@ public abstract class AbstractAsyncConfiguration implements ImportAware { protected @Nullable AnnotationAttributes enableAsync; - protected @Nullable Supplier executor; + protected @Nullable Supplier executor; - protected @Nullable Supplier exceptionHandler; + protected @Nullable Supplier exceptionHandler; @Override @@ -67,8 +67,9 @@ public abstract class AbstractAsyncConfiguration implements ImportAware { * Collect any {@link AsyncConfigurer} beans through autowiring. */ @Autowired + @SuppressWarnings("NullAway") // https://github.com/uber/NullAway/issues/1126 void setConfigurers(ObjectProvider configurers) { - Supplier configurer = SingletonSupplier.of(() -> { + SingletonSupplier configurer = SingletonSupplier.ofNullable(() -> { List candidates = configurers.stream().toList(); if (CollectionUtils.isEmpty(candidates)) { return null; @@ -82,7 +83,7 @@ public abstract class AbstractAsyncConfiguration implements ImportAware { this.exceptionHandler = adapt(configurer, AsyncConfigurer::getAsyncUncaughtExceptionHandler); } - private Supplier adapt(Supplier supplier, Function provider) { + private Supplier<@Nullable T> adapt(SingletonSupplier supplier, Function provider) { return () -> { AsyncConfigurer configurer = supplier.get(); return (configurer != null ? provider.apply(configurer) : null); diff --git a/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncAnnotationAdvisor.java b/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncAnnotationAdvisor.java index 818043f28a..a957a8d765 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncAnnotationAdvisor.java +++ b/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncAnnotationAdvisor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -64,7 +64,7 @@ public class AsyncAnnotationAdvisor extends AbstractPointcutAdvisor implements B * Create a new {@code AsyncAnnotationAdvisor} for bean-style configuration. */ public AsyncAnnotationAdvisor() { - this((Supplier) null, (Supplier) null); + this((Supplier) null, (Supplier) null); } /** @@ -92,7 +92,7 @@ public class AsyncAnnotationAdvisor extends AbstractPointcutAdvisor implements B */ @SuppressWarnings("unchecked") public AsyncAnnotationAdvisor( - @Nullable Supplier executor, @Nullable Supplier exceptionHandler) { + @Nullable Supplier executor, @Nullable Supplier exceptionHandler) { Set> asyncAnnotationTypes = CollectionUtils.newLinkedHashSet(2); asyncAnnotationTypes.add(Async.class); @@ -157,7 +157,7 @@ public class AsyncAnnotationAdvisor extends AbstractPointcutAdvisor implements B protected Advice buildAdvice( - @Nullable Supplier executor, @Nullable Supplier exceptionHandler) { + @Nullable Supplier executor, @Nullable Supplier exceptionHandler) { AnnotationAsyncExecutionInterceptor interceptor = new AnnotationAsyncExecutionInterceptor(null); interceptor.configure(executor, exceptionHandler); diff --git a/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncAnnotationBeanPostProcessor.java b/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncAnnotationBeanPostProcessor.java index 9d7c859715..8be83b3f83 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncAnnotationBeanPostProcessor.java +++ b/spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncAnnotationBeanPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -77,9 +77,9 @@ public class AsyncAnnotationBeanPostProcessor extends AbstractBeanFactoryAwareAd protected final Log logger = LogFactory.getLog(getClass()); - private @Nullable Supplier executor; + private @Nullable Supplier executor; - private @Nullable Supplier exceptionHandler; + private @Nullable Supplier exceptionHandler; private @Nullable Class asyncAnnotationType; @@ -95,8 +95,8 @@ public class AsyncAnnotationBeanPostProcessor extends AbstractBeanFactoryAwareAd * applying the corresponding default if a supplier is not resolvable. * @since 5.1 */ - public void configure(@Nullable Supplier executor, - @Nullable Supplier exceptionHandler) { + public void configure(@Nullable Supplier executor, + @Nullable Supplier exceptionHandler) { this.executor = executor; this.exceptionHandler = exceptionHandler; diff --git a/spring-context/src/main/java/org/springframework/validation/DataBinder.java b/spring-context/src/main/java/org/springframework/validation/DataBinder.java index 25400efbf8..912dad1321 100644 --- a/spring-context/src/main/java/org/springframework/validation/DataBinder.java +++ b/spring-context/src/main/java/org/springframework/validation/DataBinder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -908,9 +908,9 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter { } else { // A single data class constructor -> resolve constructor arguments from request parameters. - String[] paramNames = BeanUtils.getParameterNames(ctor); + @Nullable String[] paramNames = BeanUtils.getParameterNames(ctor); Class[] paramTypes = ctor.getParameterTypes(); - Object[] args = new Object[paramTypes.length]; + @Nullable Object[] args = new Object[paramTypes.length]; Set failedParamNames = new HashSet<>(4); for (int i = 0; i < paramNames.length; i++) { @@ -1067,14 +1067,14 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter { } @SuppressWarnings("unchecked") - private V @Nullable [] createArray(String paramPath, ResolvableType type, ValueResolver valueResolver) { + private @Nullable V @Nullable [] createArray(String paramPath, ResolvableType type, ValueResolver valueResolver) { ResolvableType elementType = type.getNested(2); SortedSet indexes = getIndexes(paramPath, valueResolver); if (indexes == null) { return null; } int size = (indexes.last() < this.autoGrowCollectionLimit ? indexes.last() + 1: 0); - V[] array = (V[]) Array.newInstance(elementType.resolve(), size); + @Nullable V[] array = (V[]) Array.newInstance(elementType.resolve(), size); for (int index : indexes) { array[index] = (V) createObject(elementType, paramPath + "[" + index + "].", valueResolver); } @@ -1096,7 +1096,7 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter { } private void validateConstructorArgument( - Class constructorClass, String nestedPath, String name, @Nullable Object value) { + Class constructorClass, String nestedPath, @Nullable String name, @Nullable Object value) { Object[] hints = null; if (this.targetType != null && this.targetType.getSource() instanceof MethodParameter parameter) { diff --git a/spring-context/src/main/java/org/springframework/validation/SmartValidator.java b/spring-context/src/main/java/org/springframework/validation/SmartValidator.java index c64a62ad38..0d4895e0c6 100644 --- a/spring-context/src/main/java/org/springframework/validation/SmartValidator.java +++ b/spring-context/src/main/java/org/springframework/validation/SmartValidator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -59,7 +59,7 @@ public interface SmartValidator extends Validator { * @see jakarta.validation.Validator#validateValue(Class, String, Object, Class[]) */ default void validateValue( - Class targetType, String fieldName, @Nullable Object value, Errors errors, Object... validationHints) { + Class targetType, @Nullable String fieldName, @Nullable Object value, Errors errors, Object... validationHints) { throw new IllegalArgumentException("Cannot validate individual value for " + targetType); } diff --git a/spring-context/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java b/spring-context/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java index 00e7af3ee2..b07d8ef783 100644 --- a/spring-context/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java +++ b/spring-context/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -242,7 +242,7 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter @Override - @SuppressWarnings({"rawtypes", "unchecked", "NullAway"}) // TODO NullAway bug? + @SuppressWarnings({"rawtypes", "unchecked"}) public void afterPropertiesSet() { Configuration configuration; if (this.providerClass != null) { @@ -332,13 +332,13 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter configuration.parameterNameProvider(new ParameterNameProvider() { @Override public List getParameterNames(Constructor constructor) { - String[] paramNames = discoverer.getParameterNames(constructor); + @Nullable String[] paramNames = discoverer.getParameterNames(constructor); return (paramNames != null ? Arrays.asList(paramNames) : defaultProvider.getParameterNames(constructor)); } @Override public List getParameterNames(Method method) { - String[] paramNames = discoverer.getParameterNames(method); + @Nullable String[] paramNames = discoverer.getParameterNames(method); return (paramNames != null ? Arrays.asList(paramNames) : defaultProvider.getParameterNames(method)); } diff --git a/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationAdapter.java b/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationAdapter.java index a8571d0be1..28c971ef79 100644 --- a/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationAdapter.java +++ b/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -236,7 +236,7 @@ public class MethodValidationAdapter implements MethodValidator { @Override public final MethodValidationResult validateArguments( Object target, Method method, MethodParameter @Nullable [] parameters, - Object[] arguments, Class[] groups) { + @Nullable Object[] arguments, Class[] groups) { Set> violations = invokeValidatorForArguments(target, method, arguments, groups); @@ -254,7 +254,7 @@ public class MethodValidationAdapter implements MethodValidator { * Invoke the validator, and return the resulting violations. */ public final Set> invokeValidatorForArguments( - Object target, Method method, Object[] arguments, Class[] groups) { + Object target, Method method, @Nullable Object[] arguments, Class[] groups) { ExecutableValidator execVal = this.validator.get().forExecutables(); try { @@ -298,7 +298,7 @@ public class MethodValidationAdapter implements MethodValidator { private MethodValidationResult adaptViolations( Object target, Method method, Set> violations, Function parameterFunction, - Function argumentFunction) { + Function argumentFunction) { Map paramViolations = new LinkedHashMap<>(); Map nestedViolations = new LinkedHashMap<>(); diff --git a/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationInterceptor.java b/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationInterceptor.java index 3d1f6aa110..a7c9038b12 100644 --- a/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationInterceptor.java +++ b/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -149,7 +149,7 @@ public class MethodValidationInterceptor implements MethodInterceptor { Object target = getTarget(invocation); Method method = invocation.getMethod(); - Object[] arguments = invocation.getArguments(); + @Nullable Object[] arguments = invocation.getArguments(); Class[] groups = determineValidationGroups(invocation); if (reactorPresent) { @@ -239,9 +239,9 @@ public class MethodValidationInterceptor implements MethodInterceptor { ReactiveAdapterRegistry.getSharedInstance(); - static Object[] insertAsyncValidation( + static @Nullable Object[] insertAsyncValidation( Supplier validatorAdapterSupplier, boolean adaptViolations, - Object target, Method method, Object[] arguments) { + Object target, Method method, @Nullable Object[] arguments) { for (int i = 0; i < method.getParameterCount(); i++) { if (arguments[i] == null) { diff --git a/spring-context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java b/spring-context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java index 6b97534466..aeb98bebab 100644 --- a/spring-context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java +++ b/spring-context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -116,7 +116,7 @@ public class SpringValidatorAdapter implements SmartValidator, jakarta.validatio @SuppressWarnings({"rawtypes", "unchecked"}) @Override public void validateValue( - Class targetType, String fieldName, @Nullable Object value, Errors errors, Object... validationHints) { + Class targetType, @Nullable String fieldName, @Nullable Object value, Errors errors, Object... validationHints) { if (this.targetValidator != null) { processConstraintViolations(this.targetValidator.validateValue( diff --git a/spring-context/src/main/java/org/springframework/validation/method/MethodValidator.java b/spring-context/src/main/java/org/springframework/validation/method/MethodValidator.java index 2b97be8e42..526ba41bf2 100644 --- a/spring-context/src/main/java/org/springframework/validation/method/MethodValidator.java +++ b/spring-context/src/main/java/org/springframework/validation/method/MethodValidator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -53,7 +53,7 @@ public interface MethodValidator { */ MethodValidationResult validateArguments( Object target, Method method, MethodParameter @Nullable [] parameters, - Object[] arguments, Class[] groups); + @Nullable Object[] arguments, Class[] groups); /** * Delegate to {@link #validateArguments} and handle the validation result, @@ -64,7 +64,7 @@ public interface MethodValidator { */ default void applyArgumentValidation( Object target, Method method, MethodParameter @Nullable [] parameters, - Object[] arguments, Class[] groups) { + @Nullable Object[] arguments, Class[] groups) { MethodValidationResult result = validateArguments(target, method, parameters, arguments, groups); if (result.hasErrors()) {