diff --git a/config/checkstyle/checkstyle-suppressions.xml b/config/checkstyle/checkstyle-suppressions.xml
index 04064bd8a80..d869769c17a 100644
--- a/config/checkstyle/checkstyle-suppressions.xml
+++ b/config/checkstyle/checkstyle-suppressions.xml
@@ -90,4 +90,5 @@
+
diff --git a/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AbstractDependsOnBeanFactoryPostProcessor.java b/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AbstractDependsOnBeanFactoryPostProcessor.java
index dacc47b9716..72128981b80 100644
--- a/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AbstractDependsOnBeanFactoryPostProcessor.java
+++ b/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AbstractDependsOnBeanFactoryPostProcessor.java
@@ -22,6 +22,8 @@ import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
+import org.jspecify.annotations.Nullable;
+
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.FactoryBean;
@@ -50,7 +52,7 @@ public abstract class AbstractDependsOnBeanFactoryPostProcessor implements BeanF
private final Class> beanClass;
- private final Class extends FactoryBean>> factoryBeanClass;
+ private final @Nullable Class extends FactoryBean>> factoryBeanClass;
private final Function> dependsOn;
@@ -61,7 +63,7 @@ public abstract class AbstractDependsOnBeanFactoryPostProcessor implements BeanF
* @param dependsOn dependency names
*/
protected AbstractDependsOnBeanFactoryPostProcessor(Class> beanClass,
- Class extends FactoryBean>> factoryBeanClass, String... dependsOn) {
+ @Nullable Class extends FactoryBean>> factoryBeanClass, String... dependsOn) {
this.beanClass = beanClass;
this.factoryBeanClass = factoryBeanClass;
this.dependsOn = (beanFactory) -> new HashSet<>(Arrays.asList(dependsOn));
@@ -75,7 +77,7 @@ public abstract class AbstractDependsOnBeanFactoryPostProcessor implements BeanF
* @since 2.1.7
*/
protected AbstractDependsOnBeanFactoryPostProcessor(Class> beanClass,
- Class extends FactoryBean>> factoryBeanClass, Class>... dependencyTypes) {
+ @Nullable Class extends FactoryBean>> factoryBeanClass, Class>... dependencyTypes) {
this.beanClass = beanClass;
this.factoryBeanClass = factoryBeanClass;
this.dependsOn = (beanFactory) -> Arrays.stream(dependencyTypes)
diff --git a/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationExcludeFilter.java b/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationExcludeFilter.java
index 088863aeedd..1b6e149dad8 100644
--- a/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationExcludeFilter.java
+++ b/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationExcludeFilter.java
@@ -19,12 +19,15 @@ package org.springframework.boot.autoconfigure;
import java.io.IOException;
import java.util.List;
+import org.jspecify.annotations.Nullable;
+
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.boot.context.annotation.ImportCandidates;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;
+import org.springframework.util.Assert;
/**
* A {@link TypeFilter} implementation that matches registered auto-configuration classes.
@@ -35,9 +38,10 @@ import org.springframework.core.type.filter.TypeFilter;
*/
public class AutoConfigurationExcludeFilter implements TypeFilter, BeanClassLoaderAware {
+ @SuppressWarnings("NullAway.Init")
private ClassLoader beanClassLoader;
- private volatile List autoConfigurations;
+ private volatile @Nullable List autoConfigurations;
@Override
public void setBeanClassLoader(ClassLoader beanClassLoader) {
@@ -66,6 +70,7 @@ public class AutoConfigurationExcludeFilter implements TypeFilter, BeanClassLoad
ImportCandidates importCandidates = ImportCandidates.load(AutoConfiguration.class, this.beanClassLoader);
this.autoConfigurations = importCandidates.getCandidates();
}
+ Assert.state(this.autoConfigurations != null, "'autoConfigurations' must not be null");
return this.autoConfigurations;
}
diff --git a/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationImportFilter.java b/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationImportFilter.java
index 461dd7deb70..4be32042053 100644
--- a/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationImportFilter.java
+++ b/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationImportFilter.java
@@ -16,6 +16,8 @@
package org.springframework.boot.autoconfigure;
+import org.jspecify.annotations.Nullable;
+
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.context.EnvironmentAware;
@@ -54,6 +56,6 @@ public interface AutoConfigurationImportFilter {
* {@code autoConfigurationClasses} parameter. Entries containing {@code false} will
* not be imported.
*/
- boolean[] match(String[] autoConfigurationClasses, AutoConfigurationMetadata autoConfigurationMetadata);
+ boolean[] match(@Nullable String[] autoConfigurationClasses, AutoConfigurationMetadata autoConfigurationMetadata);
}
diff --git a/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java b/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
index a50c408d3bb..da3649626e0 100644
--- a/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
+++ b/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
@@ -32,6 +32,7 @@ import java.util.stream.Collectors;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.jspecify.annotations.Nullable;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.Aware;
@@ -89,23 +90,27 @@ public class AutoConfigurationImportSelector implements DeferredImportSelector,
private final Class> autoConfigurationAnnotation;
+ @SuppressWarnings("NullAway.Init")
private ConfigurableListableBeanFactory beanFactory;
+ @SuppressWarnings("NullAway.Init")
private Environment environment;
+ @SuppressWarnings("NullAway.Init")
private ClassLoader beanClassLoader;
+ @SuppressWarnings("NullAway.Init")
private ResourceLoader resourceLoader;
- private volatile ConfigurationClassFilter configurationClassFilter;
+ private volatile @Nullable ConfigurationClassFilter configurationClassFilter;
- private volatile AutoConfigurationReplacements autoConfigurationReplacements;
+ private volatile @Nullable AutoConfigurationReplacements autoConfigurationReplacements;
public AutoConfigurationImportSelector() {
this(null);
}
- AutoConfigurationImportSelector(Class> autoConfigurationAnnotation) {
+ AutoConfigurationImportSelector(@Nullable Class> autoConfigurationAnnotation) {
this.autoConfigurationAnnotation = (autoConfigurationAnnotation != null) ? autoConfigurationAnnotation
: AutoConfiguration.class;
}
@@ -168,7 +173,7 @@ public class AutoConfigurationImportSelector implements DeferredImportSelector,
* @param metadata the annotation metadata
* @return annotation attributes
*/
- protected AnnotationAttributes getAttributes(AnnotationMetadata metadata) {
+ protected @Nullable AnnotationAttributes getAttributes(AnnotationMetadata metadata) {
String name = getAnnotationClass().getName();
AnnotationAttributes attributes = AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(name, true));
Assert.state(attributes != null, () -> "No auto-configuration attributes found. Is " + metadata.getClassName()
@@ -192,7 +197,8 @@ public class AutoConfigurationImportSelector implements DeferredImportSelector,
* attributes}
* @return a list of candidate configurations
*/
- protected List getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
+ protected List getCandidateConfigurations(AnnotationMetadata metadata,
+ @Nullable AnnotationAttributes attributes) {
ImportCandidates importCandidates = ImportCandidates.load(this.autoConfigurationAnnotation,
getBeanClassLoader());
List configurations = importCandidates.getCandidates();
@@ -237,10 +243,12 @@ public class AutoConfigurationImportSelector implements DeferredImportSelector,
* attributes}
* @return exclusions or an empty set
*/
- protected Set getExclusions(AnnotationMetadata metadata, AnnotationAttributes attributes) {
+ protected Set getExclusions(AnnotationMetadata metadata, @Nullable AnnotationAttributes attributes) {
Set excluded = new LinkedHashSet<>();
- excluded.addAll(asList(attributes, "exclude"));
- excluded.addAll(asList(attributes, "excludeName"));
+ if (attributes != null) {
+ excluded.addAll(asList(attributes, "exclude"));
+ excluded.addAll(asList(attributes, "excludeName"));
+ }
excluded.addAll(getExcludeAutoConfigurationsProperty());
return getAutoConfigurationReplacements().replaceAll(excluded);
}
@@ -389,7 +397,7 @@ public class AutoConfigurationImportSelector implements DeferredImportSelector,
List filter(List configurations) {
long startTime = System.nanoTime();
- String[] candidates = StringUtils.toStringArray(configurations);
+ @Nullable String[] candidates = StringUtils.toStringArray(configurations);
boolean skipped = false;
for (AutoConfigurationImportFilter filter : this.filters) {
boolean[] match = filter.match(candidates, this.autoConfigurationMetadata);
@@ -426,15 +434,18 @@ public class AutoConfigurationImportSelector implements DeferredImportSelector,
private final List autoConfigurationEntries = new ArrayList<>();
+ @SuppressWarnings("NullAway.Init")
private ClassLoader beanClassLoader;
+ @SuppressWarnings("NullAway.Init")
private BeanFactory beanFactory;
+ @SuppressWarnings("NullAway.Init")
private ResourceLoader resourceLoader;
- private AutoConfigurationMetadata autoConfigurationMetadata;
+ private @Nullable AutoConfigurationMetadata autoConfigurationMetadata;
- private AutoConfigurationReplacements autoConfigurationReplacements;
+ private @Nullable AutoConfigurationReplacements autoConfigurationReplacements;
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
@@ -488,10 +499,16 @@ public class AutoConfigurationImportSelector implements DeferredImportSelector,
.collect(Collectors.toCollection(LinkedHashSet::new));
processedConfigurations.removeAll(allExclusions);
return sortAutoConfigurations(processedConfigurations, getAutoConfigurationMetadata()).stream()
- .map((importClassName) -> new Entry(this.entries.get(importClassName), importClassName))
+ .map(this::getEntry)
.toList();
}
+ private Entry getEntry(String importClassName) {
+ AnnotationMetadata metadata = this.entries.get(importClassName);
+ Assert.state(metadata != null, "'metadata' must not be null");
+ return new Entry(metadata, importClassName);
+ }
+
private AutoConfigurationMetadata getAutoConfigurationMetadata() {
if (this.autoConfigurationMetadata == null) {
this.autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
@@ -501,6 +518,8 @@ public class AutoConfigurationImportSelector implements DeferredImportSelector,
private List sortAutoConfigurations(Set configurations,
AutoConfigurationMetadata autoConfigurationMetadata) {
+ Assert.state(this.autoConfigurationReplacements != null,
+ "'autoConfigurationReplacements' must not be null");
return new AutoConfigurationSorter(getMetadataReaderFactory(), autoConfigurationMetadata,
this.autoConfigurationReplacements::replace)
.getInPriorityOrder(configurations);
diff --git a/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationMetadata.java b/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationMetadata.java
index 6f094590ef4..5a8d52a8268 100644
--- a/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationMetadata.java
+++ b/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationMetadata.java
@@ -18,6 +18,10 @@ package org.springframework.boot.autoconfigure;
import java.util.Set;
+import org.jspecify.annotations.Nullable;
+
+import org.springframework.lang.Contract;
+
/**
* Provides access to meta-data written by the auto-configure annotation processor.
*
@@ -40,7 +44,7 @@ public interface AutoConfigurationMetadata {
* @param key the meta-data key
* @return the meta-data value or {@code null}
*/
- Integer getInteger(String className, String key);
+ @Nullable Integer getInteger(String className, String key);
/**
* Get an {@link Integer} value from the meta-data.
@@ -49,7 +53,8 @@ public interface AutoConfigurationMetadata {
* @param defaultValue the default value
* @return the meta-data value or {@code defaultValue}
*/
- Integer getInteger(String className, String key, Integer defaultValue);
+ @Contract("_, _, !null -> !null")
+ @Nullable Integer getInteger(String className, String key, @Nullable Integer defaultValue);
/**
* Get a {@link Set} value from the meta-data.
@@ -57,7 +62,7 @@ public interface AutoConfigurationMetadata {
* @param key the meta-data key
* @return the meta-data value or {@code null}
*/
- Set getSet(String className, String key);
+ @Nullable Set getSet(String className, String key);
/**
* Get a {@link Set} value from the meta-data.
@@ -66,7 +71,8 @@ public interface AutoConfigurationMetadata {
* @param defaultValue the default value
* @return the meta-data value or {@code defaultValue}
*/
- Set getSet(String className, String key, Set defaultValue);
+ @Contract("_, _, !null -> !null")
+ @Nullable Set getSet(String className, String key, @Nullable Set defaultValue);
/**
* Get an {@link String} value from the meta-data.
@@ -74,7 +80,7 @@ public interface AutoConfigurationMetadata {
* @param key the meta-data key
* @return the meta-data value or {@code null}
*/
- String get(String className, String key);
+ @Nullable String get(String className, String key);
/**
* Get an {@link String} value from the meta-data.
@@ -83,6 +89,7 @@ public interface AutoConfigurationMetadata {
* @param defaultValue the default value
* @return the meta-data value or {@code defaultValue}
*/
- String get(String className, String key, String defaultValue);
+ @Contract("_, _, !null -> !null")
+ @Nullable String get(String className, String key, @Nullable String defaultValue);
}
diff --git a/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationMetadataLoader.java b/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationMetadataLoader.java
index 60511c07b74..9c1a004f7d4 100644
--- a/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationMetadataLoader.java
+++ b/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationMetadataLoader.java
@@ -22,6 +22,8 @@ import java.util.Enumeration;
import java.util.Properties;
import java.util.Set;
+import org.jspecify.annotations.Nullable;
+
import org.springframework.core.io.UrlResource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.util.StringUtils;
@@ -42,7 +44,7 @@ final class AutoConfigurationMetadataLoader {
return loadMetadata(classLoader, PATH);
}
- static AutoConfigurationMetadata loadMetadata(ClassLoader classLoader, String path) {
+ static AutoConfigurationMetadata loadMetadata(@Nullable ClassLoader classLoader, String path) {
try {
Enumeration urls = (classLoader != null) ? classLoader.getResources(path)
: ClassLoader.getSystemResources(path);
@@ -78,34 +80,34 @@ final class AutoConfigurationMetadataLoader {
}
@Override
- public Integer getInteger(String className, String key) {
+ public @Nullable Integer getInteger(String className, String key) {
return getInteger(className, key, null);
}
@Override
- public Integer getInteger(String className, String key, Integer defaultValue) {
+ public @Nullable Integer getInteger(String className, String key, @Nullable Integer defaultValue) {
String value = get(className, key);
return (value != null) ? Integer.valueOf(value) : defaultValue;
}
@Override
- public Set getSet(String className, String key) {
+ public @Nullable Set getSet(String className, String key) {
return getSet(className, key, null);
}
@Override
- public Set getSet(String className, String key, Set defaultValue) {
+ public @Nullable Set getSet(String className, String key, @Nullable Set defaultValue) {
String value = get(className, key);
return (value != null) ? StringUtils.commaDelimitedListToSet(value) : defaultValue;
}
@Override
- public String get(String className, String key) {
+ public @Nullable String get(String className, String key) {
return get(className, key, null);
}
@Override
- public String get(String className, String key, String defaultValue) {
+ public @Nullable String get(String className, String key, @Nullable String defaultValue) {
String value = this.properties.getProperty(className + "." + key);
return (value != null) ? value : defaultValue;
}
diff --git a/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationPackages.java b/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationPackages.java
index cc4125784b3..70d1ce680c8 100644
--- a/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationPackages.java
+++ b/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationPackages.java
@@ -30,12 +30,14 @@ import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConstructorArgumentValues;
+import org.springframework.beans.factory.config.ConstructorArgumentValues.ValueHolder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.boot.context.annotation.DeterminableImports;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
+import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
@@ -105,8 +107,9 @@ public abstract class AutoConfigurationPackages {
private static void addBasePackages(BeanDefinition beanDefinition, String[] additionalBasePackages) {
ConstructorArgumentValues constructorArgumentValues = beanDefinition.getConstructorArgumentValues();
if (constructorArgumentValues.hasIndexedArgumentValue(0)) {
- String[] existingPackages = (String[]) constructorArgumentValues.getIndexedArgumentValue(0, String[].class)
- .getValue();
+ ValueHolder indexedArgumentValue = constructorArgumentValues.getIndexedArgumentValue(0, String[].class);
+ Assert.state(indexedArgumentValue != null, "'indexedArgumentValue' must not be null");
+ String[] existingPackages = (String[]) indexedArgumentValue.getValue();
constructorArgumentValues.addIndexedArgumentValue(0,
Stream.concat(Stream.of(existingPackages), Stream.of(additionalBasePackages))
.distinct()
@@ -145,6 +148,7 @@ public abstract class AutoConfigurationPackages {
PackageImports(AnnotationMetadata metadata) {
AnnotationAttributes attributes = AnnotationAttributes
.fromMap(metadata.getAnnotationAttributes(AutoConfigurationPackage.class.getName(), false));
+ Assert.state(attributes != null, "'attributes' must not be null");
List packageNames = new ArrayList<>(Arrays.asList(attributes.getStringArray("basePackages")));
for (Class> basePackageClass : attributes.getClassArray("basePackageClasses")) {
packageNames.add(basePackageClass.getPackage().getName());
diff --git a/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationReplacements.java b/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationReplacements.java
index 661811676f8..043ccb0fee9 100644
--- a/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationReplacements.java
+++ b/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationReplacements.java
@@ -28,6 +28,8 @@ import java.util.Map;
import java.util.Properties;
import java.util.Set;
+import org.jspecify.annotations.Nullable;
+
import org.springframework.boot.context.annotation.ImportCandidates;
import org.springframework.core.io.UrlResource;
import org.springframework.util.Assert;
@@ -88,7 +90,7 @@ final class AutoConfigurationReplacements {
* @param classLoader class loader to use for loading
* @return list of names of annotated classes
*/
- static AutoConfigurationReplacements load(Class> annotation, ClassLoader classLoader) {
+ static AutoConfigurationReplacements load(Class> annotation, @Nullable ClassLoader classLoader) {
Assert.notNull(annotation, "'annotation' must not be null");
ClassLoader classLoaderToUse = decideClassloader(classLoader);
String location = String.format(LOCATION, annotation.getName());
@@ -101,7 +103,7 @@ final class AutoConfigurationReplacements {
return new AutoConfigurationReplacements(replacements);
}
- private static ClassLoader decideClassloader(ClassLoader classLoader) {
+ private static ClassLoader decideClassloader(@Nullable ClassLoader classLoader) {
if (classLoader == null) {
return ImportCandidates.class.getClassLoader();
}
diff --git a/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationSorter.java b/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationSorter.java
index 812e3cb7d48..8a53a351844 100644
--- a/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationSorter.java
+++ b/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigurationSorter.java
@@ -30,6 +30,8 @@ import java.util.Set;
import java.util.TreeSet;
import java.util.function.UnaryOperator;
+import org.jspecify.annotations.Nullable;
+
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
@@ -47,12 +49,13 @@ class AutoConfigurationSorter {
private final MetadataReaderFactory metadataReaderFactory;
- private final AutoConfigurationMetadata autoConfigurationMetadata;
+ private final @Nullable AutoConfigurationMetadata autoConfigurationMetadata;
- private final UnaryOperator replacementMapper;
+ private final @Nullable UnaryOperator replacementMapper;
AutoConfigurationSorter(MetadataReaderFactory metadataReaderFactory,
- AutoConfigurationMetadata autoConfigurationMetadata, UnaryOperator replacementMapper) {
+ @Nullable AutoConfigurationMetadata autoConfigurationMetadata,
+ @Nullable UnaryOperator replacementMapper) {
Assert.notNull(metadataReaderFactory, "'metadataReaderFactory' must not be null");
this.metadataReaderFactory = metadataReaderFactory;
this.autoConfigurationMetadata = autoConfigurationMetadata;
@@ -91,7 +94,7 @@ class AutoConfigurationSorter {
}
private void doSortByAfterAnnotation(AutoConfigurationClasses classes, List toSort, Set sorted,
- Set processing, String current) {
+ Set processing, @Nullable String current) {
if (current == null) {
current = toSort.remove(0);
}
@@ -118,7 +121,7 @@ class AutoConfigurationSorter {
private final Map classes = new LinkedHashMap<>();
AutoConfigurationClasses(MetadataReaderFactory metadataReaderFactory,
- AutoConfigurationMetadata autoConfigurationMetadata, Collection classNames) {
+ @Nullable AutoConfigurationMetadata autoConfigurationMetadata, Collection classNames) {
addToClasses(metadataReaderFactory, autoConfigurationMetadata, classNames, true);
}
@@ -127,7 +130,8 @@ class AutoConfigurationSorter {
}
private void addToClasses(MetadataReaderFactory metadataReaderFactory,
- AutoConfigurationMetadata autoConfigurationMetadata, Collection classNames, boolean required) {
+ @Nullable AutoConfigurationMetadata autoConfigurationMetadata, Collection classNames,
+ boolean required) {
for (String className : classNames) {
if (!this.classes.containsKey(className)) {
AutoConfigurationClass autoConfigurationClass = new AutoConfigurationClass(className,
@@ -147,7 +151,9 @@ class AutoConfigurationSorter {
}
AutoConfigurationClass get(String className) {
- return this.classes.get(className);
+ AutoConfigurationClass autoConfigurationClass = this.classes.get(className);
+ Assert.state(autoConfigurationClass != null, "'autoConfigurationClass' must not be null");
+ return autoConfigurationClass;
}
Set getClassesRequestedAfter(String className) {
@@ -168,16 +174,16 @@ class AutoConfigurationSorter {
private final MetadataReaderFactory metadataReaderFactory;
- private final AutoConfigurationMetadata autoConfigurationMetadata;
+ private final @Nullable AutoConfigurationMetadata autoConfigurationMetadata;
- private volatile AnnotationMetadata annotationMetadata;
+ private volatile @Nullable AnnotationMetadata annotationMetadata;
- private volatile Set before;
+ private volatile @Nullable Set before;
- private volatile Set after;
+ private volatile @Nullable Set after;
AutoConfigurationClass(String className, MetadataReaderFactory metadataReaderFactory,
- AutoConfigurationMetadata autoConfigurationMetadata) {
+ @Nullable AutoConfigurationMetadata autoConfigurationMetadata) {
this.className = className;
this.metadataReaderFactory = metadataReaderFactory;
this.autoConfigurationMetadata = autoConfigurationMetadata;
@@ -210,12 +216,15 @@ class AutoConfigurationSorter {
}
private Set getClassNames(String metadataKey, Class extends Annotation> annotation) {
- Set annotationValue = wasProcessed()
- ? this.autoConfigurationMetadata.getSet(this.className, metadataKey, Collections.emptySet())
- : getAnnotationValue(annotation);
+ Set annotationValue = wasProcessed() ? getSet(metadataKey) : getAnnotationValue(annotation);
return applyReplacements(annotationValue);
}
+ private Set getSet(String metadataKey) {
+ Assert.state(this.autoConfigurationMetadata != null, "'autoConfigurationMetadata' must not be null");
+ return this.autoConfigurationMetadata.getSet(this.className, metadataKey, Collections.emptySet());
+ }
+
private Set applyReplacements(Set values) {
if (AutoConfigurationSorter.this.replacementMapper == null) {
return values;
@@ -229,10 +238,11 @@ class AutoConfigurationSorter {
private int getOrder() {
if (wasProcessed()) {
+ Assert.state(this.autoConfigurationMetadata != null, "'autoConfigurationMetadata' must not be null");
return this.autoConfigurationMetadata.getInteger(this.className, "AutoConfigureOrder",
AutoConfigureOrder.DEFAULT_ORDER);
}
- Map attributes = getAnnotationMetadata()
+ Map attributes = getAnnotationMetadata()
.getAnnotationAttributes(AutoConfigureOrder.class.getName());
return (attributes != null) ? (Integer) attributes.get("value") : AutoConfigureOrder.DEFAULT_ORDER;
}
@@ -243,8 +253,8 @@ class AutoConfigurationSorter {
}
private Set getAnnotationValue(Class> annotation) {
- Map attributes = getAnnotationMetadata().getAnnotationAttributes(annotation.getName(),
- true);
+ Map attributes = getAnnotationMetadata()
+ .getAnnotationAttributes(annotation.getName(), true);
if (attributes == null) {
return Collections.emptySet();
}
diff --git a/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ImportAutoConfigurationImportSelector.java b/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ImportAutoConfigurationImportSelector.java
index 5e0ea6a5037..90a74d3da6e 100644
--- a/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ImportAutoConfigurationImportSelector.java
+++ b/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ImportAutoConfigurationImportSelector.java
@@ -28,6 +28,8 @@ import java.util.Map;
import java.util.Objects;
import java.util.Set;
+import org.jspecify.annotations.Nullable;
+
import org.springframework.boot.context.annotation.DeterminableImports;
import org.springframework.boot.context.annotation.ImportCandidates;
import org.springframework.core.annotation.AnnotatedElementUtils;
@@ -71,12 +73,13 @@ class ImportAutoConfigurationImportSelector extends AutoConfigurationImportSelec
}
@Override
- protected AnnotationAttributes getAttributes(AnnotationMetadata metadata) {
+ protected @Nullable AnnotationAttributes getAttributes(AnnotationMetadata metadata) {
return null;
}
@Override
- protected List getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
+ protected List getCandidateConfigurations(AnnotationMetadata metadata,
+ @Nullable AnnotationAttributes attributes) {
List candidates = new ArrayList<>();
Map, List> annotations = getAnnotations(metadata);
annotations.forEach(
@@ -93,13 +96,13 @@ class ImportAutoConfigurationImportSelector extends AutoConfigurationImportSelec
private Collection getConfigurationsForAnnotation(Class> source, Annotation annotation) {
String[] classes = (String[]) AnnotationUtils.getAnnotationAttributes(annotation, true).get("classes");
- if (classes.length > 0) {
+ if (classes != null && classes.length > 0) {
return Arrays.asList(classes);
}
return loadFactoryNames(source).stream().map(this::mapFactoryName).filter(Objects::nonNull).toList();
}
- private String mapFactoryName(String name) {
+ private @Nullable String mapFactoryName(String name) {
if (!name.startsWith(OPTIONAL_PREFIX)) {
return name;
}
@@ -117,7 +120,7 @@ class ImportAutoConfigurationImportSelector extends AutoConfigurationImportSelec
}
@Override
- protected Set getExclusions(AnnotationMetadata metadata, AnnotationAttributes attributes) {
+ protected Set getExclusions(AnnotationMetadata metadata, @Nullable AnnotationAttributes attributes) {
Set exclusions = new LinkedHashSet<>();
Class> source = ClassUtils.resolveClassName(metadata.getClassName(), getBeanClassLoader());
for (String annotationName : ANNOTATION_NAMES) {
@@ -148,7 +151,7 @@ class ImportAutoConfigurationImportSelector extends AutoConfigurationImportSelec
return Collections.unmodifiableMap(annotations);
}
- private void collectAnnotations(Class> source, MultiValueMap, Annotation> annotations,
+ private void collectAnnotations(@Nullable Class> source, MultiValueMap, Annotation> annotations,
HashSet> seen) {
if (source != null && seen.add(source)) {
for (Annotation annotation : source.getDeclaredAnnotations()) {
diff --git a/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/SharedMetadataReaderFactoryContextInitializer.java b/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/SharedMetadataReaderFactoryContextInitializer.java
index 9b7bd1a8743..69168d5198f 100644
--- a/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/SharedMetadataReaderFactoryContextInitializer.java
+++ b/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/SharedMetadataReaderFactoryContextInitializer.java
@@ -191,6 +191,7 @@ class SharedMetadataReaderFactoryContextInitializer implements
implements FactoryBean, ResourceLoaderAware,
ApplicationListener {
+ @SuppressWarnings("NullAway.Init")
private ConcurrentReferenceCachingMetadataReaderFactory metadataReaderFactory;
@Override
diff --git a/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/admin/package-info.java b/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/admin/package-info.java
index 405a872c26d..986580bcb10 100644
--- a/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/admin/package-info.java
+++ b/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/admin/package-info.java
@@ -17,4 +17,7 @@
/**
* Auto-configuration for admin-related features.
*/
+@NullMarked
package org.springframework.boot.autoconfigure.admin;
+
+import org.jspecify.annotations.NullMarked;
diff --git a/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/aop/package-info.java b/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/aop/package-info.java
index 3957906d487..7994bf1ad96 100644
--- a/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/aop/package-info.java
+++ b/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/aop/package-info.java
@@ -17,4 +17,7 @@
/**
* Auto-configuration for Spring AOP.
*/
+@NullMarked
package org.springframework.boot.autoconfigure.aop;
+
+import org.jspecify.annotations.NullMarked;
diff --git a/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/availability/package-info.java b/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/availability/package-info.java
index c582a49861c..173e0ef2fc5 100644
--- a/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/availability/package-info.java
+++ b/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/availability/package-info.java
@@ -17,4 +17,7 @@
/**
* Auto-configuration for application availability features.
*/
+@NullMarked
package org.springframework.boot.autoconfigure.availability;
+
+import org.jspecify.annotations.NullMarked;
diff --git a/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/package-info.java b/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/package-info.java
index 9eaa0a0d7b5..814ca355e61 100644
--- a/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/package-info.java
+++ b/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/package-info.java
@@ -17,4 +17,7 @@
/**
* Auto-configuration base classes for Caching support.
*/
+@NullMarked
package org.springframework.boot.autoconfigure.cache;
+
+import org.jspecify.annotations.NullMarked;
diff --git a/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/AbstractNestedCondition.java b/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/AbstractNestedCondition.java
index 72260a56630..38e507e2612 100644
--- a/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/AbstractNestedCondition.java
+++ b/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/AbstractNestedCondition.java
@@ -22,6 +22,8 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
+import org.jspecify.annotations.Nullable;
+
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
@@ -153,8 +155,8 @@ public abstract class AbstractNestedCondition extends SpringBootCondition implem
@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/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionEvaluationReport.java b/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionEvaluationReport.java
index 8e019d0f88f..1a4780c3ec5 100644
--- a/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionEvaluationReport.java
+++ b/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionEvaluationReport.java
@@ -30,6 +30,8 @@ import java.util.TreeMap;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
+import org.jspecify.annotations.Nullable;
+
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.annotation.Condition;
@@ -58,7 +60,7 @@ public final class ConditionEvaluationReport {
private boolean addedAncestorOutcomes;
- private ConditionEvaluationReport parent;
+ private @Nullable ConditionEvaluationReport parent;
private final List exclusions = new ArrayList<>();
@@ -154,7 +156,7 @@ public final class ConditionEvaluationReport {
* The parent report (from a parent BeanFactory if there is one).
* @return the parent report (or null if there isn't one)
*/
- public ConditionEvaluationReport getParent() {
+ public @Nullable ConditionEvaluationReport getParent() {
return this.parent;
}
@@ -164,7 +166,7 @@ public final class ConditionEvaluationReport {
* @param beanFactory the bean factory (may be {@code null})
* @return the {@link ConditionEvaluationReport} or {@code null}
*/
- public static ConditionEvaluationReport find(BeanFactory beanFactory) {
+ public static @Nullable ConditionEvaluationReport find(BeanFactory beanFactory) {
if (beanFactory instanceof ConfigurableListableBeanFactory) {
return ConditionEvaluationReport.get((ConfigurableListableBeanFactory) beanFactory);
}
@@ -191,7 +193,7 @@ public final class ConditionEvaluationReport {
}
}
- private static void locateParent(BeanFactory beanFactory, ConditionEvaluationReport report) {
+ private static void locateParent(@Nullable BeanFactory beanFactory, ConditionEvaluationReport report) {
if (beanFactory != null && report.parent == null && beanFactory.containsBean(BEAN_NAME)) {
report.parent = beanFactory.getBean(BEAN_NAME, ConditionEvaluationReport.class);
}
diff --git a/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionEvaluationReportAutoConfigurationImportListener.java b/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionEvaluationReportAutoConfigurationImportListener.java
index 948b9f7ae0e..6c278172901 100644
--- a/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionEvaluationReportAutoConfigurationImportListener.java
+++ b/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionEvaluationReportAutoConfigurationImportListener.java
@@ -16,6 +16,8 @@
package org.springframework.boot.autoconfigure.condition;
+import org.jspecify.annotations.Nullable;
+
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
@@ -32,7 +34,7 @@ import org.springframework.boot.autoconfigure.AutoConfigurationImportListener;
class ConditionEvaluationReportAutoConfigurationImportListener
implements AutoConfigurationImportListener, BeanFactoryAware {
- private ConfigurableListableBeanFactory beanFactory;
+ private @Nullable ConfigurableListableBeanFactory beanFactory;
@Override
public void onAutoConfigurationImportEvent(AutoConfigurationImportEvent event) {
diff --git a/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionMessage.java b/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionMessage.java
index 2d63a1f7dff..fd04817c106 100644
--- a/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionMessage.java
+++ b/core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionMessage.java
@@ -23,6 +23,8 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
+import org.jspecify.annotations.Nullable;
+
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
@@ -38,13 +40,13 @@ import org.springframework.util.StringUtils;
*/
public final class ConditionMessage {
- private final String message;
+ private final @Nullable String message;
private ConditionMessage() {
this(null);
}
- private ConditionMessage(String message) {
+ private ConditionMessage(@Nullable String message) {
this.message = message;
}
@@ -87,7 +89,7 @@ public final class ConditionMessage {
* @param message the message to append
* @return a new {@link ConditionMessage} instance
*/
- public ConditionMessage append(String message) {
+ public ConditionMessage append(@Nullable String message) {
if (!StringUtils.hasLength(message)) {
return this;
}
@@ -158,7 +160,7 @@ public final class ConditionMessage {
* @param messages the source messages (may be {@code null})
* @return a new {@link ConditionMessage} instance
*/
- public static ConditionMessage of(Collection extends ConditionMessage> messages) {
+ public static ConditionMessage of(@Nullable Collection extends ConditionMessage> messages) {
ConditionMessage result = new ConditionMessage();
if (messages != null) {
for (ConditionMessage message : messages) {
@@ -296,7 +298,7 @@ public final class ConditionMessage {
* @param reason the reason for the message
* @return a built {@link ConditionMessage}
*/
- public ConditionMessage because(String reason) {
+ public ConditionMessage because(@Nullable String reason) {
if (StringUtils.hasLength(reason)) {
return new ConditionMessage(ConditionMessage.this,
StringUtils.hasLength(this.condition) ? this.condition + " " + reason : reason);
@@ -343,7 +345,7 @@ public final class ConditionMessage {
* @param items the items (may be {@code null})
* @return a built {@link ConditionMessage}
*/
- public ConditionMessage items(Object... items) {
+ public ConditionMessage items(Object @Nullable ... items) {
return items(Style.NORMAL, items);
}
@@ -355,7 +357,7 @@ public final class ConditionMessage {
* @param items the items (may be {@code null})
* @return a built {@link ConditionMessage}
*/
- public ConditionMessage items(Style style, Object... items) {
+ public ConditionMessage items(Style style, Object @Nullable ... items) {
return items(style, (items != null) ? Arrays.asList(items) : null);
}
@@ -366,7 +368,7 @@ public final class ConditionMessage {
* @param items the source of the items (may be {@code null})
* @return a built {@link ConditionMessage}
*/
- public ConditionMessage items(Collection> items) {
+ public ConditionMessage items(@Nullable Collection> items) {
return items(Style.NORMAL, items);
}
@@ -378,7 +380,7 @@ public final class ConditionMessage {
* @param items the source of the items (may be {@code null})
* @return a built {@link ConditionMessage}
*/
- public ConditionMessage items(Style style, Collection> items) {
+ public ConditionMessage items(Style style, @Nullable Collection> items) {
Assert.notNull(style, "'style' must not be null");
StringBuilder message = new StringBuilder(this.reason);
items = style.applyTo(items);
@@ -408,7 +410,7 @@ public final class ConditionMessage {
NORMAL {
@Override
- protected Object applyToItem(Object item) {
+ protected @Nullable Object applyToItem(@Nullable Object item) {
return item;
}
@@ -420,24 +422,27 @@ public final class ConditionMessage {
QUOTE {
@Override
- protected String applyToItem(Object item) {
+ protected @Nullable String applyToItem(@Nullable Object item) {
return (item != null) ? "'" + item + "'" : null;
}
};
- public Collection> applyTo(Collection> items) {
+ public @Nullable Collection> applyTo(@Nullable Collection> items) {
if (items == null) {
return null;
}
List