Add nullability annotations to tests in module/spring-boot-jetty

See gh-47263
This commit is contained in:
Moritz Halbritter 2025-10-06 12:15:30 +02:00
parent a9bf744b68
commit c92617a015
10 changed files with 44 additions and 17 deletions

View File

@ -48,6 +48,8 @@ dependencies {
testImplementation(testFixtures(project(":core:spring-boot-autoconfigure"))) testImplementation(testFixtures(project(":core:spring-boot-autoconfigure")))
testImplementation("org.apache.httpcomponents.client5:httpclient5") testImplementation("org.apache.httpcomponents.client5:httpclient5")
testCompileOnly("com.google.code.findbugs:jsr305")
testRuntimeOnly("ch.qos.logback:logback-classic") testRuntimeOnly("ch.qos.logback:logback-classic")
testRuntimeOnly("io.projectreactor:reactor-test") testRuntimeOnly("io.projectreactor:reactor-test")
testRuntimeOnly("io.projectreactor.netty:reactor-netty-http") testRuntimeOnly("io.projectreactor.netty:reactor-netty-http")
@ -61,3 +63,6 @@ test {
jvmArgs += "--add-opens=java.base/java.net=ALL-UNNAMED" jvmArgs += "--add-opens=java.base/java.net=ALL-UNNAMED"
} }
tasks.named("compileTestJava") {
options.nullability.checking = "tests"
}

View File

@ -96,7 +96,8 @@ class SslServerCustomizerTests {
void configureSslWhenSslIsEnabledWithNoKeyStoreAndNotPkcs11ThrowsException() { void configureSslWhenSslIsEnabledWithNoKeyStoreAndNotPkcs11ThrowsException() {
Ssl ssl = new Ssl(); Ssl ssl = new Ssl();
assertThatIllegalStateException().isThrownBy(() -> { assertThatIllegalStateException().isThrownBy(() -> {
SslServerCustomizer customizer = new SslServerCustomizer(null, null, null, WebServerSslBundle.get(ssl)); SslServerCustomizer customizer = new SslServerCustomizer(null, new InetSocketAddress(0), null,
WebServerSslBundle.get(ssl));
customizer.configureSsl(new SslContextFactory.Server(), ssl.getClientAuth()); customizer.configureSsl(new SslContextFactory.Server(), ssl.getClientAuth());
}).withMessageContaining("SSL is enabled but no trust material is configured"); }).withMessageContaining("SSL is enabled but no trust material is configured");
} }
@ -110,7 +111,8 @@ class SslServerCustomizerTests {
ssl.setKeyStore("classpath:test.jks"); ssl.setKeyStore("classpath:test.jks");
ssl.setKeyPassword("password"); ssl.setKeyPassword("password");
assertThatIllegalStateException().isThrownBy(() -> { assertThatIllegalStateException().isThrownBy(() -> {
SslServerCustomizer customizer = new SslServerCustomizer(null, null, null, WebServerSslBundle.get(ssl)); SslServerCustomizer customizer = new SslServerCustomizer(null, new InetSocketAddress(0), null,
WebServerSslBundle.get(ssl));
customizer.configureSsl(new SslContextFactory.Server(), ssl.getClientAuth()); customizer.configureSsl(new SslContextFactory.Server(), ssl.getClientAuth());
}).withMessageContaining("must be empty or null for PKCS11 hardware key stores"); }).withMessageContaining("must be empty or null for PKCS11 hardware key stores");
} }
@ -122,7 +124,8 @@ class SslServerCustomizerTests {
ssl.setKeyStoreProvider(MockPkcs11SecurityProvider.NAME); ssl.setKeyStoreProvider(MockPkcs11SecurityProvider.NAME);
ssl.setKeyStorePassword("1234"); ssl.setKeyStorePassword("1234");
assertThatNoException().isThrownBy(() -> { assertThatNoException().isThrownBy(() -> {
SslServerCustomizer customizer = new SslServerCustomizer(null, null, null, WebServerSslBundle.get(ssl)); SslServerCustomizer customizer = new SslServerCustomizer(null, new InetSocketAddress(0), null,
WebServerSslBundle.get(ssl));
customizer.configureSsl(new SslContextFactory.Server(), ssl.getClientAuth()); customizer.configureSsl(new SslContextFactory.Server(), ssl.getClientAuth());
}); });
} }

View File

@ -378,7 +378,9 @@ class JettyWebServerFactoryCustomizerTests {
} }
private BlockingQueue<?> getQueue(ThreadPool threadPool) { private BlockingQueue<?> getQueue(ThreadPool threadPool) {
return ReflectionTestUtils.invokeMethod(threadPool, "getQueue"); BlockingQueue<?> queue = ReflectionTestUtils.invokeMethod(threadPool, "getQueue");
assertThat(queue).isNotNull();
return queue;
} }
private void bind(String... inlinedProperties) { private void bind(String... inlinedProperties) {

View File

@ -217,7 +217,7 @@ class JettyMetricsAutoConfigurationTests {
} }
private ApplicationStartedEvent createApplicationStartedEvent(ConfigurableApplicationContext context) { private ApplicationStartedEvent createApplicationStartedEvent(ConfigurableApplicationContext context) {
return new ApplicationStartedEvent(new SpringApplication(), null, context, null); return new ApplicationStartedEvent(new SpringApplication(), new String[0], context, null);
} }
@Configuration(proxyBeanMethods = false) @Configuration(proxyBeanMethods = false)

View File

@ -76,6 +76,7 @@ class JettyReactiveWebServerAutoConfigurationTests extends AbstractReactiveWebSe
this.serverRunner.run((context) -> { this.serverRunner.run((context) -> {
WebServer webServer = ((ReactiveWebServerApplicationContext) context.getSourceApplicationContext()) WebServer webServer = ((ReactiveWebServerApplicationContext) context.getSourceApplicationContext())
.getWebServer(); .getWebServer();
assertThat(webServer).isNotNull();
ServletContextHandler servletContextHandler = (ServletContextHandler) ((StatisticsHandler) ((JettyWebServer) webServer) ServletContextHandler servletContextHandler = (ServletContextHandler) ((StatisticsHandler) ((JettyWebServer) webServer)
.getServer() .getServer()
.getHandler()).getHandler(); .getHandler()).getHandler();

View File

@ -19,6 +19,7 @@ package org.springframework.boot.jetty.autoconfigure.servlet;
import java.util.Map; import java.util.Map;
import jakarta.servlet.Filter; import jakarta.servlet.Filter;
import jakarta.servlet.ServletContext;
import org.eclipse.jetty.ee11.websocket.servlet.WebSocketUpgradeFilter; import org.eclipse.jetty.ee11.websocket.servlet.WebSocketUpgradeFilter;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -75,9 +76,11 @@ class JettyServletWebServerAutoConfigurationTests extends AbstractServletWebServ
@Test @Test
void jettyWebSocketUpgradeFilterIsAddedToServletContex() { void jettyWebSocketUpgradeFilterIsAddedToServletContex() {
this.serverRunner.run((context) -> assertThat( this.serverRunner.run((context) -> {
context.getServletContext().getFilterRegistration(WebSocketUpgradeFilter.class.getName())) ServletContext servletContext = context.getServletContext();
.isNotNull()); assertThat(servletContext).isNotNull();
assertThat(servletContext.getFilterRegistration(WebSocketUpgradeFilter.class.getName())).isNotNull();
});
} }
@Test @Test

View File

@ -72,6 +72,7 @@ class JettyReactiveWebServerFactoryTests extends AbstractReactiveWebServerFactor
} }
@Test @Test
@SuppressWarnings("NullAway") // Test null check
void setNullServerCustomizersShouldThrowException() { void setNullServerCustomizersShouldThrowException() {
JettyReactiveWebServerFactory factory = getFactory(); JettyReactiveWebServerFactory factory = getFactory();
assertThatIllegalArgumentException().isThrownBy(() -> factory.setServerCustomizers(null)) assertThatIllegalArgumentException().isThrownBy(() -> factory.setServerCustomizers(null))
@ -79,6 +80,7 @@ class JettyReactiveWebServerFactoryTests extends AbstractReactiveWebServerFactor
} }
@Test @Test
@SuppressWarnings("NullAway") // Test null check
void addNullServerCustomizersShouldThrowException() { void addNullServerCustomizersShouldThrowException() {
JettyReactiveWebServerFactory factory = getFactory(); JettyReactiveWebServerFactory factory = getFactory();
assertThatIllegalArgumentException() assertThatIllegalArgumentException()

View File

@ -58,6 +58,7 @@ import org.eclipse.jetty.util.ClassMatcher;
import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.eclipse.jetty.util.thread.ThreadPool; import org.eclipse.jetty.util.thread.ThreadPool;
import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.mockito.InOrder; import org.mockito.InOrder;
@ -123,7 +124,7 @@ class JettyServletWebServerFactoryTests extends AbstractServletWebServerFactoryT
} }
@Override @Override
protected JspServlet getJspServlet() throws Exception { protected @Nullable JspServlet getJspServlet() throws Exception {
WebAppContext context = findWebAppContext((JettyWebServer) this.webServer); WebAppContext context = findWebAppContext((JettyWebServer) this.webServer);
ServletHolder holder = context.getServletHandler().getServlet("jsp"); ServletHolder holder = context.getServletHandler().getServlet("jsp");
if (holder == null) { if (holder == null) {
@ -141,7 +142,7 @@ class JettyServletWebServerFactoryTests extends AbstractServletWebServerFactoryT
} }
@Override @Override
protected Charset getCharset(Locale locale) { protected @Nullable Charset getCharset(Locale locale) {
WebAppContext context = findWebAppContext((JettyWebServer) this.webServer); WebAppContext context = findWebAppContext((JettyWebServer) this.webServer);
String charsetName = context.getLocaleEncoding(locale); String charsetName = context.getLocaleEncoding(locale);
return (charsetName != null) ? Charset.forName(charsetName) : null; return (charsetName != null) ? Charset.forName(charsetName) : null;
@ -314,7 +315,11 @@ class JettyServletWebServerFactoryTests extends AbstractServletWebServerFactoryT
catch (NoSuchMethodError ex) { catch (NoSuchMethodError ex) {
Method getSslContextFactory = ReflectionUtils.findMethod(connectionFactory.getClass(), Method getSslContextFactory = ReflectionUtils.findMethod(connectionFactory.getClass(),
"getSslContextFactory"); "getSslContextFactory");
return (SslContextFactory) ReflectionUtils.invokeMethod(getSslContextFactory, connectionFactory); assertThat(getSslContextFactory).isNotNull();
SslContextFactory sslContextFactory = (SslContextFactory) ReflectionUtils.invokeMethod(getSslContextFactory,
connectionFactory);
assertThat(sslContextFactory).isNotNull();
return sslContextFactory;
} }
} }
@ -528,6 +533,7 @@ class JettyServletWebServerFactoryTests extends AbstractServletWebServerFactoryT
// Jetty 10 // Jetty 10
Method addEventListener = ReflectionUtils.findMethod(context.getClass(), "addEventListener", Method addEventListener = ReflectionUtils.findMethod(context.getClass(), "addEventListener",
EventListener.class); EventListener.class);
assertThat(addEventListener).isNotNull();
ReflectionUtils.invokeMethod(addEventListener, context, eventListener); ReflectionUtils.invokeMethod(addEventListener, context, eventListener);
} }
}); });

View File

@ -70,10 +70,14 @@ class LoaderHidingResourceTests {
URI warUri = createExampleWar(temp); URI warUri = createExampleWar(temp);
Resource resource = new PathResourceFactory().newResource(warUri); Resource resource = new PathResourceFactory().newResource(warUri);
LoaderHidingResource loaderHidingResource = new LoaderHidingResource(resource, resource); LoaderHidingResource loaderHidingResource = new LoaderHidingResource(resource, resource);
assertThat(loaderHidingResource.resolve("/assets/image.jpg").exists()).isTrue(); Resource image = loaderHidingResource.resolve("/assets/image.jpg");
assertThat(loaderHidingResource.resolve("/assets/image.jpg")).isInstanceOf(LoaderHidingResource.class); assertThat(image).isNotNull();
assertThat(loaderHidingResource.resolve("/assets/non-existent.jpg").exists()).isFalse(); assertThat(image.exists()).isTrue();
assertThat(loaderHidingResource.resolve("/assets/non-existent.jpg")).isInstanceOf(LoaderHidingResource.class); assertThat(image).isInstanceOf(LoaderHidingResource.class);
Resource doesntExist = loaderHidingResource.resolve("/assets/non-existent.jpg");
assertThat(doesntExist).isNotNull();
assertThat(doesntExist.exists()).isFalse();
assertThat(doesntExist).isInstanceOf(LoaderHidingResource.class);
assertThat(loaderHidingResource.resolve("/org/springframework/boot/Loader.class")).isNull(); assertThat(loaderHidingResource.resolve("/org/springframework/boot/Loader.class")).isNull();
} }

View File

@ -106,6 +106,7 @@ import org.awaitility.Awaitility;
import org.eclipse.jetty.client.ContentResponse; import org.eclipse.jetty.client.ContentResponse;
import org.eclipse.jetty.http2.client.HTTP2Client; import org.eclipse.jetty.http2.client.HTTP2Client;
import org.eclipse.jetty.http2.client.transport.HttpClientTransportOverHTTP2; import org.eclipse.jetty.http2.client.transport.HttpClientTransportOverHTTP2;
import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -1507,7 +1508,7 @@ public abstract class AbstractServletWebServerFactoryTests {
protected abstract Map<String, String> getActualMimeMappings(); protected abstract Map<String, String> getActualMimeMappings();
protected abstract Charset getCharset(Locale locale); protected abstract @Nullable Charset getCharset(Locale locale);
protected void addTestTxtFile(ConfigurableServletWebServerFactory factory) throws IOException { protected void addTestTxtFile(ConfigurableServletWebServerFactory factory) throws IOException {
FileCopyUtils.copy("test", new FileWriter(new File(this.tempDir, "test.txt"))); FileCopyUtils.copy("test", new FileWriter(new File(this.tempDir, "test.txt")));
@ -1588,7 +1589,7 @@ public abstract class AbstractServletWebServerFactoryTests {
protected abstract ConfigurableServletWebServerFactory getFactory(); protected abstract ConfigurableServletWebServerFactory getFactory();
protected abstract org.apache.jasper.servlet.JspServlet getJspServlet() throws Exception; protected abstract org.apache.jasper.servlet.@Nullable JspServlet getJspServlet() throws Exception;
protected ServletContextInitializer exampleServletRegistration() { protected ServletContextInitializer exampleServletRegistration() {
return new ServletRegistrationBean<>(new ExampleServlet(), "/hello"); return new ServletRegistrationBean<>(new ExampleServlet(), "/hello");