From 1b59d4562140765b6302e2dc155389e736dbd9ad Mon Sep 17 00:00:00 2001 From: Moritz Halbritter Date: Wed, 15 Oct 2025 14:20:41 +0200 Subject: [PATCH] Add nullability annotations to tests in module/spring-boot-tomcat See gh-47263 --- module/spring-boot-tomcat/build.gradle | 4 ++ .../TomcatEmbeddedWebappClassLoaderTests.java | 1 + .../TomcatServerPropertiesTests.java | 5 ++- ...TomcatWebServerFactoryCustomizerTests.java | 3 +- .../TomcatMetricsAutoConfigurationTests.java | 3 +- ...activeWebServerAutoConfigurationTests.java | 1 + .../TomcatReactiveWebServerFactoryTests.java | 10 ++++- .../TomcatServletWebServerFactoryTests.java | 38 +++++++++++++------ .../AbstractServletWebServerFactoryTests.java | 14 ++++--- 9 files changed, 57 insertions(+), 22 deletions(-) diff --git a/module/spring-boot-tomcat/build.gradle b/module/spring-boot-tomcat/build.gradle index 36098c547df..252f953b264 100644 --- a/module/spring-boot-tomcat/build.gradle +++ b/module/spring-boot-tomcat/build.gradle @@ -83,3 +83,7 @@ sourceSets { test { jvmArgs += "--add-opens=java.base/java.net=ALL-UNNAMED" } + +tasks.named("compileTestJava") { + options.nullability.checking = "tests" +} diff --git a/module/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/TomcatEmbeddedWebappClassLoaderTests.java b/module/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/TomcatEmbeddedWebappClassLoaderTests.java index 36285bdf3a9..f7b55c33c8d 100644 --- a/module/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/TomcatEmbeddedWebappClassLoaderTests.java +++ b/module/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/TomcatEmbeddedWebappClassLoaderTests.java @@ -45,6 +45,7 @@ import static org.assertj.core.api.Assertions.assertThat; class TomcatEmbeddedWebappClassLoaderTests { @TempDir + @SuppressWarnings("NullAway.Init") File tempDir; @Test diff --git a/module/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/autoconfigure/TomcatServerPropertiesTests.java b/module/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/autoconfigure/TomcatServerPropertiesTests.java index 70a2587a169..4f730df6cef 100644 --- a/module/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/autoconfigure/TomcatServerPropertiesTests.java +++ b/module/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/autoconfigure/TomcatServerPropertiesTests.java @@ -232,7 +232,10 @@ class TomcatServerPropertiesTests { void tomcatMaxKeepAliveRequestsDefault() throws Exception { AbstractEndpoint endpoint = (AbstractEndpoint) ReflectionTestUtils.getField(getDefaultProtocol(), "endpoint"); - int defaultMaxKeepAliveRequests = (int) ReflectionTestUtils.getField(endpoint, "maxKeepAliveRequests"); + assertThat(endpoint).isNotNull(); + Object value = ReflectionTestUtils.getField(endpoint, "maxKeepAliveRequests"); + assertThat(value).isNotNull(); + int defaultMaxKeepAliveRequests = (int) value; assertThat(this.properties.getMaxKeepAliveRequests()).isEqualTo(defaultMaxKeepAliveRequests); } diff --git a/module/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/autoconfigure/TomcatWebServerFactoryCustomizerTests.java b/module/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/autoconfigure/TomcatWebServerFactoryCustomizerTests.java index 40c5bd2dfad..ccef1fdb82c 100644 --- a/module/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/autoconfigure/TomcatWebServerFactoryCustomizerTests.java +++ b/module/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/autoconfigure/TomcatWebServerFactoryCustomizerTests.java @@ -30,6 +30,7 @@ import org.apache.coyote.AbstractProtocol; import org.apache.coyote.ajp.AbstractAjpProtocol; import org.apache.coyote.http11.AbstractHttp11Protocol; import org.apache.coyote.http2.Http2Protocol; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -655,7 +656,7 @@ class TomcatWebServerFactoryCustomizerTests { customizeAndRunServer(null); } - private void customizeAndRunServer(Consumer consumer) { + private void customizeAndRunServer(@Nullable Consumer consumer) { TomcatWebServer server = customizeAndGetServer(); server.start(); try { diff --git a/module/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/autoconfigure/metrics/TomcatMetricsAutoConfigurationTests.java b/module/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/autoconfigure/metrics/TomcatMetricsAutoConfigurationTests.java index 000c09f448c..a103753bbe4 100644 --- a/module/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/autoconfigure/metrics/TomcatMetricsAutoConfigurationTests.java +++ b/module/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/autoconfigure/metrics/TomcatMetricsAutoConfigurationTests.java @@ -111,13 +111,14 @@ class TomcatMetricsAutoConfigurationTests { } private ApplicationStartedEvent createApplicationStartedEvent(ConfigurableApplicationContext context) { - return new ApplicationStartedEvent(new SpringApplication(), null, context, null); + return new ApplicationStartedEvent(new SpringApplication(), new String[0], context, null); } private void resetTomcatState() { ReflectionTestUtils.setField(Registry.class, "registry", null); AtomicInteger containerCounter = (AtomicInteger) ReflectionTestUtils.getField(TomcatWebServer.class, "containerCounter"); + assertThat(containerCounter).isNotNull(); containerCounter.set(-1); } diff --git a/module/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/autoconfigure/reactive/TomcatReactiveWebServerAutoConfigurationTests.java b/module/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/autoconfigure/reactive/TomcatReactiveWebServerAutoConfigurationTests.java index 76fa89ea0fd..c93b6127960 100644 --- a/module/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/autoconfigure/reactive/TomcatReactiveWebServerAutoConfigurationTests.java +++ b/module/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/autoconfigure/reactive/TomcatReactiveWebServerAutoConfigurationTests.java @@ -128,6 +128,7 @@ class TomcatReactiveWebServerAutoConfigurationTests extends AbstractReactiveWebS this.serverRunner.run((context) -> { WebServer webServer = ((ReactiveWebServerApplicationContext) context.getSourceApplicationContext()) .getWebServer(); + assertThat(webServer).isNotNull(); ServletContext servletContext = findContext(((TomcatWebServer) webServer).getTomcat()).getServletContext(); Object serverContainer = servletContext.getAttribute("jakarta.websocket.server.ServerContainer"); assertThat(serverContainer).isInstanceOf(ServerContainer.class); diff --git a/module/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/reactive/TomcatReactiveWebServerFactoryTests.java b/module/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/reactive/TomcatReactiveWebServerFactoryTests.java index c8a2f2d577d..60d0bb69d0c 100644 --- a/module/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/reactive/TomcatReactiveWebServerFactoryTests.java +++ b/module/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/reactive/TomcatReactiveWebServerFactoryTests.java @@ -132,6 +132,7 @@ class TomcatReactiveWebServerFactoryTests extends AbstractReactiveWebServerFacto } @Test + @SuppressWarnings("NullAway") // Test null check void setNullConnectorCustomizersShouldThrowException() { TomcatReactiveWebServerFactory factory = getFactory(); assertThatIllegalArgumentException().isThrownBy(() -> factory.setConnectorCustomizers(null)) @@ -139,6 +140,7 @@ class TomcatReactiveWebServerFactoryTests extends AbstractReactiveWebServerFacto } @Test + @SuppressWarnings("NullAway") // Test null check void addNullAddConnectorCustomizersShouldThrowException() { TomcatReactiveWebServerFactory factory = getFactory(); assertThatIllegalArgumentException() @@ -147,6 +149,7 @@ class TomcatReactiveWebServerFactoryTests extends AbstractReactiveWebServerFacto } @Test + @SuppressWarnings("NullAway") // Test null check void setNullProtocolHandlerCustomizersShouldThrowException() { TomcatReactiveWebServerFactory factory = getFactory(); assertThatIllegalArgumentException().isThrownBy(() -> factory.setProtocolHandlerCustomizers(null)) @@ -154,6 +157,7 @@ class TomcatReactiveWebServerFactoryTests extends AbstractReactiveWebServerFacto } @Test + @SuppressWarnings("NullAway") // Test null check void addNullProtocolHandlerCustomizersShouldThrowException() { TomcatReactiveWebServerFactory factory = getFactory(); assertThatIllegalArgumentException() @@ -205,6 +209,7 @@ class TomcatReactiveWebServerFactoryTests extends AbstractReactiveWebServerFacto } @Test + @SuppressWarnings("NullAway") // Test null check void addNullAdditionalConnectorsThrows() { TomcatReactiveWebServerFactory factory = getFactory(); assertThatIllegalArgumentException().isThrownBy(() -> factory.addAdditionalConnectors((Connector[]) null)) @@ -277,8 +282,9 @@ class TomcatReactiveWebServerFactoryTests extends AbstractReactiveWebServerFacto @Override protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) { - webServerReference.set(new TomcatWebServer(tomcat)); - return webServerReference.get(); + TomcatWebServer server = new TomcatWebServer(tomcat); + webServerReference.set(server); + return server; } }.getWebServer(new EchoHandler()); diff --git a/module/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/servlet/TomcatServletWebServerFactoryTests.java b/module/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/servlet/TomcatServletWebServerFactoryTests.java index 8236351a9ef..f9362d661aa 100644 --- a/module/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/servlet/TomcatServletWebServerFactoryTests.java +++ b/module/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/servlet/TomcatServletWebServerFactoryTests.java @@ -75,6 +75,7 @@ import org.apache.tomcat.JarScanType; import org.apache.tomcat.util.scan.StandardJarScanFilter; import org.assertj.core.api.ThrowableAssert.ThrowingCallable; import org.awaitility.Awaitility; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.mockito.InOrder; @@ -245,8 +246,10 @@ class TomcatServletWebServerFactoryTests extends AbstractServletWebServerFactory .setProcessorCache(250); factory.addProtocolHandlerCustomizers(customizer); Tomcat tomcat = getTomcat(factory); - Connector connector = TomcatAccess.getServiceConnectors((TomcatWebServer) this.webServer) - .get(tomcat.getService())[0]; + Connector[] connectors = TomcatAccess.getServiceConnectors((TomcatWebServer) this.webServer) + .get(tomcat.getService()); + assertThat(connectors).isNotNull(); + Connector connector = connectors[0]; AbstractHttp11Protocol protocolHandler = (AbstractHttp11Protocol) connector.getProtocolHandler(); assertThat(protocolHandler.getProcessorCache()).isEqualTo(250); } @@ -275,6 +278,7 @@ class TomcatServletWebServerFactoryTests extends AbstractServletWebServerFactory } @Test + @SuppressWarnings("NullAway") // Test null check void addNullAdditionalConnectorThrows() { TomcatServletWebServerFactory factory = getFactory(); assertThatIllegalArgumentException().isThrownBy(() -> factory.addAdditionalConnectors((Connector[]) null)) @@ -312,6 +316,7 @@ class TomcatServletWebServerFactoryTests extends AbstractServletWebServerFactory } @Test + @SuppressWarnings("NullAway") // Test null check void setNullTomcatContextCustomizersThrows() { TomcatServletWebServerFactory factory = getFactory(); assertThatIllegalArgumentException().isThrownBy(() -> factory.setContextCustomizers(null)) @@ -319,6 +324,7 @@ class TomcatServletWebServerFactoryTests extends AbstractServletWebServerFactory } @Test + @SuppressWarnings("NullAway") // Test null check void addNullContextCustomizersThrows() { TomcatServletWebServerFactory factory = getFactory(); assertThatIllegalArgumentException() @@ -327,6 +333,7 @@ class TomcatServletWebServerFactoryTests extends AbstractServletWebServerFactory } @Test + @SuppressWarnings("NullAway") // Test null check void setNullTomcatConnectorCustomizersThrows() { TomcatServletWebServerFactory factory = getFactory(); assertThatIllegalArgumentException().isThrownBy(() -> factory.setConnectorCustomizers(null)) @@ -334,6 +341,7 @@ class TomcatServletWebServerFactoryTests extends AbstractServletWebServerFactory } @Test + @SuppressWarnings("NullAway") // Test null check void addNullConnectorCustomizersThrows() { TomcatServletWebServerFactory factory = getFactory(); assertThatIllegalArgumentException() @@ -342,6 +350,7 @@ class TomcatServletWebServerFactoryTests extends AbstractServletWebServerFactory } @Test + @SuppressWarnings("NullAway") // Test null check void setNullTomcatProtocolHandlerCustomizersThrows() { TomcatServletWebServerFactory factory = getFactory(); assertThatIllegalArgumentException().isThrownBy(() -> factory.setProtocolHandlerCustomizers(null)) @@ -349,6 +358,7 @@ class TomcatServletWebServerFactoryTests extends AbstractServletWebServerFactory } @Test + @SuppressWarnings("NullAway") // Test null check void addNullTomcatProtocolHandlerCustomizersThrows() { TomcatServletWebServerFactory factory = getFactory(); assertThatIllegalArgumentException() @@ -361,8 +371,10 @@ class TomcatServletWebServerFactoryTests extends AbstractServletWebServerFactory TomcatServletWebServerFactory factory = getFactory(); factory.setUriEncoding(StandardCharsets.US_ASCII); Tomcat tomcat = getTomcat(factory); - Connector connector = TomcatAccess.getServiceConnectors((TomcatWebServer) this.webServer) - .get(tomcat.getService())[0]; + Connector[] connectors = TomcatAccess.getServiceConnectors((TomcatWebServer) this.webServer) + .get(tomcat.getService()); + assertThat(connectors).isNotNull(); + Connector connector = connectors[0]; assertThat(connector.getURIEncoding()).isEqualTo("US-ASCII"); } @@ -370,8 +382,10 @@ class TomcatServletWebServerFactoryTests extends AbstractServletWebServerFactory void defaultUriEncoding() { TomcatServletWebServerFactory factory = getFactory(); Tomcat tomcat = getTomcat(factory); - Connector connector = TomcatAccess.getServiceConnectors((TomcatWebServer) this.webServer) - .get(tomcat.getService())[0]; + Connector[] connectors = TomcatAccess.getServiceConnectors((TomcatWebServer) this.webServer) + .get(tomcat.getService()); + assertThat(connectors).isNotNull(); + Connector connector = connectors[0]; assertThat(connector.getURIEncoding()).isEqualTo("UTF-8"); } @@ -553,7 +567,9 @@ class TomcatServletWebServerFactoryTests extends AbstractServletWebServerFactory }); this.webServer = factory.getWebServer(); this.webServer.start(); - File temp = (File) servletContextReference.get().getAttribute(ServletContext.TEMPDIR); + ServletContext servletContext = servletContextReference.get(); + assertThat(servletContext).isNotNull(); + File temp = (File) servletContext.getAttribute(ServletContext.TEMPDIR); FileSystemUtils.deleteRecursively(temp); RestTemplate restTemplate = new RestTemplate(); HttpHeaders headers = new HttpHeaders(); @@ -697,7 +713,7 @@ class TomcatServletWebServerFactoryTests extends AbstractServletWebServerFactory } @Override - protected JspServlet getJspServlet() throws ServletException { + protected @Nullable JspServlet getJspServlet() throws ServletException { Tomcat tomcat = ((TomcatWebServer) this.webServer).getTomcat(); Container container = tomcat.getHost().findChildren()[0]; StandardWrapper standardWrapper = (StandardWrapper) container.findChild("jsp"); @@ -719,7 +735,7 @@ class TomcatServletWebServerFactoryTests extends AbstractServletWebServerFactory } @Override - protected Charset getCharset(Locale locale) { + protected @Nullable Charset getCharset(Locale locale) { Context context = (Context) ((TomcatWebServer) this.webServer).getTomcat().getHost().findChildren()[0]; CharsetMapper mapper = ((TomcatEmbeddedContext) context).getCharsetMapper(); String charsetName = mapper.getCharset(locale); @@ -756,7 +772,7 @@ class TomcatServletWebServerFactoryTests extends AbstractServletWebServerFactory private static final class RememberingHostnameVerifier implements HostnameVerifier { - private volatile String lastPrincipal; + private volatile @Nullable String lastPrincipal; @Override public boolean verify(String hostname, SSLSession session) { @@ -769,7 +785,7 @@ class TomcatServletWebServerFactoryTests extends AbstractServletWebServerFactory return true; } - String getLastPrincipal() { + @Nullable String getLastPrincipal() { return this.lastPrincipal; } diff --git a/module/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/server/servlet/AbstractServletWebServerFactoryTests.java b/module/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/server/servlet/AbstractServletWebServerFactoryTests.java index 7a82c9f73e2..2b6f4617734 100644 --- a/module/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/server/servlet/AbstractServletWebServerFactoryTests.java +++ b/module/spring-boot-web-server/src/testFixtures/java/org/springframework/boot/web/server/servlet/AbstractServletWebServerFactoryTests.java @@ -713,21 +713,23 @@ public abstract class AbstractServletWebServerFactoryTests { assertThat(response.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND); } - protected Ssl getSsl(ClientAuth clientAuth, String keyPassword, String keyStore) { + protected Ssl getSsl(@Nullable ClientAuth clientAuth, @Nullable String keyPassword, @Nullable String keyStore) { return getSsl(clientAuth, keyPassword, keyStore, null, null, null); } - protected Ssl getSsl(ClientAuth clientAuth, String keyPassword, String keyAlias, String keyStore) { + protected Ssl getSsl(@Nullable ClientAuth clientAuth, @Nullable String keyPassword, @Nullable String keyAlias, + @Nullable String keyStore) { return getSsl(clientAuth, keyPassword, keyAlias, keyStore, null, null, null); } - protected Ssl getSsl(ClientAuth clientAuth, String keyPassword, String keyStore, String trustStore, - String[] supportedProtocols, String[] ciphers) { + protected Ssl getSsl(@Nullable ClientAuth clientAuth, @Nullable String keyPassword, @Nullable String keyStore, + @Nullable String trustStore, String @Nullable [] supportedProtocols, String @Nullable [] ciphers) { return getSsl(clientAuth, keyPassword, null, keyStore, trustStore, supportedProtocols, ciphers); } - private Ssl getSsl(ClientAuth clientAuth, String keyPassword, String keyAlias, String keyStore, String trustStore, - String[] supportedProtocols, String[] ciphers) { + private Ssl getSsl(@Nullable ClientAuth clientAuth, @Nullable String keyPassword, @Nullable String keyAlias, + @Nullable String keyStore, @Nullable String trustStore, String @Nullable [] supportedProtocols, + String @Nullable [] ciphers) { Ssl ssl = new Ssl(); ssl.setClientAuth(clientAuth); if (keyPassword != null) {