From 8b51b36729af4653450114a238b1b22d2a5383a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Deleuze?= Date: Tue, 26 Mar 2024 15:53:01 +0100 Subject: [PATCH] Perform NullAway build-time checks in more modules This commit enables null-safety build-time checks in all remaining modules except spring-test. See gh-32475 --- gradle/spring-module.gradle | 7 +++---- .../jcache/interceptor/CacheResultInterceptor.java | 2 +- .../interceptor/DefaultJCacheOperationSource.java | 3 +++ .../scheduling/quartz/LocalDataSourceJobStore.java | 1 + .../scheduling/quartz/SchedulerAccessor.java | 1 + .../scheduling/quartz/SchedulerFactoryBean.java | 1 + .../context/annotation/BeanMethod.java | 1 + .../ComponentScanBeanDefinitionParser.java | 13 ++++++++++--- .../context/annotation/ConfigurationClass.java | 1 + .../annotation/ConfigurationClassParser.java | 1 + .../annotation/ConfigurationClassPostProcessor.java | 2 ++ .../ContextAnnotationAutowireCandidateResolver.java | 1 + .../context/annotation/ProfileCondition.java | 1 + .../event/AbstractApplicationEventMulticaster.java | 4 +++- .../event/ApplicationListenerMethodAdapter.java | 1 + .../context/event/EventListenerMethodProcessor.java | 2 +- .../i18n/LocaleContextThreadLocalAccessor.java | 3 +++ .../standard/DateTimeFormatterRegistrar.java | 1 + .../springframework/jmx/export/MBeanExporter.java | 1 + .../annotation/AnnotationJmxAttributeSource.java | 3 ++- .../org/springframework/validation/DataBinder.java | 5 ++++- .../validation/DefaultMessageCodesResolver.java | 3 ++- .../org/springframework/validation/FieldError.java | 3 +-- .../method/ParameterValidationResult.java | 4 ++-- .../aot/hint/BindingReflectionHintsRegistrar.java | 1 + .../org/springframework/core/CoroutinesUtils.java | 2 +- .../org/springframework/util/PlaceholderParser.java | 2 ++ .../java/org/springframework/util/StreamUtils.java | 2 ++ .../jms/connection/JmsResourceHolder.java | 1 + .../listener/SimpleMessageListenerContainer.java | 1 + .../rsocket/service/RSocketServiceMethod.java | 1 + ...nceManagedTypesBeanRegistrationAotProcessor.java | 1 + .../interceptor/TransactionAspectSupport.java | 8 ++++++-- .../http/InvalidMediaTypeException.java | 5 +++-- .../org/springframework/http/RequestEntity.java | 8 ++++---- .../org/springframework/http/ResponseEntity.java | 3 +-- .../client/AbstractStreamingClientHttpRequest.java | 1 + .../http/client/JdkClientHttpRequest.java | 1 + .../http/client/JettyClientHttpRequest.java | 1 + .../codec/ServerSentEventHttpMessageReader.java | 1 + .../http/codec/multipart/MultipartParser.java | 2 ++ .../http/codec/multipart/PartGenerator.java | 1 + .../ResourceRegionHttpMessageConverter.java | 1 + .../json/AbstractJackson2HttpMessageConverter.java | 3 ++- .../reactive/AbstractListenerReadPublisher.java | 1 + .../AbstractListenerWriteFlushProcessor.java | 1 + .../reactive/AbstractListenerWriteProcessor.java | 1 + .../server/reactive/ServletServerHttpRequest.java | 1 + .../http/server/reactive/WriteResultPublisher.java | 1 + .../web/service/invoker/HttpServiceMethod.java | 4 +++- .../annotation/RequestMappingHandlerMapping.java | 1 + ...tractMessageConverterMethodArgumentResolver.java | 2 +- .../web/servlet/tags/MessageTag.java | 1 + 53 files changed, 93 insertions(+), 31 deletions(-) diff --git a/gradle/spring-module.gradle b/gradle/spring-module.gradle index fdc33db87ed6..d096d5b23bf6 100644 --- a/gradle/spring-module.gradle +++ b/gradle/spring-module.gradle @@ -117,12 +117,11 @@ tasks.withType(JavaCompile).configureEach { options.errorprone { 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.jdbc," + - "org.springframework.r2dbc,org.springframework.orm,org.springframework.beans,org.springframework.aop") + option("NullAway:AnnotatedPackages", "org.springframework") 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.aot.nativex.feature") + "org.springframework.javapoet,org.springframework.aot.nativex.substitution,org.springframework.aot.nativex.feature," + + "org.springframework.test,org.springframework.mock") } } tasks.compileJava { diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/CacheResultInterceptor.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/CacheResultInterceptor.java index 755a7374d294..dbd71ba26485 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/CacheResultInterceptor.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/CacheResultInterceptor.java @@ -101,7 +101,7 @@ protected void cacheException(@Nullable Cache exceptionCache, ExceptionTypeFilte private Cache resolveExceptionCache(CacheOperationInvocationContext context) { CacheResolver exceptionCacheResolver = context.getOperation().getExceptionCacheResolver(); if (exceptionCacheResolver != null) { - return extractFrom(context.getOperation().getExceptionCacheResolver().resolveCaches(context)); + return extractFrom(exceptionCacheResolver.resolveCaches(context)); } return null; } 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 f6f84d360467..1b93b140ba2b 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 @@ -188,6 +188,7 @@ protected T getBean(Class type) { } } + @SuppressWarnings("NullAway") protected CacheManager getDefaultCacheManager() { if (getCacheManager() == null) { Assert.state(this.beanFactory != null, "BeanFactory required for default CacheManager resolution"); @@ -207,6 +208,7 @@ protected CacheManager getDefaultCacheManager() { } @Override + @SuppressWarnings("NullAway") protected CacheResolver getDefaultCacheResolver() { if (getCacheResolver() == null) { this.cacheResolver = SingletonSupplier.of(new SimpleCacheResolver(getDefaultCacheManager())); @@ -215,6 +217,7 @@ protected CacheResolver getDefaultCacheResolver() { } @Override + @SuppressWarnings("NullAway") protected CacheResolver getDefaultExceptionCacheResolver() { if (getExceptionCacheResolver() == null) { this.exceptionCacheResolver = SingletonSupplier.of(new LazyCacheResolver()); diff --git a/spring-context-support/src/main/java/org/springframework/scheduling/quartz/LocalDataSourceJobStore.java b/spring-context-support/src/main/java/org/springframework/scheduling/quartz/LocalDataSourceJobStore.java index f6042bee9347..5e68e7331865 100644 --- a/spring-context-support/src/main/java/org/springframework/scheduling/quartz/LocalDataSourceJobStore.java +++ b/spring-context-support/src/main/java/org/springframework/scheduling/quartz/LocalDataSourceJobStore.java @@ -90,6 +90,7 @@ public class LocalDataSourceJobStore extends JobStoreCMT { @Override + @SuppressWarnings("NullAway") public void initialize(ClassLoadHelper loadHelper, SchedulerSignaler signaler) throws SchedulerConfigException { // Absolutely needs thread-bound DataSource to initialize. this.dataSource = SchedulerFactoryBean.getConfigTimeDataSource(); diff --git a/spring-context-support/src/main/java/org/springframework/scheduling/quartz/SchedulerAccessor.java b/spring-context-support/src/main/java/org/springframework/scheduling/quartz/SchedulerAccessor.java index f9d4c72ab306..e6b1c7aa5437 100644 --- a/spring-context-support/src/main/java/org/springframework/scheduling/quartz/SchedulerAccessor.java +++ b/spring-context-support/src/main/java/org/springframework/scheduling/quartz/SchedulerAccessor.java @@ -203,6 +203,7 @@ public void setResourceLoader(ResourceLoader resourceLoader) { /** * Register jobs and triggers (within a transaction, if possible). */ + @SuppressWarnings("NullAway") protected void registerJobsAndTriggers() throws SchedulerException { TransactionStatus transactionStatus = null; if (this.transactionManager != null) { diff --git a/spring-context-support/src/main/java/org/springframework/scheduling/quartz/SchedulerFactoryBean.java b/spring-context-support/src/main/java/org/springframework/scheduling/quartz/SchedulerFactoryBean.java index 8b69a7d50e4c..937240d1a78f 100644 --- a/spring-context-support/src/main/java/org/springframework/scheduling/quartz/SchedulerFactoryBean.java +++ b/spring-context-support/src/main/java/org/springframework/scheduling/quartz/SchedulerFactoryBean.java @@ -661,6 +661,7 @@ private Scheduler prepareScheduler(SchedulerFactory schedulerFactory) throws Sch * @see #afterPropertiesSet * @see org.quartz.SchedulerFactory#getScheduler */ + @SuppressWarnings("NullAway") protected Scheduler createScheduler(SchedulerFactory schedulerFactory, @Nullable String schedulerName) throws SchedulerException { diff --git a/spring-context/src/main/java/org/springframework/context/annotation/BeanMethod.java b/spring-context/src/main/java/org/springframework/context/annotation/BeanMethod.java index b1570ddad5a7..1b41d938c289 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/BeanMethod.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/BeanMethod.java @@ -43,6 +43,7 @@ final class BeanMethod extends ConfigurationMethod { @Override + @SuppressWarnings("NullAway") public void validate(ProblemReporter problemReporter) { if ("void".equals(getMetadata().getReturnTypeName())) { // declared as void: potential misuse of @Bean, maybe meant as init method instead? diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ComponentScanBeanDefinitionParser.java b/spring-context/src/main/java/org/springframework/context/annotation/ComponentScanBeanDefinitionParser.java index 00df7a55dd7b..d38a670c9582 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ComponentScanBeanDefinitionParser.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ComponentScanBeanDefinitionParser.java @@ -40,6 +40,7 @@ import org.springframework.core.type.filter.RegexPatternTypeFilter; import org.springframework.core.type.filter.TypeFilter; import org.springframework.lang.Nullable; +import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.ReflectionUtils; import org.springframework.util.StringUtils; @@ -112,14 +113,18 @@ protected ClassPathBeanDefinitionScanner configureScanner(ParserContext parserCo parseBeanNameGenerator(element, scanner); } catch (Exception ex) { - parserContext.getReaderContext().error(ex.getMessage(), parserContext.extractSource(element), ex.getCause()); + String message = ex.getMessage(); + Assert.state(message != null, "Exception message must not be null"); + parserContext.getReaderContext().error(message, parserContext.extractSource(element), ex.getCause()); } try { parseScope(element, scanner); } catch (Exception ex) { - parserContext.getReaderContext().error(ex.getMessage(), parserContext.extractSource(element), ex.getCause()); + String message = ex.getMessage(); + Assert.state(message != null, "Exception message must not be null"); + parserContext.getReaderContext().error(message, parserContext.extractSource(element), ex.getCause()); } parseTypeFilters(element, scanner, parserContext); @@ -214,8 +219,10 @@ else if (EXCLUDE_FILTER_ELEMENT.equals(localName)) { "Ignoring non-present type filter class: " + ex, parserContext.extractSource(element)); } catch (Exception ex) { + String message = ex.getMessage(); + Assert.state(message != null, "Exception message must not be null"); parserContext.getReaderContext().error( - ex.getMessage(), parserContext.extractSource(element), ex.getCause()); + message, parserContext.extractSource(element), ex.getCause()); } } } diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClass.java b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClass.java index dfb3c4045bb5..7664cb69813a 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClass.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClass.java @@ -219,6 +219,7 @@ Map getImportBeanDefinitionRe return this.importBeanDefinitionRegistrars; } + @SuppressWarnings("NullAway") void validate(ProblemReporter problemReporter) { Map attributes = this.metadata.getAnnotationAttributes(Configuration.class.getName()); 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 e42aa2532a19..b4356d8957b6 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 @@ -819,6 +819,7 @@ void register(DeferredImportSelectorHolder deferredImport) { deferredImport.getConfigurationClass()); } + @SuppressWarnings("NullAway") void processGroupImports() { for (DeferredImportSelectorGrouping grouping : this.groupings.values()) { Predicate filter = grouping.getCandidateFilter(); 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 b1a4408c6fb5..336ce0956265 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 @@ -325,6 +325,7 @@ public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registe @Override @Nullable + @SuppressWarnings("NullAway") public BeanFactoryInitializationAotContribution processAheadOfTime(ConfigurableListableBeanFactory beanFactory) { boolean hasPropertySourceDescriptors = !CollectionUtils.isEmpty(this.propertySourceDescriptors); boolean hasImportRegistry = beanFactory.containsBean(IMPORT_REGISTRY_BEAN_NAME); @@ -556,6 +557,7 @@ public ImportAwareBeanPostProcessor(BeanFactory beanFactory) { } @Override + @Nullable public PropertyValues postProcessProperties(@Nullable PropertyValues pvs, Object bean, String beanName) { // Inject the BeanFactory before AutowiredAnnotationBeanPostProcessor's // postProcessProperties method attempts to autowire other configuration beans. diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ContextAnnotationAutowireCandidateResolver.java b/spring-context/src/main/java/org/springframework/context/annotation/ContextAnnotationAutowireCandidateResolver.java index 1718ffd4de49..dcf4aa91aeb2 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ContextAnnotationAutowireCandidateResolver.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ContextAnnotationAutowireCandidateResolver.java @@ -98,6 +98,7 @@ public Class getTargetClass() { return descriptor.getDependencyType(); } @Override + @SuppressWarnings("NullAway") public Object getTarget() { Set autowiredBeanNames = (beanName != null ? new LinkedHashSet<>(1) : null); Object target = dlbf.doResolveDependency(descriptor, beanName, autowiredBeanNames, null); diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ProfileCondition.java b/spring-context/src/main/java/org/springframework/context/annotation/ProfileCondition.java index cc9b664921de..a720639e7cb6 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ProfileCondition.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ProfileCondition.java @@ -31,6 +31,7 @@ class ProfileCondition implements Condition { @Override + @SuppressWarnings("NullAway") public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { MultiValueMap attrs = metadata.getAllAnnotationAttributes(Profile.class.getName()); if (attrs != null) { diff --git a/spring-context/src/main/java/org/springframework/context/event/AbstractApplicationEventMulticaster.java b/spring-context/src/main/java/org/springframework/context/event/AbstractApplicationEventMulticaster.java index 76be0c052529..14f8c44e950a 100644 --- a/spring-context/src/main/java/org/springframework/context/event/AbstractApplicationEventMulticaster.java +++ b/spring-context/src/main/java/org/springframework/context/event/AbstractApplicationEventMulticaster.java @@ -40,6 +40,7 @@ import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; +import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; /** @@ -229,6 +230,7 @@ protected Collection> getApplicationListeners( * @param retriever the ListenerRetriever, if supposed to populate one (for caching purposes) * @return the pre-filtered list of application listeners for the given event and source type */ + @SuppressWarnings("NullAway") private Collection> retrieveApplicationListeners( ResolvableType eventType, @Nullable Class sourceType, @Nullable CachedListenerRetriever retriever) { @@ -313,7 +315,7 @@ private Collection> retrieveApplicationListeners( AnnotationAwareOrderComparator.sort(allListeners); if (retriever != null) { - if (filteredListenerBeans.isEmpty()) { + if (CollectionUtils.isEmpty(filteredListenerBeans)) { retriever.applicationListeners = new LinkedHashSet<>(allListeners); retriever.applicationListenerBeans = filteredListenerBeans; } diff --git a/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java b/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java index b64fe8fbd5e2..a717216728a0 100644 --- a/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java +++ b/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java @@ -460,6 +460,7 @@ private void assertTargetBean(Method method, Object targetBean, @Nullable Object } } + @SuppressWarnings("NullAway") private String getInvocationErrorMessage(Object bean, @Nullable String message, @Nullable Object[] resolvedArgs) { StringBuilder sb = new StringBuilder(getDetailedErrorMessage(bean, message)); sb.append("Resolved arguments: \n"); diff --git a/spring-context/src/main/java/org/springframework/context/event/EventListenerMethodProcessor.java b/spring-context/src/main/java/org/springframework/context/event/EventListenerMethodProcessor.java index 12afa030567a..5f330e754526 100644 --- a/spring-context/src/main/java/org/springframework/context/event/EventListenerMethodProcessor.java +++ b/spring-context/src/main/java/org/springframework/context/event/EventListenerMethodProcessor.java @@ -111,7 +111,7 @@ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) @Override public void afterSingletonsInstantiated() { ConfigurableListableBeanFactory beanFactory = this.beanFactory; - Assert.state(this.beanFactory != null, "No ConfigurableListableBeanFactory set"); + Assert.state(beanFactory != null, "No ConfigurableListableBeanFactory set"); String[] beanNames = beanFactory.getBeanNamesForType(Object.class); for (String beanName : beanNames) { if (!ScopedProxyUtils.isScopedTarget(beanName)) { diff --git a/spring-context/src/main/java/org/springframework/context/i18n/LocaleContextThreadLocalAccessor.java b/spring-context/src/main/java/org/springframework/context/i18n/LocaleContextThreadLocalAccessor.java index 4a0c09d2cab8..5d31165db814 100644 --- a/spring-context/src/main/java/org/springframework/context/i18n/LocaleContextThreadLocalAccessor.java +++ b/spring-context/src/main/java/org/springframework/context/i18n/LocaleContextThreadLocalAccessor.java @@ -18,6 +18,8 @@ import io.micrometer.context.ThreadLocalAccessor; +import org.springframework.lang.Nullable; + /** * Adapt {@link LocaleContextHolder} to the {@link ThreadLocalAccessor} contract * to assist the Micrometer Context Propagation library with {@link LocaleContext} @@ -40,6 +42,7 @@ public Object key() { } @Override + @Nullable public LocaleContext getValue() { return LocaleContextHolder.getLocaleContext(); } diff --git a/spring-context/src/main/java/org/springframework/format/datetime/standard/DateTimeFormatterRegistrar.java b/spring-context/src/main/java/org/springframework/format/datetime/standard/DateTimeFormatterRegistrar.java index 1a72d4494938..6ef3f2780748 100644 --- a/spring-context/src/main/java/org/springframework/format/datetime/standard/DateTimeFormatterRegistrar.java +++ b/spring-context/src/main/java/org/springframework/format/datetime/standard/DateTimeFormatterRegistrar.java @@ -51,6 +51,7 @@ * @see org.springframework.format.FormatterRegistrar#registerFormatters * @see org.springframework.format.datetime.DateFormatterRegistrar */ +@SuppressWarnings("NullAway") public class DateTimeFormatterRegistrar implements FormatterRegistrar { private enum Type {DATE, TIME, DATE_TIME} diff --git a/spring-context/src/main/java/org/springframework/jmx/export/MBeanExporter.java b/spring-context/src/main/java/org/springframework/jmx/export/MBeanExporter.java index 990e26b7de6a..b37536818098 100644 --- a/spring-context/src/main/java/org/springframework/jmx/export/MBeanExporter.java +++ b/spring-context/src/main/java/org/springframework/jmx/export/MBeanExporter.java @@ -993,6 +993,7 @@ private void registerNotificationListeners() throws MBeanExportException { * Unregister the configured {@link NotificationListener NotificationListeners} * from the {@link MBeanServer}. */ + @SuppressWarnings("NullAway") private void unregisterNotificationListeners() { if (this.server != null) { this.registeredNotificationListeners.forEach((bean, mappedObjectNames) -> { 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 6f02406bb164..3398cc8803cd 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 @@ -43,6 +43,7 @@ import org.springframework.jmx.export.metadata.InvalidMetadataException; import org.springframework.jmx.export.metadata.JmxAttributeSource; import org.springframework.lang.Nullable; +import org.springframework.util.StringUtils; import org.springframework.util.StringValueResolver; /** @@ -117,7 +118,7 @@ public org.springframework.jmx.export.metadata.ManagedAttribute getManagedAttrib pvs.removePropertyValue("defaultValue"); PropertyAccessorFactory.forBeanPropertyAccess(bean).setPropertyValues(pvs); String defaultValue = (String) map.get("defaultValue"); - if (!defaultValue.isEmpty()) { + if (StringUtils.hasLength(defaultValue)) { bean.setDefaultValue(defaultValue); } return bean; 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 c7af62b50117..8702cc52f827 100644 --- a/spring-context/src/main/java/org/springframework/validation/DataBinder.java +++ b/spring-context/src/main/java/org/springframework/validation/DataBinder.java @@ -682,7 +682,8 @@ public void setValidator(@Nullable Validator validator) { } } - private void assertValidators(Validator... validators) { + @SuppressWarnings("NullAway") + private void assertValidators(@Nullable Validator... validators) { Object target = getTarget(); for (Validator validator : validators) { if (validator != null && (target != null && !validator.supports(target.getClass()))) { @@ -741,6 +742,7 @@ public List getValidators() { * {@link #setExcludedValidators(Predicate) exclude predicate}. * @since 6.1 */ + @SuppressWarnings("NullAway") public List getValidatorsToApply() { return (this.excludedValidators != null ? this.validators.stream().filter(validator -> !this.excludedValidators.test(validator)).toList() : @@ -1168,6 +1170,7 @@ protected boolean isAllowed(String field) { * @see #getBindingErrorProcessor * @see BindingErrorProcessor#processMissingFieldError */ + @SuppressWarnings("NullAway") protected void checkRequiredFields(MutablePropertyValues mpvs) { String[] requiredFields = getRequiredFields(); if (!ObjectUtils.isEmpty(requiredFields)) { diff --git a/spring-context/src/main/java/org/springframework/validation/DefaultMessageCodesResolver.java b/spring-context/src/main/java/org/springframework/validation/DefaultMessageCodesResolver.java index 15655c1cc7fc..47bf72dd7b2e 100644 --- a/spring-context/src/main/java/org/springframework/validation/DefaultMessageCodesResolver.java +++ b/spring-context/src/main/java/org/springframework/validation/DefaultMessageCodesResolver.java @@ -242,7 +242,8 @@ public String format(String errorCode, @Nullable String objectName, @Nullable St * {@link DefaultMessageCodesResolver#CODE_SEPARATOR}, skipping zero-length or * null elements altogether. */ - public static String toDelimitedString(String... elements) { + @SuppressWarnings("NullAway") + public static String toDelimitedString(@Nullable String... elements) { StringJoiner rtn = new StringJoiner(CODE_SEPARATOR); for (String element : elements) { if (StringUtils.hasLength(element)) { diff --git a/spring-context/src/main/java/org/springframework/validation/FieldError.java b/spring-context/src/main/java/org/springframework/validation/FieldError.java index e8b03717cf1d..bb57d556ff39 100644 --- a/spring-context/src/main/java/org/springframework/validation/FieldError.java +++ b/spring-context/src/main/java/org/springframework/validation/FieldError.java @@ -107,8 +107,7 @@ public boolean equals(@Nullable Object other) { if (!super.equals(other)) { return false; } - FieldError otherError = (FieldError) other; - return (getField().equals(otherError.getField()) && + return (other instanceof FieldError otherError && getField().equals(otherError.getField()) && ObjectUtils.nullSafeEquals(getRejectedValue(), otherError.getRejectedValue()) && isBindingFailure() == otherError.isBindingFailure()); } diff --git a/spring-context/src/main/java/org/springframework/validation/method/ParameterValidationResult.java b/spring-context/src/main/java/org/springframework/validation/method/ParameterValidationResult.java index aeb0f3493bc5..6f14e1de2df2 100644 --- a/spring-context/src/main/java/org/springframework/validation/method/ParameterValidationResult.java +++ b/spring-context/src/main/java/org/springframework/validation/method/ParameterValidationResult.java @@ -173,8 +173,8 @@ public boolean equals(@Nullable Object other) { if (!super.equals(other)) { return false; } - ParameterValidationResult otherResult = (ParameterValidationResult) other; - return (getMethodParameter().equals(otherResult.getMethodParameter()) && + return (other instanceof ParameterValidationResult otherResult && + getMethodParameter().equals(otherResult.getMethodParameter()) && ObjectUtils.nullSafeEquals(getArgument(), otherResult.getArgument()) && ObjectUtils.nullSafeEquals(getContainerIndex(), otherResult.getContainerIndex()) && ObjectUtils.nullSafeEquals(getContainerKey(), otherResult.getContainerKey())); diff --git a/spring-core/src/main/java/org/springframework/aot/hint/BindingReflectionHintsRegistrar.java b/spring-core/src/main/java/org/springframework/aot/hint/BindingReflectionHintsRegistrar.java index 1c94b9dbe5c8..b6a7500ae79c 100644 --- a/spring-core/src/main/java/org/springframework/aot/hint/BindingReflectionHintsRegistrar.java +++ b/spring-core/src/main/java/org/springframework/aot/hint/BindingReflectionHintsRegistrar.java @@ -63,6 +63,7 @@ public class BindingReflectionHintsRegistrar { * @param hints the hints instance to use * @param types the types to register */ + @SuppressWarnings("NullAway") public void registerReflectionHints(ReflectionHints hints, @Nullable Type... types) { Set seen = new HashSet<>(); for (Type type : types) { diff --git a/spring-core/src/main/java/org/springframework/core/CoroutinesUtils.java b/spring-core/src/main/java/org/springframework/core/CoroutinesUtils.java index cf5781a60e0b..54835cde378f 100644 --- a/spring-core/src/main/java/org/springframework/core/CoroutinesUtils.java +++ b/spring-core/src/main/java/org/springframework/core/CoroutinesUtils.java @@ -108,7 +108,7 @@ public static Publisher invokeSuspendingFunction(Method method, Object target * @throws IllegalArgumentException if {@code method} is not a suspending function * @since 6.0 */ - @SuppressWarnings({"deprecation", "DataFlowIssue"}) + @SuppressWarnings({"deprecation", "DataFlowIssue", "NullAway"}) public static Publisher invokeSuspendingFunction( CoroutineContext context, Method method, @Nullable Object target, @Nullable Object... args) { diff --git a/spring-core/src/main/java/org/springframework/util/PlaceholderParser.java b/spring-core/src/main/java/org/springframework/util/PlaceholderParser.java index 4d3c3929dfd3..f354029e4834 100644 --- a/spring-core/src/main/java/org/springframework/util/PlaceholderParser.java +++ b/spring-core/src/main/java/org/springframework/util/PlaceholderParser.java @@ -322,6 +322,7 @@ static class PartResolutionContext implements PlaceholderResolver { } @Override + @Nullable public String resolvePlaceholder(String placeholderName) { String value = this.resolver.resolvePlaceholder(placeholderName); if (value != null && logger.isTraceEnabled()) { @@ -358,6 +359,7 @@ public void flagPlaceholderAsVisited(String placeholder) { } public void removePlaceholder(String placeholder) { + Assert.state(this.visitedPlaceholders != null, "Visited placeholders must not be null"); this.visitedPlaceholders.remove(placeholder); } diff --git a/spring-core/src/main/java/org/springframework/util/StreamUtils.java b/spring-core/src/main/java/org/springframework/util/StreamUtils.java index c9d7035a9d21..38fa26f76460 100644 --- a/spring-core/src/main/java/org/springframework/util/StreamUtils.java +++ b/spring-core/src/main/java/org/springframework/util/StreamUtils.java @@ -25,6 +25,7 @@ import java.io.OutputStream; import java.nio.charset.Charset; +import org.springframework.lang.Contract; import org.springframework.lang.Nullable; /** @@ -201,6 +202,7 @@ else if (bytesRead <= bytesToCopy) { * @throws IOException in case of I/O errors * @since 4.3 */ + @Contract("null -> fail") public static int drain(@Nullable InputStream in) throws IOException { Assert.notNull(in, "No InputStream specified"); return (int) in.transferTo(OutputStream.nullOutputStream()); diff --git a/spring-jms/src/main/java/org/springframework/jms/connection/JmsResourceHolder.java b/spring-jms/src/main/java/org/springframework/jms/connection/JmsResourceHolder.java index 7b43c35152c0..6916fc2e4063 100644 --- a/spring-jms/src/main/java/org/springframework/jms/connection/JmsResourceHolder.java +++ b/spring-jms/src/main/java/org/springframework/jms/connection/JmsResourceHolder.java @@ -222,6 +222,7 @@ public S getSession(Class sessionType) { * for the given connection, or {@code null} if none. */ @Nullable + @SuppressWarnings("NullAway") public S getSession(Class sessionType, @Nullable Connection connection) { Deque sessions = (connection != null ? this.sessionsPerConnection.get(connection) : this.sessions); diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/SimpleMessageListenerContainer.java b/spring-jms/src/main/java/org/springframework/jms/listener/SimpleMessageListenerContainer.java index b7c6121f6fc8..345019392653 100644 --- a/spring-jms/src/main/java/org/springframework/jms/listener/SimpleMessageListenerContainer.java +++ b/spring-jms/src/main/java/org/springframework/jms/listener/SimpleMessageListenerContainer.java @@ -344,6 +344,7 @@ protected MessageConsumer createListenerConsumer(final Session session) throws J * @see #executeListener * @see #setExposeListenerSession */ + @SuppressWarnings("NullAway") protected void processMessage(Message message, Session session) { ConnectionFactory connectionFactory = getConnectionFactory(); boolean exposeResource = (connectionFactory != null && isExposeListenerSession()); diff --git a/spring-messaging/src/main/java/org/springframework/messaging/rsocket/service/RSocketServiceMethod.java b/spring-messaging/src/main/java/org/springframework/messaging/rsocket/service/RSocketServiceMethod.java index e4cf46db7ba3..1b6c87f81746 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/rsocket/service/RSocketServiceMethod.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/rsocket/service/RSocketServiceMethod.java @@ -92,6 +92,7 @@ private static MethodParameter[] initMethodParameters(Method method) { } @Nullable + @SuppressWarnings("NullAway") private static String initRoute( Method method, Class containingClass, RSocketStrategies strategies, @Nullable StringValueResolver embeddedValueResolver) { diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/PersistenceManagedTypesBeanRegistrationAotProcessor.java b/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/PersistenceManagedTypesBeanRegistrationAotProcessor.java index 481b37abea29..e6ac691473b0 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/PersistenceManagedTypesBeanRegistrationAotProcessor.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/PersistenceManagedTypesBeanRegistrationAotProcessor.java @@ -203,6 +203,7 @@ private void contributeHibernateHints(RuntimeHints hints, @Nullable ClassLoader }); } + @SuppressWarnings("NullAway") private void registerInstantiatorForReflection(ReflectionHints reflection, @Nullable Annotation annotation) { if (annotation == null) { return; diff --git a/spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionAspectSupport.java b/spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionAspectSupport.java index 7d8f1c476f80..a02fd664cf9c 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionAspectSupport.java +++ b/spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionAspectSupport.java @@ -409,7 +409,9 @@ protected Object invokeWithinTransaction(Method method, @Nullable Class targe future.get(); } catch (ExecutionException ex) { - if (txAttr.rollbackOn(ex.getCause())) { + Throwable cause = ex.getCause(); + Assert.state(cause != null, "Cause must not be null"); + if (txAttr.rollbackOn(cause)) { status.setRollbackOnly(); } } @@ -901,7 +903,9 @@ public ThrowableHolderException(Throwable throwable) { @Override public String toString() { - return getCause().toString(); + Throwable cause = getCause(); + Assert.state(cause != null, "Cause must not be null"); + return cause.toString(); } } diff --git a/spring-web/src/main/java/org/springframework/http/InvalidMediaTypeException.java b/spring-web/src/main/java/org/springframework/http/InvalidMediaTypeException.java index ec324b8353d0..905e95a0d037 100644 --- a/spring-web/src/main/java/org/springframework/http/InvalidMediaTypeException.java +++ b/spring-web/src/main/java/org/springframework/http/InvalidMediaTypeException.java @@ -16,6 +16,7 @@ package org.springframework.http; +import org.springframework.lang.Nullable; import org.springframework.util.InvalidMimeTypeException; /** @@ -36,8 +37,8 @@ public class InvalidMediaTypeException extends IllegalArgumentException { * @param mediaType the offending media type * @param message a detail message indicating the invalid part */ - public InvalidMediaTypeException(String mediaType, String message) { - super("Invalid media type \"" + mediaType + "\": " + message); + public InvalidMediaTypeException(String mediaType, @Nullable String message) { + super(message != null ? "Invalid media type \"" + mediaType + "\": " + message : "Invalid media type \"" + mediaType); this.mediaType = mediaType; } diff --git a/spring-web/src/main/java/org/springframework/http/RequestEntity.java b/spring-web/src/main/java/org/springframework/http/RequestEntity.java index 364a1373bfa3..d387735f8b7a 100644 --- a/spring-web/src/main/java/org/springframework/http/RequestEntity.java +++ b/spring-web/src/main/java/org/springframework/http/RequestEntity.java @@ -205,8 +205,8 @@ public boolean equals(@Nullable Object other) { if (!super.equals(other)) { return false; } - RequestEntity otherEntity = (RequestEntity) other; - return (ObjectUtils.nullSafeEquals(this.method, otherEntity.method) && + return (other instanceof RequestEntity otherEntity && + ObjectUtils.nullSafeEquals(this.method, otherEntity.method) && ObjectUtils.nullSafeEquals(this.url, otherEntity.url)); } @@ -736,8 +736,8 @@ public boolean equals(@Nullable Object other) { if (!super.equals(other)) { return false; } - UriTemplateRequestEntity otherEntity = (UriTemplateRequestEntity) other; - return (ObjectUtils.nullSafeEquals(this.uriTemplate, otherEntity.uriTemplate) && + return (other instanceof UriTemplateRequestEntity otherEntity && + ObjectUtils.nullSafeEquals(this.uriTemplate, otherEntity.uriTemplate) && ObjectUtils.nullSafeEquals(this.uriVarsArray, otherEntity.uriVarsArray) && ObjectUtils.nullSafeEquals(this.uriVarsMap, otherEntity.uriVarsMap)); } diff --git a/spring-web/src/main/java/org/springframework/http/ResponseEntity.java b/spring-web/src/main/java/org/springframework/http/ResponseEntity.java index 2d60ec47345d..350e11a2aba0 100644 --- a/spring-web/src/main/java/org/springframework/http/ResponseEntity.java +++ b/spring-web/src/main/java/org/springframework/http/ResponseEntity.java @@ -162,8 +162,7 @@ public boolean equals(@Nullable Object other) { if (!super.equals(other)) { return false; } - ResponseEntity otherEntity = (ResponseEntity) other; - return ObjectUtils.nullSafeEquals(this.status, otherEntity.status); + return (other instanceof ResponseEntity otherEntity && ObjectUtils.nullSafeEquals(this.status, otherEntity.status)); } @Override diff --git a/spring-web/src/main/java/org/springframework/http/client/AbstractStreamingClientHttpRequest.java b/spring-web/src/main/java/org/springframework/http/client/AbstractStreamingClientHttpRequest.java index fd0f4fcccf18..fa3ea1dfea4f 100644 --- a/spring-web/src/main/java/org/springframework/http/client/AbstractStreamingClientHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/client/AbstractStreamingClientHttpRequest.java @@ -63,6 +63,7 @@ public final void setBody(Body body) { } @Override + @SuppressWarnings("NullAway") protected final ClientHttpResponse executeInternal(HttpHeaders headers) throws IOException { if (this.body == null && this.bodyStream != null) { this.body = outputStream -> this.bodyStream.writeTo(outputStream); diff --git a/spring-web/src/main/java/org/springframework/http/client/JdkClientHttpRequest.java b/spring-web/src/main/java/org/springframework/http/client/JdkClientHttpRequest.java index 3237f32adc6c..971722b75d89 100644 --- a/spring-web/src/main/java/org/springframework/http/client/JdkClientHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/client/JdkClientHttpRequest.java @@ -90,6 +90,7 @@ public URI getURI() { @Override + @SuppressWarnings("NullAway") protected ClientHttpResponse executeInternal(HttpHeaders headers, @Nullable Body body) throws IOException { try { HttpRequest request = buildRequest(headers, body); diff --git a/spring-web/src/main/java/org/springframework/http/client/JettyClientHttpRequest.java b/spring-web/src/main/java/org/springframework/http/client/JettyClientHttpRequest.java index c8462dda81dc..c846684e4101 100644 --- a/spring-web/src/main/java/org/springframework/http/client/JettyClientHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/client/JettyClientHttpRequest.java @@ -69,6 +69,7 @@ public URI getURI() { } @Override + @SuppressWarnings("NullAway") protected ClientHttpResponse executeInternal(HttpHeaders headers, @Nullable Body body) throws IOException { if (!headers.isEmpty()) { this.request.headers(httpFields -> { diff --git a/spring-web/src/main/java/org/springframework/http/codec/ServerSentEventHttpMessageReader.java b/spring-web/src/main/java/org/springframework/http/codec/ServerSentEventHttpMessageReader.java index f012b9283978..61289b03e927 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/ServerSentEventHttpMessageReader.java +++ b/spring-web/src/main/java/org/springframework/http/codec/ServerSentEventHttpMessageReader.java @@ -138,6 +138,7 @@ public Flux read( } @Nullable + @SuppressWarnings("NullAway") private Object buildEvent(List lines, ResolvableType valueType, boolean shouldWrap, Map hints) { diff --git a/spring-web/src/main/java/org/springframework/http/codec/multipart/MultipartParser.java b/spring-web/src/main/java/org/springframework/http/codec/multipart/MultipartParser.java index e0097c036742..00e35677388e 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/multipart/MultipartParser.java +++ b/spring-web/src/main/java/org/springframework/http/codec/multipart/MultipartParser.java @@ -49,6 +49,7 @@ * @author Arjen Poutsma * @since 5.3 */ +@SuppressWarnings("NullAway") final class MultipartParser extends BaseSubscriber { private static final byte CR = '\r'; @@ -115,6 +116,7 @@ protected void hookOnSubscribe(Subscription subscription) { } @Override + @SuppressWarnings("NullAway") protected void hookOnNext(DataBuffer value) { this.requestOutstanding.set(false); this.state.get().onNext(value); diff --git a/spring-web/src/main/java/org/springframework/http/codec/multipart/PartGenerator.java b/spring-web/src/main/java/org/springframework/http/codec/multipart/PartGenerator.java index 6519b8c7b0d0..cb7b94b8bdb1 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/multipart/PartGenerator.java +++ b/spring-web/src/main/java/org/springframework/http/codec/multipart/PartGenerator.java @@ -57,6 +57,7 @@ * @author Arjen Poutsma * @since 5.3 */ +@SuppressWarnings("NullAway") final class PartGenerator extends BaseSubscriber { private static final Log logger = LogFactory.getLog(PartGenerator.class); diff --git a/spring-web/src/main/java/org/springframework/http/converter/ResourceRegionHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/ResourceRegionHttpMessageConverter.java index 732e2c82e57f..dd6561dd04da 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/ResourceRegionHttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/ResourceRegionHttpMessageConverter.java @@ -167,6 +167,7 @@ protected void writeResourceRegion(ResourceRegion region, HttpOutputMessage outp } } + @SuppressWarnings("NullAway") private void writeResourceRegionCollection(Collection resourceRegions, HttpOutputMessage outputMessage) throws IOException { diff --git a/spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java index 81c7165b5ccc..2fd9f47179f5 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java @@ -329,7 +329,8 @@ protected void logWarningIfNecessary(Type type, @Nullable Throwable cause) { } // Do not log warning for serializer not found (note: different message wording on Jackson 2.9) - boolean debugLevel = (cause instanceof JsonMappingException && cause.getMessage().startsWith("Cannot find")); + boolean debugLevel = (cause instanceof JsonMappingException && cause.getMessage() != null && + cause.getMessage().startsWith("Cannot find")); if (debugLevel ? logger.isDebugEnabled() : logger.isWarnEnabled()) { String msg = "Failed to evaluate Jackson " + (type instanceof JavaType ? "de" : "") + diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractListenerReadPublisher.java b/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractListenerReadPublisher.java index a3753486c35a..72d68e8b052d 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractListenerReadPublisher.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractListenerReadPublisher.java @@ -47,6 +47,7 @@ * @since 5.0 * @param the type of element signaled */ +@SuppressWarnings("NullAway") public abstract class AbstractListenerReadPublisher implements Publisher { /** diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractListenerWriteFlushProcessor.java b/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractListenerWriteFlushProcessor.java index a7665be28708..2392f85ea924 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractListenerWriteFlushProcessor.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractListenerWriteFlushProcessor.java @@ -40,6 +40,7 @@ * @since 5.0 * @param the type of element signaled to the {@link Subscriber} */ +@SuppressWarnings("NullAway") public abstract class AbstractListenerWriteFlushProcessor implements Processor, Void> { /** diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractListenerWriteProcessor.java b/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractListenerWriteProcessor.java index 7e81b6e72b3b..ef9b8976b1b1 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractListenerWriteProcessor.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractListenerWriteProcessor.java @@ -43,6 +43,7 @@ * @since 5.0 * @param the type of element signaled to the {@link Subscriber} */ +@SuppressWarnings("NullAway") public abstract class AbstractListenerWriteProcessor implements Processor { /** diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpRequest.java b/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpRequest.java index 531718eb5c07..fd8fb73524e0 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/ServletServerHttpRequest.java @@ -131,6 +131,7 @@ private static URI initUri(HttpServletRequest request) throws URISyntaxException return new URI(url.toString()); } + @SuppressWarnings("NullAway") private static MultiValueMap initHeaders( MultiValueMap headerValues, HttpServletRequest request) { diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/WriteResultPublisher.java b/spring-web/src/main/java/org/springframework/http/server/reactive/WriteResultPublisher.java index 63ac63dd3557..da41ee1450fa 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/WriteResultPublisher.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/WriteResultPublisher.java @@ -36,6 +36,7 @@ * @author Rossen Stoyanchev * @since 5.0 */ +@SuppressWarnings("NullAway") class WriteResultPublisher implements Publisher { /** diff --git a/spring-web/src/main/java/org/springframework/web/service/invoker/HttpServiceMethod.java b/spring-web/src/main/java/org/springframework/web/service/invoker/HttpServiceMethod.java index 206be4e06be6..1ebf85b41e23 100644 --- a/spring-web/src/main/java/org/springframework/web/service/invoker/HttpServiceMethod.java +++ b/spring-web/src/main/java/org/springframework/web/service/invoker/HttpServiceMethod.java @@ -489,7 +489,9 @@ private static Function> initResponseEntityFunct return request -> client.exchangeForEntityFlux(request, bodyType) .map(entity -> { - Object body = reactiveAdapter.fromPublisher(entity.getBody()); + Flux entityBody = entity.getBody(); + Assert.state(entityBody != null, "Entity body must not be null"); + Object body = reactiveAdapter.fromPublisher(entityBody); return new ResponseEntity<>(body, entity.getHeaders(), entity.getStatusCode()); }); } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerMapping.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerMapping.java index a9c8380bceb9..3b9bdfd6a5ee 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerMapping.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerMapping.java @@ -177,6 +177,7 @@ protected RequestMappingInfo getMappingForMethod(Method method, Class handler if (this.embeddedValueResolver != null) { prefix = this.embeddedValueResolver.resolveStringValue(prefix); } + Assert.state(prefix != null, "Prefix must not be null"); info = RequestMappingInfo.paths(prefix).options(this.config).build().combine(info); break; } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/AbstractMessageConverterMethodArgumentResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/AbstractMessageConverterMethodArgumentResolver.java index a3bfda40648e..f1d65922816f 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/AbstractMessageConverterMethodArgumentResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/AbstractMessageConverterMethodArgumentResolver.java @@ -141,7 +141,7 @@ protected Object readWithMessageConverters(NativeWebRequest webRequest, Meth * @throws HttpMediaTypeNotSupportedException if no suitable message converter is found */ @Nullable - @SuppressWarnings({"rawtypes", "unchecked"}) + @SuppressWarnings({"rawtypes", "unchecked", "NullAway"}) protected Object readWithMessageConverters(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType) throws IOException, HttpMediaTypeNotSupportedException, HttpMessageNotReadableException { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/MessageTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/MessageTag.java index 3744ce0f8ce3..9d700ef2daec 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/MessageTag.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/MessageTag.java @@ -306,6 +306,7 @@ public void release() { * Resolve the specified message into a concrete message String. * The returned message String should be unescaped. */ + @SuppressWarnings("NullAway") protected String resolveMessage() throws JspException, NoSuchMessageException { MessageSource messageSource = getMessageSource();