Skip to content

Commit 1b3e9e6

Browse files
committed
Add nullability annotations to core/spring-boot
See gh-46587
1 parent adee697 commit 1b3e9e6

File tree

368 files changed

+2706
-1616
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

368 files changed

+2706
-1616
lines changed

config/checkstyle/checkstyle-suppressions.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,4 +86,8 @@
8686
<suppress files="ConfigurationPropertyCaching\.java" checks="SpringJavadoc" message="\@since"/>
8787
<suppress files="StructuredLoggingJsonMembersCustomizer\.java" checks="SpringJavadoc" message="\@since"/>
8888
<suppress files="FieldValues\.java" checks="SimplifyBooleanExpression" />
89+
<!-- jspecify: https://github.com/spring-io/spring-javaformat/issues/454 -->
90+
<suppress files="PemPrivateKeyParser\.java" checks="NoWhitespaceBefore" message="'...' is preceded with whitespace"/>
91+
<suppress files="Bindable\.java" checks="NoWhitespaceBefore" message="'...' is preceded with whitespace"/>
92+
<suppress files="LambdaSafe\.java" checks="NoWhitespaceBefore" message="'...' is preceded with whitespace"/>
8993
</suppressions>

core/spring-boot/src/main/java/org/springframework/boot/ApplicationArguments.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import java.util.List;
2020
import java.util.Set;
2121

22+
import org.jspecify.annotations.Nullable;
23+
2224
/**
2325
* Provides access to the arguments that were used to run a {@link SpringApplication}.
2426
*
@@ -63,7 +65,7 @@ public interface ApplicationArguments {
6365
* @param name the name of the option
6466
* @return a list of option values for the given name
6567
*/
66-
List<String> getOptionValues(String name);
68+
@Nullable List<String> getOptionValues(String name);
6769

6870
/**
6971
* Return the collection of non-option arguments parsed.

core/spring-boot/src/main/java/org/springframework/boot/ApplicationContextFactory.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
import java.util.function.Supplier;
2020

21+
import org.jspecify.annotations.Nullable;
22+
2123
import org.springframework.beans.BeanUtils;
2224
import org.springframework.context.ConfigurableApplicationContext;
2325
import org.springframework.core.env.ConfigurableEnvironment;
@@ -46,11 +48,12 @@ public interface ApplicationContextFactory {
4648
* Return the {@link Environment} type expected to be set on the
4749
* {@link #create(WebApplicationType) created} application context. The result of this
4850
* method can be used to convert an existing environment instance to the correct type.
49-
* @param webApplicationType the web application type
51+
* @param webApplicationType the web application type or {@code null}
5052
* @return the expected application context type or {@code null} to use the default
5153
* @since 2.6.14
5254
*/
53-
default Class<? extends ConfigurableEnvironment> getEnvironmentType(WebApplicationType webApplicationType) {
55+
default @Nullable Class<? extends ConfigurableEnvironment> getEnvironmentType(
56+
@Nullable WebApplicationType webApplicationType) {
5457
return null;
5558
}
5659

@@ -59,11 +62,11 @@ default Class<? extends ConfigurableEnvironment> getEnvironmentType(WebApplicati
5962
* {@link #create(WebApplicationType) created} application context. The result of this
6063
* method must match the type returned by
6164
* {@link #getEnvironmentType(WebApplicationType)}.
62-
* @param webApplicationType the web application type
65+
* @param webApplicationType the web application type or {@code null}
6366
* @return an environment instance or {@code null} to use the default
6467
* @since 2.6.14
6568
*/
66-
default ConfigurableEnvironment createEnvironment(WebApplicationType webApplicationType) {
69+
default @Nullable ConfigurableEnvironment createEnvironment(@Nullable WebApplicationType webApplicationType) {
6770
return null;
6871
}
6972

@@ -73,7 +76,7 @@ default ConfigurableEnvironment createEnvironment(WebApplicationType webApplicat
7376
* @param webApplicationType the web application type
7477
* @return the newly created application context
7578
*/
76-
ConfigurableApplicationContext create(WebApplicationType webApplicationType);
79+
ConfigurableApplicationContext create(@Nullable WebApplicationType webApplicationType);
7780

7881
/**
7982
* Creates an {@code ApplicationContextFactory} that will create contexts by

core/spring-boot/src/main/java/org/springframework/boot/ApplicationEnvironment.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package org.springframework.boot;
1818

19+
import org.jspecify.annotations.Nullable;
20+
1921
import org.springframework.boot.context.properties.source.ConfigurationPropertySources;
2022
import org.springframework.core.env.ConfigurablePropertyResolver;
2123
import org.springframework.core.env.MutablePropertySources;
@@ -29,12 +31,12 @@
2931
class ApplicationEnvironment extends StandardEnvironment {
3032

3133
@Override
32-
protected String doGetActiveProfilesProperty() {
34+
protected @Nullable String doGetActiveProfilesProperty() {
3335
return null;
3436
}
3537

3638
@Override
37-
protected String doGetDefaultProfilesProperty() {
39+
protected @Nullable String doGetDefaultProfilesProperty() {
3840
return null;
3941
}
4042

core/spring-boot/src/main/java/org/springframework/boot/ApplicationInfoPropertySource.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import java.util.HashMap;
2020
import java.util.Map;
2121

22+
import org.jspecify.annotations.Nullable;
23+
2224
import org.springframework.boot.origin.Origin;
2325
import org.springframework.boot.origin.OriginLookup;
2426
import org.springframework.boot.system.ApplicationPid;
@@ -38,7 +40,7 @@ class ApplicationInfoPropertySource extends MapPropertySource implements OriginL
3840

3941
static final String NAME = "applicationInfo";
4042

41-
ApplicationInfoPropertySource(Class<?> mainClass) {
43+
ApplicationInfoPropertySource(@Nullable Class<?> mainClass) {
4244
super(NAME, getProperties(readVersion(mainClass)));
4345
}
4446

@@ -47,7 +49,7 @@ class ApplicationInfoPropertySource extends MapPropertySource implements OriginL
4749
}
4850

4951
@Override
50-
public Origin getOrigin(String key) {
52+
public @Nullable Origin getOrigin(String key) {
5153
return null;
5254
}
5355

@@ -56,7 +58,7 @@ public boolean isImmutable() {
5658
return true;
5759
}
5860

59-
private static Map<String, Object> getProperties(String applicationVersion) {
61+
private static Map<String, Object> getProperties(@Nullable String applicationVersion) {
6062
Map<String, Object> result = new HashMap<>();
6163
if (StringUtils.hasText(applicationVersion)) {
6264
result.put("spring.application.version", applicationVersion);
@@ -68,7 +70,7 @@ private static Map<String, Object> getProperties(String applicationVersion) {
6870
return result;
6971
}
7072

71-
private static String readVersion(Class<?> applicationClass) {
73+
private static @Nullable String readVersion(@Nullable Class<?> applicationClass) {
7274
Package sourcePackage = (applicationClass != null) ? applicationClass.getPackage() : null;
7375
return (sourcePackage != null) ? sourcePackage.getImplementationVersion() : null;
7476
}

core/spring-boot/src/main/java/org/springframework/boot/ApplicationProperties.java

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,15 @@
1919
import java.util.LinkedHashSet;
2020
import java.util.Set;
2121

22+
import org.jspecify.annotations.Nullable;
23+
2224
import org.springframework.aot.hint.RuntimeHints;
2325
import org.springframework.aot.hint.RuntimeHintsRegistrar;
2426
import org.springframework.boot.Banner.Mode;
2527
import org.springframework.boot.context.properties.bind.BindableRuntimeHintsRegistrar;
2628
import org.springframework.boot.logging.LoggingSystemProperty;
2729
import org.springframework.core.env.Environment;
30+
import org.springframework.util.Assert;
2831

2932
/**
3033
* Spring application properties.
@@ -48,7 +51,7 @@ class ApplicationProperties {
4851
/**
4952
* Mode used to display the banner when the application runs.
5053
*/
51-
private Banner.Mode bannerMode;
54+
private Banner.@Nullable Mode bannerMode;
5255

5356
/**
5457
* Whether to keep the application alive even if there are no more non-daemon threads.
@@ -80,7 +83,7 @@ class ApplicationProperties {
8083
* Flag to explicitly request a specific type of web application. If not set,
8184
* auto-detected based on the classpath.
8285
*/
83-
private WebApplicationType webApplicationType;
86+
private @Nullable WebApplicationType webApplicationType;
8487

8588
boolean isAllowBeanDefinitionOverriding() {
8689
return this.allowBeanDefinitionOverriding;
@@ -102,12 +105,13 @@ Mode getBannerMode(Environment environment) {
102105
if (this.bannerMode != null) {
103106
return this.bannerMode;
104107
}
105-
boolean structuredLoggingEnabled = environment
106-
.containsProperty(LoggingSystemProperty.CONSOLE_STRUCTURED_FORMAT.getApplicationPropertyName());
108+
String applicationPropertyName = LoggingSystemProperty.CONSOLE_STRUCTURED_FORMAT.getApplicationPropertyName();
109+
Assert.state(applicationPropertyName != null, "applicationPropertyName must not be null");
110+
boolean structuredLoggingEnabled = environment.containsProperty(applicationPropertyName);
107111
return (structuredLoggingEnabled) ? Mode.OFF : Banner.Mode.CONSOLE;
108112
}
109113

110-
void setBannerMode(Mode bannerMode) {
114+
void setBannerMode(@Nullable Mode bannerMode) {
111115
this.bannerMode = bannerMode;
112116
}
113117

@@ -151,18 +155,18 @@ void setSources(Set<String> sources) {
151155
this.sources = new LinkedHashSet<>(sources);
152156
}
153157

154-
WebApplicationType getWebApplicationType() {
158+
@Nullable WebApplicationType getWebApplicationType() {
155159
return this.webApplicationType;
156160
}
157161

158-
void setWebApplicationType(WebApplicationType webApplicationType) {
162+
void setWebApplicationType(@Nullable WebApplicationType webApplicationType) {
159163
this.webApplicationType = webApplicationType;
160164
}
161165

162166
static class ApplicationPropertiesRuntimeHints implements RuntimeHintsRegistrar {
163167

164168
@Override
165-
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
169+
public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) {
166170
BindableRuntimeHintsRegistrar.forTypes(ApplicationProperties.class).registerHints(hints, classLoader);
167171
}
168172

core/spring-boot/src/main/java/org/springframework/boot/Banner.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
import java.io.PrintStream;
2020

21+
import org.jspecify.annotations.Nullable;
22+
2123
import org.springframework.core.env.Environment;
2224

2325
/**
@@ -34,10 +36,10 @@ public interface Banner {
3436
/**
3537
* Print the banner to the specified print stream.
3638
* @param environment the spring environment
37-
* @param sourceClass the source class for the application
39+
* @param sourceClass the source class for the application or {@code null}
3840
* @param out the output print stream
3941
*/
40-
void printBanner(Environment environment, Class<?> sourceClass, PrintStream out);
42+
void printBanner(Environment environment, @Nullable Class<?> sourceClass, PrintStream out);
4143

4244
/**
4345
* An enumeration of possible values for configuring the Banner.

core/spring-boot/src/main/java/org/springframework/boot/BeanDefinitionLoader.java

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.util.regex.Pattern;
2424

2525
import groovy.lang.Closure;
26+
import org.jspecify.annotations.Nullable;
2627

2728
import org.springframework.beans.BeanUtils;
2829
import org.springframework.beans.factory.BeanDefinitionStoreException;
@@ -68,11 +69,11 @@ class BeanDefinitionLoader {
6869

6970
private final AbstractBeanDefinitionReader xmlReader;
7071

71-
private final BeanDefinitionReader groovyReader;
72+
private final @Nullable BeanDefinitionReader groovyReader;
7273

7374
private final ClassPathBeanDefinitionScanner scanner;
7475

75-
private ResourceLoader resourceLoader;
76+
private @Nullable ResourceLoader resourceLoader;
7677

7778
/**
7879
* Create a new {@link BeanDefinitionLoader} that will load beans into the specified
@@ -86,7 +87,7 @@ class BeanDefinitionLoader {
8687
this.sources = sources;
8788
this.annotatedReader = new AnnotatedBeanDefinitionReader(registry);
8889
this.xmlReader = new XmlBeanDefinitionReader(registry);
89-
this.groovyReader = (isGroovyPresent() ? new GroovyBeanDefinitionReader(registry) : null);
90+
this.groovyReader = isGroovyPresent() ? new GroovyBeanDefinitionReader(registry) : null;
9091
this.scanner = new ClassPathBeanDefinitionScanner(registry);
9192
this.scanner.addExcludeFilter(new ClassExcludeFilter(sources));
9293
}
@@ -152,7 +153,7 @@ private void load(Object source) {
152153
}
153154

154155
private void load(Class<?> source) {
155-
if (isGroovyPresent() && GroovyBeanDefinitionSource.class.isAssignableFrom(source)) {
156+
if (this.groovyReader != null && GroovyBeanDefinitionSource.class.isAssignableFrom(source)) {
156157
// Any GroovyLoaders added in beans{} DSL can contribute beans here
157158
GroovyBeanDefinitionSource loader = BeanUtils.instantiateClass(source, GroovyBeanDefinitionSource.class);
158159
((GroovyBeanDefinitionReader) this.groovyReader).beans(loader.getBeans());
@@ -163,7 +164,9 @@ private void load(Class<?> source) {
163164
}
164165

165166
private void load(Resource source) {
166-
if (source.getFilename().endsWith(".groovy")) {
167+
String filename = source.getFilename();
168+
Assert.state(filename != null, "Source has no filename");
169+
if (filename.endsWith(".groovy")) {
167170
if (this.groovyReader == null) {
168171
throw new BeanDefinitionStoreException("Cannot load Groovy beans without Groovy on classpath");
169172
}
@@ -231,7 +234,7 @@ private Resource[] findResources(String source) {
231234
}
232235
}
233236

234-
private boolean isLoadCandidate(Resource resource) {
237+
private boolean isLoadCandidate(@Nullable Resource resource) {
235238
if (resource == null || !resource.exists()) {
236239
return false;
237240
}
@@ -253,7 +256,7 @@ private boolean isLoadCandidate(Resource resource) {
253256
return true;
254257
}
255258

256-
private Package findPackage(CharSequence source) {
259+
private @Nullable Package findPackage(CharSequence source) {
257260
Package pkg = getClass().getClassLoader().getDefinedPackage(source.toString());
258261
if (pkg != null) {
259262
return pkg;
@@ -264,7 +267,9 @@ private Package findPackage(CharSequence source) {
264267
Resource[] resources = resolver
265268
.getResources(ClassUtils.convertClassNameToResourcePath(source.toString()) + "/*.class");
266269
for (Resource resource : resources) {
267-
String className = StringUtils.stripFilenameExtension(resource.getFilename());
270+
String filename = resource.getFilename();
271+
Assert.state(filename != null, "No filename available");
272+
String className = StringUtils.stripFilenameExtension(filename);
268273
load(Class.forName(source + "." + className));
269274
break;
270275
}

core/spring-boot/src/main/java/org/springframework/boot/BootstrapContext.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
import java.util.function.Supplier;
2020

21+
import org.jspecify.annotations.Nullable;
22+
2123
import org.springframework.context.ApplicationContext;
2224
import org.springframework.core.env.Environment;
2325

@@ -41,7 +43,7 @@ public interface BootstrapContext {
4143
* @return the instance managed by the context
4244
* @throws IllegalStateException if the type has not been registered
4345
*/
44-
<T> T get(Class<T> type) throws IllegalStateException;
46+
<T> @Nullable T get(Class<T> type) throws IllegalStateException;
4547

4648
/**
4749
* Return an instance from the context if the type has been registered. The instance
@@ -51,7 +53,7 @@ public interface BootstrapContext {
5153
* @param other the instance to use if the type has not been registered
5254
* @return the instance
5355
*/
54-
<T> T getOrElse(Class<T> type, T other);
56+
<T> @Nullable T getOrElse(Class<T> type, @Nullable T other);
5557

5658
/**
5759
* Return an instance from the context if the type has been registered. The instance
@@ -61,7 +63,7 @@ public interface BootstrapContext {
6163
* @param other a supplier for the instance to use if the type has not been registered
6264
* @return the instance
6365
*/
64-
<T> T getOrElseSupply(Class<T> type, Supplier<T> other);
66+
<T> @Nullable T getOrElseSupply(Class<T> type, Supplier<@Nullable T> other);
6567

6668
/**
6769
* Return an instance from the context if the type has been registered. The instance
@@ -74,7 +76,8 @@ public interface BootstrapContext {
7476
* @throws X if the type has not been registered
7577
* @throws IllegalStateException if the type has not been registered
7678
*/
77-
<T, X extends Throwable> T getOrElseThrow(Class<T> type, Supplier<? extends X> exceptionSupplier) throws X;
79+
<T, X extends Throwable> @Nullable T getOrElseThrow(Class<T> type, Supplier<? extends X> exceptionSupplier)
80+
throws X;
7881

7982
/**
8083
* Return if a registration exists for the given type.

0 commit comments

Comments
 (0)