Browse Source

Add nullability annotations to module/spring-boot-devtools

See gh-46587
pull/47390/head
Moritz Halbritter 4 months ago
parent
commit
4d76f204e3
  1. 4
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/RemoteUrlPropertyExtractor.java
  2. 1
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/ConditionEvaluationDeltaLoggingListener.java
  3. 16
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/DevToolsDataSourceAutoConfiguration.java
  4. 14
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/DevToolsProperties.java
  5. 9
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/DevToolsR2dbcAutoConfiguration.java
  6. 5
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/LocalDevToolsAutoConfiguration.java
  7. 5
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/OptionalLiveReloadServer.java
  8. 5
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/RemoteDevToolsAutoConfiguration.java
  9. 20
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/RemoteDevToolsProperties.java
  10. 3
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/package-info.java
  11. 3
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/classpath/ClassPathDirectories.java
  12. 6
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/classpath/ClassPathFileChangeListener.java
  13. 7
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/classpath/ClassPathFileSystemWatcher.java
  14. 3
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/classpath/package-info.java
  15. 6
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/env/DevToolsHomePropertiesPostProcessor.java
  16. 3
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/env/DevToolsPropertyDefaultsPostProcessor.java
  17. 3
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/env/package-info.java
  18. 4
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/filewatch/ChangedFile.java
  19. 4
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/filewatch/ChangedFiles.java
  20. 12
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/filewatch/DirectorySnapshot.java
  21. 4
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/filewatch/FileSnapshot.java
  22. 22
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/filewatch/FileSystemWatcher.java
  23. 6
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/filewatch/SnapshotStateRepository.java
  24. 6
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/filewatch/StaticSnapshotStateRepository.java
  25. 3
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/filewatch/package-info.java
  26. 7
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/livereload/LiveReloadServer.java
  27. 3
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/livereload/package-info.java
  28. 3
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/logger/package-info.java
  29. 3
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/package-info.java
  30. 1
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/remote/client/ClassPathChangeUploader.java
  31. 5
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/remote/client/RemoteClientConfiguration.java
  32. 3
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/remote/client/package-info.java
  33. 4
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/remote/server/HandlerMapper.java
  34. 4
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/remote/server/UrlHandlerMapper.java
  35. 3
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/remote/server/package-info.java
  36. 4
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/AgentReloader.java
  37. 12
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/ClassLoaderFilesResourcePatternResolver.java
  38. 4
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/DefaultRestartInitializer.java
  39. 4
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/MainMethod.java
  40. 4
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/OnInitializedRestarterCondition.java
  41. 4
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/RestartInitializer.java
  42. 6
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/RestartLauncher.java
  43. 6
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/RestartScopeInitializer.java
  44. 28
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/Restarter.java
  45. 6
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/SilentExitExceptionHandler.java
  46. 10
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/classloader/ClassLoaderFile.java
  47. 4
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/classloader/ClassLoaderFileRepository.java
  48. 8
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/classloader/ClassLoaderFiles.java
  49. 13
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/classloader/RestartClassLoader.java
  50. 3
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/classloader/package-info.java
  51. 3
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/package-info.java
  52. 4
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/server/DefaultSourceDirectoryUrlFilter.java
  53. 4
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/server/RestartServer.java
  54. 3
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/server/package-info.java
  55. 3
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/settings/DevToolsSettings.java
  56. 3
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/settings/package-info.java
  57. 3
      module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/system/package-info.java

4
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/RemoteUrlPropertyExtractor.java

@ -21,6 +21,8 @@ import java.net.URISyntaxException; @@ -21,6 +21,8 @@ import java.net.URISyntaxException;
import java.util.Collections;
import java.util.Map;
import org.jspecify.annotations.Nullable;
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.core.Ordered;
@ -59,7 +61,7 @@ class RemoteUrlPropertyExtractor implements ApplicationListener<ApplicationEnvir @@ -59,7 +61,7 @@ class RemoteUrlPropertyExtractor implements ApplicationListener<ApplicationEnvir
environment.getPropertySources().addLast(propertySource);
}
private String cleanRemoteUrl(String url) {
private @Nullable String cleanRemoteUrl(@Nullable String url) {
if (StringUtils.hasText(url) && url.endsWith("/")) {
return url.substring(0, url.length() - 1);
}

1
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/ConditionEvaluationDeltaLoggingListener.java

@ -41,6 +41,7 @@ class ConditionEvaluationDeltaLoggingListener @@ -41,6 +41,7 @@ class ConditionEvaluationDeltaLoggingListener
private static final Log logger = LogFactory.getLog(ConditionEvaluationDeltaLoggingListener.class);
@SuppressWarnings("NullAway.Init")
private volatile ApplicationContext context;
@Override

16
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/DevToolsDataSourceAutoConfiguration.java

@ -25,10 +25,12 @@ import java.util.Set; @@ -25,10 +25,12 @@ import java.util.Set;
import javax.sql.DataSource;
import org.apache.derby.jdbc.EmbeddedDriver;
import org.jspecify.annotations.Nullable;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionMessage;
@ -50,6 +52,7 @@ import org.springframework.context.annotation.Import; @@ -50,6 +52,7 @@ import org.springframework.context.annotation.Import;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.orm.jpa.AbstractEntityManagerFactoryBean;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.util.Assert;
/**
* {@link EnableAutoConfiguration Auto-configuration} for DevTools-specific
@ -136,13 +139,13 @@ public final class DevToolsDataSourceAutoConfiguration { @@ -136,13 +139,13 @@ public final class DevToolsDataSourceAutoConfiguration {
HSQLDB("jdbc:hsqldb:mem:", Set.of("org.hsqldb.jdbcDriver", "org.hsqldb.jdbc.JDBCDriver",
"org.hsqldb.jdbc.pool.JDBCXADataSource"));
private final String urlPrefix;
private final @Nullable String urlPrefix;
private final ShutdownHandler shutdownHandler;
private final Set<String> driverClassNames;
InMemoryDatabase(String urlPrefix, Set<String> driverClassNames) {
InMemoryDatabase(@Nullable String urlPrefix, Set<String> driverClassNames) {
this(urlPrefix, driverClassNames, (dataSource) -> {
try (Connection connection = dataSource.getConnection()) {
try (Statement statement = connection.createStatement()) {
@ -152,7 +155,8 @@ public final class DevToolsDataSourceAutoConfiguration { @@ -152,7 +155,8 @@ public final class DevToolsDataSourceAutoConfiguration {
});
}
InMemoryDatabase(String urlPrefix, Set<String> driverClassNames, ShutdownHandler shutdownHandler) {
InMemoryDatabase(@Nullable String urlPrefix, Set<String> driverClassNames,
ShutdownHandler shutdownHandler) {
this.urlPrefix = urlPrefix;
this.driverClassNames = driverClassNames;
this.shutdownHandler = shutdownHandler;
@ -189,11 +193,13 @@ public final class DevToolsDataSourceAutoConfiguration { @@ -189,11 +193,13 @@ public final class DevToolsDataSourceAutoConfiguration {
@Override
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
ConditionMessage.Builder message = ConditionMessage.forCondition("DevTools DataSource Condition");
String[] dataSourceBeanNames = context.getBeanFactory().getBeanNamesForType(DataSource.class, true, false);
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
Assert.state(beanFactory != null, "'beanFactory' must not be null");
String[] dataSourceBeanNames = beanFactory.getBeanNamesForType(DataSource.class, true, false);
if (dataSourceBeanNames.length != 1) {
return ConditionOutcome.noMatch(message.didNotFind("a single DataSource bean").atAll());
}
if (context.getBeanFactory().getBeanNamesForType(DataSourceProperties.class, true, false).length != 1) {
if (beanFactory.getBeanNamesForType(DataSourceProperties.class, true, false).length != 1) {
return ConditionOutcome.noMatch(message.didNotFind("a single DataSourceProperties bean").atAll());
}
BeanDefinition dataSourceDefinition = context.getRegistry().getBeanDefinition(dataSourceBeanNames[0]);

14
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/DevToolsProperties.java

@ -21,6 +21,8 @@ import java.time.Duration; @@ -21,6 +21,8 @@ import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import org.jspecify.annotations.Nullable;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
import org.springframework.util.StringUtils;
@ -76,7 +78,7 @@ public class DevToolsProperties { @@ -76,7 +78,7 @@ public class DevToolsProperties {
/**
* Additional patterns that should be excluded from triggering a full restart.
*/
private String additionalExclude;
private @Nullable String additionalExclude;
/**
* Amount of time to wait between polling for classpath changes.
@ -94,7 +96,7 @@ public class DevToolsProperties { @@ -94,7 +96,7 @@ public class DevToolsProperties {
* a simple name (without any path) of a file that appears on your classpath. If
* not specified, any classpath file change triggers the restart.
*/
private String triggerFile;
private @Nullable String triggerFile;
/**
* Additional paths to watch for changes.
@ -133,11 +135,11 @@ public class DevToolsProperties { @@ -133,11 +135,11 @@ public class DevToolsProperties {
this.exclude = exclude;
}
public String getAdditionalExclude() {
public @Nullable String getAdditionalExclude() {
return this.additionalExclude;
}
public void setAdditionalExclude(String additionalExclude) {
public void setAdditionalExclude(@Nullable String additionalExclude) {
this.additionalExclude = additionalExclude;
}
@ -157,11 +159,11 @@ public class DevToolsProperties { @@ -157,11 +159,11 @@ public class DevToolsProperties {
this.quietPeriod = quietPeriod;
}
public String getTriggerFile() {
public @Nullable String getTriggerFile() {
return this.triggerFile;
}
public void setTriggerFile(String triggerFile) {
public void setTriggerFile(@Nullable String triggerFile) {
this.triggerFile = triggerFile;
}

9
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/DevToolsR2dbcAutoConfiguration.java

@ -18,12 +18,14 @@ package org.springframework.boot.devtools.autoconfigure; @@ -18,12 +18,14 @@ package org.springframework.boot.devtools.autoconfigure;
import io.r2dbc.spi.Connection;
import io.r2dbc.spi.ConnectionFactory;
import org.jspecify.annotations.Nullable;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Mono;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionMessage;
@ -40,6 +42,7 @@ import org.springframework.context.annotation.Conditional; @@ -40,6 +42,7 @@ import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.ConfigurationCondition;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.core.type.MethodMetadata;
import org.springframework.util.Assert;
/**
* {@link EnableAutoConfiguration Auto-configuration} for DevTools-specific R2DBC
@ -99,7 +102,7 @@ public final class DevToolsR2dbcAutoConfiguration { @@ -99,7 +102,7 @@ public final class DevToolsR2dbcAutoConfiguration {
return closeConnection(connection, null);
}
private Publisher<Void> closeConnection(Connection connection, Throwable ex) {
private Publisher<Void> closeConnection(Connection connection, @Nullable Throwable ex) {
return connection.close();
}
@ -115,7 +118,9 @@ public final class DevToolsR2dbcAutoConfiguration { @@ -115,7 +118,9 @@ public final class DevToolsR2dbcAutoConfiguration {
@Override
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
ConditionMessage.Builder message = ConditionMessage.forCondition("DevTools ConnectionFactory Condition");
String[] beanNames = context.getBeanFactory().getBeanNamesForType(ConnectionFactory.class, true, false);
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
Assert.state(beanFactory != null, "'beanFactory' must not be null");
String[] beanNames = beanFactory.getBeanNamesForType(ConnectionFactory.class, true, false);
if (beanNames.length != 1) {
return ConditionOutcome.noMatch(message.didNotFind("a single ConnectionFactory bean").atAll());
}

5
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/LocalDevToolsAutoConfiguration.java

@ -22,6 +22,7 @@ import java.util.List; @@ -22,6 +22,7 @@ import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jspecify.annotations.Nullable;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
@ -49,6 +50,7 @@ import org.springframework.context.event.ContextRefreshedEvent; @@ -49,6 +50,7 @@ import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.GenericApplicationListener;
import org.springframework.core.ResolvableType;
import org.springframework.core.log.LogMessage;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
@ -116,6 +118,7 @@ public final class LocalDevToolsAutoConfiguration { @@ -116,6 +118,7 @@ public final class LocalDevToolsAutoConfiguration {
ClassPathFileSystemWatcher classPathFileSystemWatcher(FileSystemWatcherFactory fileSystemWatcherFactory,
ClassPathRestartStrategy classPathRestartStrategy) {
URL[] urls = Restarter.getInstance().getInitialUrls();
Assert.state(urls != null, "'urls' must not be null");
ClassPathFileSystemWatcher watcher = new ClassPathFileSystemWatcher(fileSystemWatcherFactory,
classPathRestartStrategy, urls);
watcher.setStopWatcherOnRestart(true);
@ -176,7 +179,7 @@ public final class LocalDevToolsAutoConfiguration { @@ -176,7 +179,7 @@ public final class LocalDevToolsAutoConfiguration {
}
@Override
public boolean supportsSourceType(Class<?> sourceType) {
public boolean supportsSourceType(@Nullable Class<?> sourceType) {
return true;
}

5
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/OptionalLiveReloadServer.java

@ -18,6 +18,7 @@ package org.springframework.boot.devtools.autoconfigure; @@ -18,6 +18,7 @@ package org.springframework.boot.devtools.autoconfigure;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jspecify.annotations.Nullable;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.devtools.livereload.LiveReloadServer;
@ -34,13 +35,13 @@ public class OptionalLiveReloadServer implements InitializingBean { @@ -34,13 +35,13 @@ public class OptionalLiveReloadServer implements InitializingBean {
private static final Log logger = LogFactory.getLog(OptionalLiveReloadServer.class);
private LiveReloadServer server;
private @Nullable LiveReloadServer server;
/**
* Create a new {@link OptionalLiveReloadServer} instance.
* @param server the server to manage or {@code null}
*/
public OptionalLiveReloadServer(LiveReloadServer server) {
public OptionalLiveReloadServer(@Nullable LiveReloadServer server) {
this.server = server;
}

5
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/RemoteDevToolsAutoConfiguration.java

@ -48,6 +48,7 @@ import org.springframework.context.annotation.Configuration; @@ -48,6 +48,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.log.LogMessage;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.util.Assert;
/**
* {@link EnableAutoConfiguration Auto-configuration} for remote development support.
@ -78,7 +79,9 @@ public final class RemoteDevToolsAutoConfiguration { @@ -78,7 +79,9 @@ public final class RemoteDevToolsAutoConfiguration {
@ConditionalOnMissingBean
AccessManager remoteDevToolsAccessManager() {
RemoteDevToolsProperties remoteProperties = this.properties.getRemote();
return new HttpHeaderAccessManager(remoteProperties.getSecretHeaderName(), remoteProperties.getSecret());
String secret = remoteProperties.getSecret();
Assert.state(secret != null, "'secret' must not be null");
return new HttpHeaderAccessManager(remoteProperties.getSecretHeaderName(), secret);
}
@Bean

20
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/RemoteDevToolsProperties.java

@ -16,6 +16,8 @@ @@ -16,6 +16,8 @@
package org.springframework.boot.devtools.autoconfigure;
import org.jspecify.annotations.Nullable;
/**
* Configuration properties for remote Spring Boot applications.
*
@ -39,7 +41,7 @@ public class RemoteDevToolsProperties { @@ -39,7 +41,7 @@ public class RemoteDevToolsProperties {
* A shared secret required to establish a connection (required to enable remote
* support).
*/
private String secret;
private @Nullable String secret;
/**
* HTTP header used to transfer the shared secret.
@ -58,11 +60,11 @@ public class RemoteDevToolsProperties { @@ -58,11 +60,11 @@ public class RemoteDevToolsProperties {
this.contextPath = contextPath;
}
public String getSecret() {
public @Nullable String getSecret() {
return this.secret;
}
public void setSecret(String secret) {
public void setSecret(@Nullable String secret) {
this.secret = secret;
}
@ -104,26 +106,26 @@ public class RemoteDevToolsProperties { @@ -104,26 +106,26 @@ public class RemoteDevToolsProperties {
/**
* The host of the proxy to use to connect to the remote application.
*/
private String host;
private @Nullable String host;
/**
* The port of the proxy to use to connect to the remote application.
*/
private Integer port;
private @Nullable Integer port;
public String getHost() {
public @Nullable String getHost() {
return this.host;
}
public void setHost(String host) {
public void setHost(@Nullable String host) {
this.host = host;
}
public Integer getPort() {
public @Nullable Integer getPort() {
return this.port;
}
public void setPort(Integer port) {
public void setPort(@Nullable Integer port) {
this.port = port;
}

3
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/package-info.java

@ -17,4 +17,7 @@ @@ -17,4 +17,7 @@
/**
* Auto-configuration for {@code spring-boot-devtools}.
*/
@NullMarked
package org.springframework.boot.devtools.autoconfigure;
import org.jspecify.annotations.NullMarked;

3
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/classpath/ClassPathDirectories.java

@ -25,6 +25,7 @@ import java.util.List; @@ -25,6 +25,7 @@ import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jspecify.annotations.Nullable;
import org.springframework.core.log.LogMessage;
import org.springframework.util.ResourceUtils;
@ -41,7 +42,7 @@ public class ClassPathDirectories implements Iterable<File> { @@ -41,7 +42,7 @@ public class ClassPathDirectories implements Iterable<File> {
private final List<File> directories = new ArrayList<>();
public ClassPathDirectories(URL[] urls) {
public ClassPathDirectories(URL @Nullable [] urls) {
if (urls != null) {
addUrls(urls);
}

6
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/classpath/ClassPathFileChangeListener.java

@ -18,6 +18,8 @@ package org.springframework.boot.devtools.classpath; @@ -18,6 +18,8 @@ package org.springframework.boot.devtools.classpath;
import java.util.Set;
import org.jspecify.annotations.Nullable;
import org.springframework.boot.devtools.filewatch.ChangedFile;
import org.springframework.boot.devtools.filewatch.ChangedFiles;
import org.springframework.boot.devtools.filewatch.FileChangeListener;
@ -39,7 +41,7 @@ class ClassPathFileChangeListener implements FileChangeListener { @@ -39,7 +41,7 @@ class ClassPathFileChangeListener implements FileChangeListener {
private final ClassPathRestartStrategy restartStrategy;
private final FileSystemWatcher fileSystemWatcherToStop;
private final @Nullable FileSystemWatcher fileSystemWatcherToStop;
/**
* Create a new {@link ClassPathFileChangeListener} instance.
@ -49,7 +51,7 @@ class ClassPathFileChangeListener implements FileChangeListener { @@ -49,7 +51,7 @@ class ClassPathFileChangeListener implements FileChangeListener {
* {@code null})
*/
ClassPathFileChangeListener(ApplicationEventPublisher eventPublisher, ClassPathRestartStrategy restartStrategy,
FileSystemWatcher fileSystemWatcherToStop) {
@Nullable FileSystemWatcher fileSystemWatcherToStop) {
Assert.notNull(eventPublisher, "'eventPublisher' must not be null");
Assert.notNull(restartStrategy, "'restartStrategy' must not be null");
this.eventPublisher = eventPublisher;

7
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/classpath/ClassPathFileSystemWatcher.java

@ -18,6 +18,8 @@ package org.springframework.boot.devtools.classpath; @@ -18,6 +18,8 @@ package org.springframework.boot.devtools.classpath;
import java.net.URL;
import org.jspecify.annotations.Nullable;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
@ -39,8 +41,9 @@ public class ClassPathFileSystemWatcher implements InitializingBean, DisposableB @@ -39,8 +41,9 @@ public class ClassPathFileSystemWatcher implements InitializingBean, DisposableB
private final FileSystemWatcher fileSystemWatcher;
private final ClassPathRestartStrategy restartStrategy;
private final @Nullable ClassPathRestartStrategy restartStrategy;
@SuppressWarnings("NullAway.Init")
private ApplicationContext applicationContext;
private boolean stopWatcherOnRestart;
@ -53,7 +56,7 @@ public class ClassPathFileSystemWatcher implements InitializingBean, DisposableB @@ -53,7 +56,7 @@ public class ClassPathFileSystemWatcher implements InitializingBean, DisposableB
* @param urls the URLs to watch
*/
public ClassPathFileSystemWatcher(FileSystemWatcherFactory fileSystemWatcherFactory,
ClassPathRestartStrategy restartStrategy, URL[] urls) {
@Nullable ClassPathRestartStrategy restartStrategy, URL[] urls) {
Assert.notNull(fileSystemWatcherFactory, "'fileSystemWatcherFactory' must not be null");
Assert.notNull(urls, "'urls' must not be null");
this.fileSystemWatcher = fileSystemWatcherFactory.getFileSystemWatcher();

3
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/classpath/package-info.java

@ -17,4 +17,7 @@ @@ -17,4 +17,7 @@
/**
* Support for classpath monitoring.
*/
@NullMarked
package org.springframework.boot.devtools.classpath;
import org.jspecify.annotations.NullMarked;

6
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/env/DevToolsHomePropertiesPostProcessor.java vendored

@ -29,6 +29,8 @@ import java.util.Set; @@ -29,6 +29,8 @@ import java.util.Set;
import java.util.function.Function;
import java.util.function.Supplier;
import org.jspecify.annotations.Nullable;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.devtools.system.DevToolsEnablementDeducer;
import org.springframework.boot.env.EnvironmentPostProcessor;
@ -137,14 +139,14 @@ public class DevToolsHomePropertiesPostProcessor implements EnvironmentPostProce @@ -137,14 +139,14 @@ public class DevToolsHomePropertiesPostProcessor implements EnvironmentPostProce
.anyMatch((fileExtension) -> StringUtils.endsWithIgnoreCase(name, fileExtension));
}
protected File getHomeDirectory() {
protected @Nullable File getHomeDirectory() {
return getHomeDirectory(() -> this.environmentVariables.get("SPRING_DEVTOOLS_HOME"),
() -> this.systemProperties.getProperty("spring.devtools.home"),
() -> this.systemProperties.getProperty("user.home"));
}
@SafeVarargs
private File getHomeDirectory(Supplier<String>... pathSuppliers) {
private @Nullable File getHomeDirectory(Supplier<String>... pathSuppliers) {
for (Supplier<String> pathSupplier : pathSuppliers) {
String path = pathSupplier.get();
if (StringUtils.hasText(path)) {

3
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/env/DevToolsPropertyDefaultsPostProcessor.java vendored

@ -24,6 +24,7 @@ import java.util.Map; @@ -24,6 +24,7 @@ import java.util.Map;
import java.util.Properties;
import org.apache.commons.logging.Log;
import org.jspecify.annotations.Nullable;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.devtools.logger.DevToolsLogFactory;
@ -123,7 +124,7 @@ public class DevToolsPropertyDefaultsPostProcessor implements EnvironmentPostPro @@ -123,7 +124,7 @@ public class DevToolsPropertyDefaultsPostProcessor implements EnvironmentPostPro
return false;
}
private Class<?> resolveClassName(String candidate, ClassLoader classLoader) {
private @Nullable Class<?> resolveClassName(String candidate, ClassLoader classLoader) {
try {
return ClassUtils.resolveClassName(candidate, classLoader);
}

3
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/env/package-info.java vendored

@ -18,4 +18,7 @@ @@ -18,4 +18,7 @@
* DevTools classes relating to Spring Framework's
* {@link org.springframework.core.env.Environment}.
*/
@NullMarked
package org.springframework.boot.devtools.env;
import org.jspecify.annotations.NullMarked;

4
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/filewatch/ChangedFile.java

@ -18,6 +18,8 @@ package org.springframework.boot.devtools.filewatch; @@ -18,6 +18,8 @@ package org.springframework.boot.devtools.filewatch;
import java.io.File;
import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@ -82,7 +84,7 @@ public final class ChangedFile { @@ -82,7 +84,7 @@ public final class ChangedFile {
}
@Override
public boolean equals(Object obj) {
public boolean equals(@Nullable Object obj) {
if (obj == this) {
return true;
}

4
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/filewatch/ChangedFiles.java

@ -21,6 +21,8 @@ import java.util.Collections; @@ -21,6 +21,8 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.Set;
import org.jspecify.annotations.Nullable;
/**
* A collections of files from a specific source directory that have changed.
*
@ -62,7 +64,7 @@ public final class ChangedFiles implements Iterable<ChangedFile> { @@ -62,7 +64,7 @@ public final class ChangedFiles implements Iterable<ChangedFile> {
}
@Override
public boolean equals(Object obj) {
public boolean equals(@Nullable Object obj) {
if (obj == null) {
return false;
}

12
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/filewatch/DirectorySnapshot.java

@ -27,6 +27,8 @@ import java.util.LinkedHashSet; @@ -27,6 +27,8 @@ import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import org.jspecify.annotations.Nullable;
import org.springframework.boot.devtools.filewatch.ChangedFile.Type;
import org.springframework.util.Assert;
@ -73,7 +75,7 @@ class DirectorySnapshot { @@ -73,7 +75,7 @@ class DirectorySnapshot {
}
}
ChangedFiles getChangedFiles(DirectorySnapshot snapshot, FileFilter triggerFilter) {
ChangedFiles getChangedFiles(DirectorySnapshot snapshot, @Nullable FileFilter triggerFilter) {
Assert.notNull(snapshot, "'snapshot' must not be null");
File directory = this.directory;
Assert.isTrue(snapshot.directory.equals(directory),
@ -99,7 +101,7 @@ class DirectorySnapshot { @@ -99,7 +101,7 @@ class DirectorySnapshot {
return new ChangedFiles(directory, changes);
}
private boolean acceptChangedFile(FileFilter triggerFilter, FileSnapshot file) {
private boolean acceptChangedFile(@Nullable FileFilter triggerFilter, FileSnapshot file) {
return (triggerFilter == null || !triggerFilter.accept(file.getFile()));
}
@ -112,7 +114,7 @@ class DirectorySnapshot { @@ -112,7 +114,7 @@ class DirectorySnapshot {
}
@Override
public boolean equals(Object obj) {
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
@ -125,7 +127,7 @@ class DirectorySnapshot { @@ -125,7 +127,7 @@ class DirectorySnapshot {
return super.equals(obj);
}
boolean equals(DirectorySnapshot other, FileFilter filter) {
boolean equals(DirectorySnapshot other, @Nullable FileFilter filter) {
if (this.directory.equals(other.directory)) {
Set<FileSnapshot> ourFiles = filter(this.files, filter);
Set<FileSnapshot> otherFiles = filter(other.files, filter);
@ -134,7 +136,7 @@ class DirectorySnapshot { @@ -134,7 +136,7 @@ class DirectorySnapshot {
return false;
}
private Set<FileSnapshot> filter(Set<FileSnapshot> source, FileFilter filter) {
private Set<FileSnapshot> filter(Set<FileSnapshot> source, @Nullable FileFilter filter) {
if (filter == null) {
return source;
}

4
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/filewatch/FileSnapshot.java

@ -18,6 +18,8 @@ package org.springframework.boot.devtools.filewatch; @@ -18,6 +18,8 @@ package org.springframework.boot.devtools.filewatch;
import java.io.File;
import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
/**
@ -49,7 +51,7 @@ class FileSnapshot { @@ -49,7 +51,7 @@ class FileSnapshot {
}
@Override
public boolean equals(Object obj) {
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}

22
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/filewatch/FileSystemWatcher.java

@ -30,6 +30,8 @@ import java.util.Map; @@ -30,6 +30,8 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
/**
@ -58,11 +60,11 @@ public class FileSystemWatcher { @@ -58,11 +60,11 @@ public class FileSystemWatcher {
private final AtomicInteger remainingScans = new AtomicInteger(-1);
private final Map<File, DirectorySnapshot> directories = new HashMap<>();
private final Map<File, @Nullable DirectorySnapshot> directories = new HashMap<>();
private Thread watchThread;
private @Nullable Thread watchThread;
private FileFilter triggerFilter;
private @Nullable FileFilter triggerFilter;
private final Object monitor = new Object();
@ -94,7 +96,7 @@ public class FileSystemWatcher { @@ -94,7 +96,7 @@ public class FileSystemWatcher {
* @since 2.4.0
*/
public FileSystemWatcher(boolean daemon, Duration pollInterval, Duration quietPeriod,
SnapshotStateRepository snapshotStateRepository) {
@Nullable SnapshotStateRepository snapshotStateRepository) {
Assert.notNull(pollInterval, "'pollInterval' must not be null");
Assert.notNull(quietPeriod, "'quietPeriod' must not be null");
Assert.isTrue(pollInterval.toMillis() > 0, "'pollInterval' must be positive");
@ -151,7 +153,7 @@ public class FileSystemWatcher { @@ -151,7 +153,7 @@ public class FileSystemWatcher {
* Set an optional {@link FileFilter} used to limit the files that trigger a change.
* @param triggerFilter a trigger filter or null
*/
public void setTriggerFilter(FileFilter triggerFilter) {
public void setTriggerFilter(@Nullable FileFilter triggerFilter) {
synchronized (this.monitor) {
this.triggerFilter = triggerFilter;
}
@ -227,7 +229,7 @@ public class FileSystemWatcher { @@ -227,7 +229,7 @@ public class FileSystemWatcher {
private final List<FileChangeListener> listeners;
private final FileFilter triggerFilter;
private final @Nullable FileFilter triggerFilter;
private final long pollInterval;
@ -237,9 +239,9 @@ public class FileSystemWatcher { @@ -237,9 +239,9 @@ public class FileSystemWatcher {
private final SnapshotStateRepository snapshotStateRepository;
private Watcher(AtomicInteger remainingScans, List<FileChangeListener> listeners, FileFilter triggerFilter,
long pollInterval, long quietPeriod, Map<File, DirectorySnapshot> directories,
SnapshotStateRepository snapshotStateRepository) {
private Watcher(AtomicInteger remainingScans, List<FileChangeListener> listeners,
@Nullable FileFilter triggerFilter, long pollInterval, long quietPeriod,
Map<File, DirectorySnapshot> directories, SnapshotStateRepository snapshotStateRepository) {
this.remainingScans = remainingScans;
this.listeners = listeners;
this.triggerFilter = triggerFilter;
@ -289,6 +291,7 @@ public class FileSystemWatcher { @@ -289,6 +291,7 @@ public class FileSystemWatcher {
for (Map.Entry<File, DirectorySnapshot> entry : previous.entrySet()) {
DirectorySnapshot previousDirectory = entry.getValue();
DirectorySnapshot currentDirectory = current.get(entry.getKey());
Assert.state(currentDirectory != null, "'currentDirectory' must not be null");
if (!previousDirectory.equals(currentDirectory, this.triggerFilter)) {
return true;
}
@ -310,6 +313,7 @@ public class FileSystemWatcher { @@ -310,6 +313,7 @@ public class FileSystemWatcher {
for (DirectorySnapshot snapshot : snapshots) {
DirectorySnapshot previous = this.directories.get(snapshot.getDirectory());
updated.put(snapshot.getDirectory(), snapshot);
Assert.state(previous != null, "'previous' must not be null");
ChangedFiles changedFiles = previous.getChangedFiles(snapshot, this.triggerFilter);
if (!changedFiles.getFiles().isEmpty()) {
changeSet.add(changedFiles);

6
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/filewatch/SnapshotStateRepository.java

@ -16,6 +16,8 @@ @@ -16,6 +16,8 @@
package org.springframework.boot.devtools.filewatch;
import org.jspecify.annotations.Nullable;
/**
* Repository used by {@link FileSystemWatcher} to save file/directory snapshots across
* restarts.
@ -35,7 +37,7 @@ public interface SnapshotStateRepository { @@ -35,7 +37,7 @@ public interface SnapshotStateRepository {
}
@Override
public Object restore() {
public @Nullable Object restore() {
return null;
}
@ -57,6 +59,6 @@ public interface SnapshotStateRepository { @@ -57,6 +59,6 @@ public interface SnapshotStateRepository {
* Restore any previously saved state.
* @return the previously saved state or {@code null}
*/
Object restore();
@Nullable Object restore();
}

6
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/filewatch/StaticSnapshotStateRepository.java

@ -16,6 +16,8 @@ @@ -16,6 +16,8 @@
package org.springframework.boot.devtools.filewatch;
import org.jspecify.annotations.Nullable;
/**
* {@link SnapshotStateRepository} that uses a single static instance.
*
@ -25,7 +27,7 @@ class StaticSnapshotStateRepository implements SnapshotStateRepository { @@ -25,7 +27,7 @@ class StaticSnapshotStateRepository implements SnapshotStateRepository {
static final StaticSnapshotStateRepository INSTANCE = new StaticSnapshotStateRepository();
private volatile Object state;
private volatile @Nullable Object state;
@Override
public void save(Object state) {
@ -33,7 +35,7 @@ class StaticSnapshotStateRepository implements SnapshotStateRepository { @@ -33,7 +35,7 @@ class StaticSnapshotStateRepository implements SnapshotStateRepository {
}
@Override
public Object restore() {
public @Nullable Object restore() {
return this.state;
}

3
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/filewatch/package-info.java

@ -17,4 +17,7 @@ @@ -17,4 +17,7 @@
/**
* Class to watch the local filesystem for changes.
*/
@NullMarked
package org.springframework.boot.devtools.filewatch;
import org.jspecify.annotations.NullMarked;

7
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/livereload/LiveReloadServer.java

@ -32,6 +32,7 @@ import java.util.concurrent.atomic.AtomicInteger; @@ -32,6 +32,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jspecify.annotations.Nullable;
import org.springframework.core.log.LogMessage;
import org.springframework.util.Assert;
@ -63,9 +64,9 @@ public class LiveReloadServer { @@ -63,9 +64,9 @@ public class LiveReloadServer {
private final ThreadFactory threadFactory;
private ServerSocket serverSocket;
private @Nullable ServerSocket serverSocket;
private Thread listenThread;
private @Nullable Thread listenThread;
/**
* Create a new {@link LiveReloadServer} listening on the default port.
@ -140,6 +141,7 @@ public class LiveReloadServer { @@ -140,6 +141,7 @@ public class LiveReloadServer {
}
private void acceptConnections() {
Assert.state(this.serverSocket != null, "'serverSocket' must not be null");
do {
try {
Socket socket = this.serverSocket.accept();
@ -173,6 +175,7 @@ public class LiveReloadServer { @@ -173,6 +175,7 @@ public class LiveReloadServer {
catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
Assert.state(this.serverSocket != null, "'serverSocket' must not be null");
this.serverSocket.close();
try {
this.listenThread.join();

3
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/livereload/package-info.java

@ -17,4 +17,7 @@ @@ -17,4 +17,7 @@
/**
* Support for the livereload protocol.
*/
@NullMarked
package org.springframework.boot.devtools.livereload;
import org.jspecify.annotations.NullMarked;

3
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/logger/package-info.java

@ -17,4 +17,7 @@ @@ -17,4 +17,7 @@
/**
* Devtools specific logging concerns.
*/
@NullMarked
package org.springframework.boot.devtools.logger;
import org.jspecify.annotations.NullMarked;

3
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/package-info.java

@ -17,4 +17,7 @@ @@ -17,4 +17,7 @@
/**
* Spring Boot developer tools.
*/
@NullMarked
package org.springframework.boot.devtools;
import org.jspecify.annotations.NullMarked;

1
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/remote/client/ClassPathChangeUploader.java

@ -155,6 +155,7 @@ public class ClassPathChangeUploader implements ApplicationListener<ClassPathCha @@ -155,6 +155,7 @@ public class ClassPathChangeUploader implements ApplicationListener<ClassPathCha
private ClassLoaderFile asClassLoaderFile(ChangedFile changedFile) throws IOException {
ClassLoaderFile.Kind kind = TYPE_MAPPINGS.get(changedFile.getType());
Assert.state(kind != null, "'kind' must not be null");
byte[] bytes = (kind != Kind.DELETED) ? FileCopyUtils.copyToByteArray(changedFile.getFile()) : null;
long lastModified = (kind != Kind.DELETED) ? changedFile.getFile().lastModified() : System.currentTimeMillis();
return new ClassLoaderFile(kind, lastModified, bytes);

5
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/remote/client/RemoteClientConfiguration.java

@ -26,6 +26,7 @@ import java.util.concurrent.Executors; @@ -26,6 +26,7 @@ import java.util.concurrent.Executors;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jspecify.annotations.Nullable;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.ObjectProvider;
@ -77,7 +78,7 @@ public class RemoteClientConfiguration implements InitializingBean { @@ -77,7 +78,7 @@ public class RemoteClientConfiguration implements InitializingBean {
private final DevToolsProperties properties;
@Value("${remoteUrl}")
private String remoteUrl;
private @Nullable String remoteUrl;
public RemoteClientConfiguration(DevToolsProperties properties) {
this.properties = properties;
@ -119,7 +120,7 @@ public class RemoteClientConfiguration implements InitializingBean { @@ -119,7 +120,7 @@ public class RemoteClientConfiguration implements InitializingBean {
if (!remoteProperties.getRestart().isEnabled()) {
logger.warn("Remote restart is disabled.");
}
if (!this.remoteUrl.startsWith("https://")) {
if (this.remoteUrl == null || !this.remoteUrl.startsWith("https://")) {
logger.warn(LogMessage.format(
"The connection to %s is insecure. You should use a URL starting with 'https://'.",
this.remoteUrl));

3
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/remote/client/package-info.java

@ -17,4 +17,7 @@ @@ -17,4 +17,7 @@
/**
* Client support for a remotely running Spring Boot application.
*/
@NullMarked
package org.springframework.boot.devtools.remote.client;
import org.jspecify.annotations.NullMarked;

4
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/remote/server/HandlerMapper.java

@ -16,6 +16,8 @@ @@ -16,6 +16,8 @@
package org.springframework.boot.devtools.remote.server;
import org.jspecify.annotations.Nullable;
import org.springframework.http.server.ServerHttpRequest;
/**
@ -33,6 +35,6 @@ public interface HandlerMapper { @@ -33,6 +35,6 @@ public interface HandlerMapper {
* @param request the request
* @return a {@link Handler} or {@code null}
*/
Handler getHandler(ServerHttpRequest request);
@Nullable Handler getHandler(ServerHttpRequest request);
}

4
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/remote/server/UrlHandlerMapper.java

@ -16,6 +16,8 @@ @@ -16,6 +16,8 @@
package org.springframework.boot.devtools.remote.server;
import org.jspecify.annotations.Nullable;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.util.Assert;
@ -45,7 +47,7 @@ public class UrlHandlerMapper implements HandlerMapper { @@ -45,7 +47,7 @@ public class UrlHandlerMapper implements HandlerMapper {
}
@Override
public Handler getHandler(ServerHttpRequest request) {
public @Nullable Handler getHandler(ServerHttpRequest request) {
if (this.requestUri.equals(request.getURI().getPath())) {
return this.handler;
}

3
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/remote/server/package-info.java

@ -17,4 +17,7 @@ @@ -17,4 +17,7 @@
/**
* Server support for a remotely running Spring Boot application.
*/
@NullMarked
package org.springframework.boot.devtools.remote.server;
import org.jspecify.annotations.NullMarked;

4
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/AgentReloader.java

@ -20,6 +20,8 @@ import java.util.Collections; @@ -20,6 +20,8 @@ import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import org.jspecify.annotations.Nullable;
import org.springframework.util.ClassUtils;
/**
@ -52,7 +54,7 @@ public abstract class AgentReloader { @@ -52,7 +54,7 @@ public abstract class AgentReloader {
|| isActive(ClassLoader.getSystemClassLoader());
}
private static boolean isActive(ClassLoader classLoader) {
private static boolean isActive(@Nullable ClassLoader classLoader) {
for (String agentClass : AGENT_CLASSES) {
if (ClassUtils.isPresent(agentClass, classLoader)) {
return true;

12
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/ClassLoaderFilesResourcePatternResolver.java

@ -27,6 +27,8 @@ import java.util.List; @@ -27,6 +27,8 @@ import java.util.List;
import java.util.Map.Entry;
import java.util.function.Supplier;
import org.jspecify.annotations.Nullable;
import org.springframework.boot.devtools.restart.classloader.ClassLoaderFile;
import org.springframework.boot.devtools.restart.classloader.ClassLoaderFile.Kind;
import org.springframework.boot.devtools.restart.classloader.ClassLoaderFileURLStreamHandler;
@ -77,7 +79,7 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe @@ -77,7 +79,7 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe
.getResourcePatternResolver(applicationContext, retrieveResourceLoader(applicationContext));
}
private ResourceLoader retrieveResourceLoader(ApplicationContext applicationContext) {
private @Nullable ResourceLoader retrieveResourceLoader(ApplicationContext applicationContext) {
Field field = ReflectionUtils.findField(applicationContext.getClass(), "resourceLoader", ResourceLoader.class);
if (field == null) {
return null;
@ -94,7 +96,7 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe @@ -94,7 +96,7 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe
}
@Override
public ClassLoader getClassLoader() {
public @Nullable ClassLoader getClassLoader() {
return this.patternResolverDelegate.getClassLoader();
}
@ -200,7 +202,7 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe @@ -200,7 +202,7 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe
private static class ResourcePatternResolverFactory {
ResourcePatternResolver getResourcePatternResolver(AbstractApplicationContext applicationContext,
ResourceLoader resourceLoader) {
@Nullable ResourceLoader resourceLoader) {
ResourceLoader targetResourceLoader = (resourceLoader != null) ? resourceLoader
: new ApplicationContextResourceLoader(applicationContext::getProtocolResolvers);
return new PathMatchingResourcePatternResolver(targetResourceLoader);
@ -216,7 +218,7 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe @@ -216,7 +218,7 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe
@Override
public ResourcePatternResolver getResourcePatternResolver(AbstractApplicationContext applicationContext,
ResourceLoader resourceLoader) {
@Nullable ResourceLoader resourceLoader) {
if (applicationContext instanceof WebApplicationContext) {
return getServletContextResourcePatternResolver(applicationContext, resourceLoader);
}
@ -224,7 +226,7 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe @@ -224,7 +226,7 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe
}
private ResourcePatternResolver getServletContextResourcePatternResolver(
AbstractApplicationContext applicationContext, ResourceLoader resourceLoader) {
AbstractApplicationContext applicationContext, @Nullable ResourceLoader resourceLoader) {
ResourceLoader targetResourceLoader = (resourceLoader != null) ? resourceLoader
: new WebApplicationContextResourceLoader(applicationContext::getProtocolResolvers,
(WebApplicationContext) applicationContext);

4
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/DefaultRestartInitializer.java

@ -18,6 +18,8 @@ package org.springframework.boot.devtools.restart; @@ -18,6 +18,8 @@ package org.springframework.boot.devtools.restart;
import java.net.URL;
import org.jspecify.annotations.Nullable;
import org.springframework.boot.devtools.system.DevToolsEnablementDeducer;
/**
@ -32,7 +34,7 @@ import org.springframework.boot.devtools.system.DevToolsEnablementDeducer; @@ -32,7 +34,7 @@ import org.springframework.boot.devtools.system.DevToolsEnablementDeducer;
public class DefaultRestartInitializer implements RestartInitializer {
@Override
public URL[] getInitialUrls(Thread thread) {
public URL @Nullable [] getInitialUrls(Thread thread) {
if (!isMain(thread)) {
return null;
}

4
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/MainMethod.java

@ -19,6 +19,8 @@ package org.springframework.boot.devtools.restart; @@ -19,6 +19,8 @@ package org.springframework.boot.devtools.restart;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
/**
@ -57,7 +59,7 @@ class MainMethod { @@ -57,7 +59,7 @@ class MainMethod {
return className.startsWith("org.springframework.boot.loader.");
}
private Method getMainMethod(StackTraceElement element) {
private @Nullable Method getMainMethod(StackTraceElement element) {
try {
Class<?> elementClass = Class.forName(element.getClassName());
Method method = elementClass.getDeclaredMethod("main", String[].class);

4
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/OnInitializedRestarterCondition.java

@ -16,6 +16,8 @@ @@ -16,6 +16,8 @@
package org.springframework.boot.devtools.restart;
import org.jspecify.annotations.Nullable;
import org.springframework.boot.autoconfigure.condition.ConditionMessage;
import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
@ -44,7 +46,7 @@ class OnInitializedRestarterCondition extends SpringBootCondition { @@ -44,7 +46,7 @@ class OnInitializedRestarterCondition extends SpringBootCondition {
return ConditionOutcome.match(message.because("available and initialized"));
}
private Restarter getRestarter() {
private @Nullable Restarter getRestarter() {
try {
return Restarter.getInstance();
}

4
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/RestartInitializer.java

@ -18,6 +18,8 @@ package org.springframework.boot.devtools.restart; @@ -18,6 +18,8 @@ package org.springframework.boot.devtools.restart;
import java.net.URL;
import org.jspecify.annotations.Nullable;
/**
* Strategy interface used to initialize a {@link Restarter}.
*
@ -39,6 +41,6 @@ public interface RestartInitializer { @@ -39,6 +41,6 @@ public interface RestartInitializer {
* @param thread the source thread
* @return initial URLs or {@code null}
*/
URL[] getInitialUrls(Thread thread);
URL @Nullable [] getInitialUrls(Thread thread);
}

6
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/RestartLauncher.java

@ -18,6 +18,8 @@ package org.springframework.boot.devtools.restart; @@ -18,6 +18,8 @@ package org.springframework.boot.devtools.restart;
import java.lang.reflect.Method;
import org.jspecify.annotations.Nullable;
/**
* Thread used to launch a restarted application.
*
@ -29,7 +31,7 @@ class RestartLauncher extends Thread { @@ -29,7 +31,7 @@ class RestartLauncher extends Thread {
private final String[] args;
private Throwable error;
private @Nullable Throwable error;
RestartLauncher(ClassLoader classLoader, String mainClassName, String[] args,
UncaughtExceptionHandler exceptionHandler) {
@ -55,7 +57,7 @@ class RestartLauncher extends Thread { @@ -55,7 +57,7 @@ class RestartLauncher extends Thread {
}
}
Throwable getError() {
@Nullable Throwable getError() {
return this.error;
}

6
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/RestartScopeInitializer.java

@ -16,6 +16,8 @@ @@ -16,6 +16,8 @@
package org.springframework.boot.devtools.restart;
import org.jspecify.annotations.Nullable;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.config.Scope;
import org.springframework.context.ApplicationContextInitializer;
@ -54,12 +56,12 @@ public class RestartScopeInitializer implements ApplicationContextInitializer<Co @@ -54,12 +56,12 @@ public class RestartScopeInitializer implements ApplicationContextInitializer<Co
}
@Override
public Object resolveContextualObject(String key) {
public @Nullable Object resolveContextualObject(String key) {
return null;
}
@Override
public String getConversationId() {
public @Nullable String getConversationId() {
return null;
}

28
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/Restarter.java

@ -38,6 +38,7 @@ import java.util.concurrent.locks.ReentrantLock; @@ -38,6 +38,7 @@ import java.util.concurrent.locks.ReentrantLock;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jspecify.annotations.Nullable;
import org.springframework.beans.CachedIntrospectionResults;
import org.springframework.beans.factory.ObjectFactory;
@ -86,7 +87,7 @@ public class Restarter { @@ -86,7 +87,7 @@ public class Restarter {
private static final String[] NO_ARGS = {};
private static Restarter instance;
private static @Nullable Restarter instance;
private final Set<URL> urls = new LinkedHashSet<>();
@ -106,9 +107,9 @@ public class Restarter { @@ -106,9 +107,9 @@ public class Restarter {
private boolean enabled = true;
private final URL[] initialUrls;
private final URL @Nullable [] initialUrls;
private final String mainClassName;
private final @Nullable String mainClassName;
private final ClassLoader applicationClassLoader;
@ -145,7 +146,7 @@ public class Restarter { @@ -145,7 +146,7 @@ public class Restarter {
this.leakSafeThreads.add(new LeakSafeThread());
}
private String getMainClassName(Thread thread) {
private @Nullable String getMainClassName(Thread thread) {
try {
return new MainMethod(thread).getDeclaringClassName();
}
@ -170,7 +171,7 @@ public class Restarter { @@ -170,7 +171,7 @@ public class Restarter {
getLeakSafeThread().callAndWait(() -> {
start(FailureHandler.NONE);
cleanupCaches();
return null;
return new Object();
});
}
catch (Exception ex) {
@ -249,7 +250,7 @@ public class Restarter { @@ -249,7 +250,7 @@ public class Restarter {
getLeakSafeThread().call(() -> {
Restarter.this.stop();
Restarter.this.start(failureHandler);
return null;
return new Object();
});
}
@ -271,7 +272,7 @@ public class Restarter { @@ -271,7 +272,7 @@ public class Restarter {
while (true);
}
private Throwable doStart() throws Exception {
private @Nullable Throwable doStart() throws Exception {
Assert.state(this.mainClassName != null, "Unable to find the main class to restart");
URL[] urls = this.urls.toArray(new URL[0]);
ClassLoaderFiles updatedFiles = new ClassLoaderFiles(this.classLoaderFiles);
@ -288,7 +289,8 @@ public class Restarter { @@ -288,7 +289,8 @@ public class Restarter {
* @return any exception that caused the launch to fail or {@code null}
* @throws Exception in case of errors
*/
protected Throwable relaunch(ClassLoader classLoader) throws Exception {
protected @Nullable Throwable relaunch(ClassLoader classLoader) throws Exception {
Assert.state(this.mainClassName != null, "'mainClassName' must not be null");
RestartLauncher launcher = new RestartLauncher(classLoader, this.mainClassName, this.args,
this.exceptionHandler);
launcher.start();
@ -417,7 +419,7 @@ public class Restarter { @@ -417,7 +419,7 @@ public class Restarter {
this.rootContexts.add(applicationContext);
}
void remove(ConfigurableApplicationContext applicationContext) {
void remove(@Nullable ConfigurableApplicationContext applicationContext) {
if (applicationContext != null) {
this.rootContexts.remove(applicationContext);
}
@ -456,7 +458,7 @@ public class Restarter { @@ -456,7 +458,7 @@ public class Restarter {
* Return the initial set of URLs as configured by the {@link RestartInitializer}.
* @return the initial URLs or {@code null}
*/
public URL[] getInitialUrls() {
public URL @Nullable [] getInitialUrls() {
return this.initialUrls;
}
@ -575,9 +577,9 @@ public class Restarter { @@ -575,9 +577,9 @@ public class Restarter {
*/
private class LeakSafeThread extends Thread {
private Callable<?> callable;
private @Nullable Callable<?> callable;
private Object result;
private @Nullable Object result;
LeakSafeThread() {
setDaemon(false);
@ -594,6 +596,7 @@ public class Restarter { @@ -594,6 +596,7 @@ public class Restarter {
start();
try {
join();
Assert.state(this.result != null, "'this.result' must not be null");
return (V) this.result;
}
catch (InterruptedException ex) {
@ -609,6 +612,7 @@ public class Restarter { @@ -609,6 +612,7 @@ public class Restarter {
// RestartClassLoader
try {
Restarter.this.leakSafeThreads.put(new LeakSafeThread());
Assert.state(this.callable != null, "'callable' must not be null");
this.result = this.callable.call();
}
catch (Exception ex) {

6
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/SilentExitExceptionHandler.java

@ -20,6 +20,8 @@ import java.lang.Thread.UncaughtExceptionHandler; @@ -20,6 +20,8 @@ import java.lang.Thread.UncaughtExceptionHandler;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import org.jspecify.annotations.Nullable;
/**
* {@link UncaughtExceptionHandler} decorator that allows a thread to exit silently.
*
@ -28,9 +30,9 @@ import java.util.Arrays; @@ -28,9 +30,9 @@ import java.util.Arrays;
*/
class SilentExitExceptionHandler implements UncaughtExceptionHandler {
private final UncaughtExceptionHandler delegate;
private final @Nullable UncaughtExceptionHandler delegate;
SilentExitExceptionHandler(UncaughtExceptionHandler delegate) {
SilentExitExceptionHandler(@Nullable UncaughtExceptionHandler delegate) {
this.delegate = delegate;
}

10
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/classloader/ClassLoaderFile.java

@ -16,8 +16,11 @@ @@ -16,8 +16,11 @@
package org.springframework.boot.devtools.restart.classloader;
import java.io.Serial;
import java.io.Serializable;
import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
/**
@ -30,11 +33,12 @@ import org.springframework.util.Assert; @@ -30,11 +33,12 @@ import org.springframework.util.Assert;
*/
public class ClassLoaderFile implements Serializable {
@Serial
private static final long serialVersionUID = 1;
private final Kind kind;
private final byte[] contents;
private final byte @Nullable [] contents;
private final long lastModified;
@ -53,7 +57,7 @@ public class ClassLoaderFile implements Serializable { @@ -53,7 +57,7 @@ public class ClassLoaderFile implements Serializable {
* @param lastModified the last modified time
* @param contents the file contents
*/
public ClassLoaderFile(Kind kind, long lastModified, byte[] contents) {
public ClassLoaderFile(Kind kind, long lastModified, byte @Nullable [] contents) {
Assert.notNull(kind, "'kind' must not be null");
if (kind == Kind.DELETED) {
Assert.isTrue(contents == null, "'contents' must be null");
@ -87,7 +91,7 @@ public class ClassLoaderFile implements Serializable { @@ -87,7 +91,7 @@ public class ClassLoaderFile implements Serializable {
* {@link #getKind()} is {@link Kind#DELETED}.
* @return the contents or {@code null}
*/
public byte[] getContents() {
public byte @Nullable [] getContents() {
return this.contents;
}

4
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/classloader/ClassLoaderFileRepository.java

@ -16,6 +16,8 @@ @@ -16,6 +16,8 @@
package org.springframework.boot.devtools.restart.classloader;
import org.jspecify.annotations.Nullable;
/**
* A container for files that may be served from a {@link ClassLoader}. Can be used to
* represent files that have been added, modified or deleted since the original JAR was
@ -39,6 +41,6 @@ public interface ClassLoaderFileRepository { @@ -39,6 +41,6 @@ public interface ClassLoaderFileRepository {
* @param name the name of the file
* @return a {@link ClassLoaderFile} or {@code null}
*/
ClassLoaderFile getFile(String name);
@Nullable ClassLoaderFile getFile(String name);
}

8
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/classloader/ClassLoaderFiles.java

@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
package org.springframework.boot.devtools.restart.classloader;
import java.io.Serial;
import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
@ -26,6 +27,8 @@ import java.util.Set; @@ -26,6 +27,8 @@ import java.util.Set;
import javax.management.loading.ClassLoaderRepository;
import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
/**
@ -133,7 +136,7 @@ public class ClassLoaderFiles implements ClassLoaderFileRepository, Serializable @@ -133,7 +136,7 @@ public class ClassLoaderFiles implements ClassLoaderFileRepository, Serializable
}
@Override
public ClassLoaderFile getFile(String name) {
public @Nullable ClassLoaderFile getFile(String name) {
for (SourceDirectory sourceDirectory : this.sourceDirectories.values()) {
ClassLoaderFile file = sourceDirectory.get(name);
if (file != null) {
@ -148,6 +151,7 @@ public class ClassLoaderFiles implements ClassLoaderFileRepository, Serializable @@ -148,6 +151,7 @@ public class ClassLoaderFiles implements ClassLoaderFileRepository, Serializable
*/
public static class SourceDirectory implements Serializable {
@Serial
private static final long serialVersionUID = 1;
private final String name;
@ -170,7 +174,7 @@ public class ClassLoaderFiles implements ClassLoaderFileRepository, Serializable @@ -170,7 +174,7 @@ public class ClassLoaderFiles implements ClassLoaderFileRepository, Serializable
this.files.remove(name);
}
protected final ClassLoaderFile get(String name) {
protected final @Nullable ClassLoaderFile get(String name) {
return this.files.get(name);
}

13
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/classloader/RestartClassLoader.java

@ -23,6 +23,8 @@ import java.net.URLClassLoader; @@ -23,6 +23,8 @@ import java.net.URLClassLoader;
import java.security.ProtectionDomain;
import java.util.Enumeration;
import org.jspecify.annotations.Nullable;
import org.springframework.boot.devtools.restart.classloader.ClassLoaderFile.Kind;
import org.springframework.core.SmartClassLoader;
import org.springframework.util.Assert;
@ -80,7 +82,7 @@ public class RestartClassLoader extends URLClassLoader implements SmartClassLoad @@ -80,7 +82,7 @@ public class RestartClassLoader extends URLClassLoader implements SmartClassLoad
}
@Override
public URL getResource(String name) {
public @Nullable URL getResource(String name) {
ClassLoaderFile file = this.updatedFiles.getFile(name);
if (file != null && file.getKind() == Kind.DELETED) {
return null;
@ -93,7 +95,7 @@ public class RestartClassLoader extends URLClassLoader implements SmartClassLoad @@ -93,7 +95,7 @@ public class RestartClassLoader extends URLClassLoader implements SmartClassLoad
}
@Override
public URL findResource(String name) {
public @Nullable URL findResource(String name) {
final ClassLoaderFile file = this.updatedFiles.getFile(name);
if (file == null) {
return super.findResource(name);
@ -139,11 +141,12 @@ public class RestartClassLoader extends URLClassLoader implements SmartClassLoad @@ -139,11 +141,12 @@ public class RestartClassLoader extends URLClassLoader implements SmartClassLoad
throw new ClassNotFoundException(name);
}
byte[] bytes = file.getContents();
Assert.state(bytes != null, "'bytes' must not be null");
return defineClass(name, bytes, 0, bytes.length);
}
@Override
public Class<?> publicDefineClass(String name, byte[] b, ProtectionDomain protectionDomain) {
public Class<?> publicDefineClass(String name, byte[] b, @Nullable ProtectionDomain protectionDomain) {
return defineClass(name, b, 0, b.length, protectionDomain);
}
@ -171,11 +174,11 @@ public class RestartClassLoader extends URLClassLoader implements SmartClassLoad @@ -171,11 +174,11 @@ public class RestartClassLoader extends URLClassLoader implements SmartClassLoad
*/
private static class CompoundEnumeration<E> implements Enumeration<E> {
private E firstElement;
private @Nullable E firstElement;
private final Enumeration<E> enumeration;
CompoundEnumeration(E firstElement, Enumeration<E> enumeration) {
CompoundEnumeration(@Nullable E firstElement, Enumeration<E> enumeration) {
this.firstElement = firstElement;
this.enumeration = enumeration;
}

3
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/classloader/package-info.java

@ -17,4 +17,7 @@ @@ -17,4 +17,7 @@
/**
* Classloaders used for reload support.
*/
@NullMarked
package org.springframework.boot.devtools.restart.classloader;
import org.jspecify.annotations.NullMarked;

3
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/package-info.java

@ -17,4 +17,7 @@ @@ -17,4 +17,7 @@
/**
* Application restart support.
*/
@NullMarked
package org.springframework.boot.devtools.restart;
import org.jspecify.annotations.NullMarked;

4
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/server/DefaultSourceDirectoryUrlFilter.java

@ -20,6 +20,8 @@ import java.net.URL; @@ -20,6 +20,8 @@ import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.jspecify.annotations.Nullable;
import org.springframework.util.StringUtils;
/**
@ -46,7 +48,7 @@ public class DefaultSourceDirectoryUrlFilter implements SourceDirectoryUrlFilter @@ -46,7 +48,7 @@ public class DefaultSourceDirectoryUrlFilter implements SourceDirectoryUrlFilter
return isMatch(sourceDirectory, jarName);
}
private String getJarName(URL url) {
private @Nullable String getJarName(URL url) {
Matcher matcher = URL_MODULE_PATTERN.matcher(url.toString());
if (matcher.find()) {
return matcher.group(1);

4
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/server/RestartServer.java

@ -107,7 +107,9 @@ public class RestartServer { @@ -107,7 +107,9 @@ public class RestartServer {
if (classLoaderFile.getKind() == Kind.DELETED) {
return file.delete();
}
FileCopyUtils.copy(classLoaderFile.getContents(), file);
byte[] contents = classLoaderFile.getContents();
Assert.state(contents != null, "'contents' must not be null");
FileCopyUtils.copy(contents, file);
return true;
}
}

3
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/server/package-info.java

@ -17,4 +17,7 @@ @@ -17,4 +17,7 @@
/**
* Remote restart server.
*/
@NullMarked
package org.springframework.boot.devtools.restart.server;
import org.jspecify.annotations.NullMarked;

3
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/settings/DevToolsSettings.java

@ -25,6 +25,7 @@ import java.util.Map; @@ -25,6 +25,7 @@ import java.util.Map;
import java.util.regex.Pattern;
import org.apache.commons.logging.Log;
import org.jspecify.annotations.Nullable;
import org.springframework.boot.devtools.logger.DevToolsLogFactory;
import org.springframework.core.io.UrlResource;
@ -45,7 +46,7 @@ public class DevToolsSettings { @@ -45,7 +46,7 @@ public class DevToolsSettings {
private static final Log logger = DevToolsLogFactory.getLog(DevToolsSettings.class);
private static DevToolsSettings settings;
private static @Nullable DevToolsSettings settings;
private final List<Pattern> restartIncludePatterns = new ArrayList<>();

3
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/settings/package-info.java

@ -17,4 +17,7 @@ @@ -17,4 +17,7 @@
/**
* Classes for loading DevTools settings.
*/
@NullMarked
package org.springframework.boot.devtools.settings;
import org.jspecify.annotations.NullMarked;

3
module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/system/package-info.java

@ -17,4 +17,7 @@ @@ -17,4 +17,7 @@
/**
* Devtools system support classes.
*/
@NullMarked
package org.springframework.boot.devtools.system;
import org.jspecify.annotations.NullMarked;

Loading…
Cancel
Save