From cea8fed6f87cdabb745fac1c0a10317703e49eed Mon Sep 17 00:00:00 2001 From: Moritz Halbritter Date: Wed, 30 Jul 2025 13:34:21 +0200 Subject: [PATCH] Add nullability annotations to module/spring-boot-mongodb See gh-46587 --- module/spring-boot-mongodb/build.gradle | 2 + .../MongoClientFactorySupport.java | 3 +- .../autoconfigure/MongoConnectionDetails.java | 15 ++-- .../autoconfigure/MongoProperties.java | 89 ++++++++++--------- .../MongoReactiveAutoConfiguration.java | 5 +- .../PropertiesMongoConnectionDetails.java | 7 +- ...dMongoClientSettingsBuilderCustomizer.java | 33 +------ .../autoconfigure/metrics/package-info.java | 3 + .../mongodb/autoconfigure/package-info.java | 3 + .../docker/compose/MongoEnvironment.java | 14 +-- .../mongodb/docker/compose/package-info.java | 3 + ...ongoContainerConnectionDetailsFactory.java | 3 +- .../mongodb/testcontainers/package-info.java | 3 + 13 files changed, 88 insertions(+), 95 deletions(-) diff --git a/module/spring-boot-mongodb/build.gradle b/module/spring-boot-mongodb/build.gradle index 73ffcd2c6f5..470b01e75dc 100644 --- a/module/spring-boot-mongodb/build.gradle +++ b/module/spring-boot-mongodb/build.gradle @@ -28,6 +28,8 @@ description = "Spring Boot MongoDB" dependencies { api(project(":core:spring-boot")) + compileOnly("com.google.code.findbugs:jsr305") + optional(project(":core:spring-boot-autoconfigure")) optional(project(":core:spring-boot-docker-compose")) optional(project(":core:spring-boot-testcontainers")) diff --git a/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/MongoClientFactorySupport.java b/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/MongoClientFactorySupport.java index a96c205a837..5aa6ce3e9d6 100644 --- a/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/MongoClientFactorySupport.java +++ b/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/MongoClientFactorySupport.java @@ -23,6 +23,7 @@ import java.util.function.BiFunction; import com.mongodb.MongoClientSettings; import com.mongodb.MongoClientSettings.Builder; import com.mongodb.MongoDriverInformation; +import org.jspecify.annotations.Nullable; /** * Base class for setup that is common to MongoDB client factories. @@ -38,7 +39,7 @@ public abstract class MongoClientFactorySupport { private final BiFunction clientCreator; - protected MongoClientFactorySupport(List builderCustomizers, + protected MongoClientFactorySupport(@Nullable List builderCustomizers, BiFunction clientCreator) { this.builderCustomizers = (builderCustomizers != null) ? builderCustomizers : Collections.emptyList(); this.clientCreator = clientCreator; diff --git a/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/MongoConnectionDetails.java b/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/MongoConnectionDetails.java index 1f8e45e2ce9..cc544c987a4 100644 --- a/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/MongoConnectionDetails.java +++ b/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/MongoConnectionDetails.java @@ -17,6 +17,7 @@ package org.springframework.boot.mongodb.autoconfigure; import com.mongodb.ConnectionString; +import org.jspecify.annotations.Nullable; import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails; import org.springframework.boot.ssl.SslBundle; @@ -41,7 +42,7 @@ public interface MongoConnectionDetails extends ConnectionDetails { * SSL bundle to use. * @return the SSL bundle to use */ - default SslBundle getSslBundle() { + default @Nullable SslBundle getSslBundle() { return null; } @@ -49,7 +50,7 @@ public interface MongoConnectionDetails extends ConnectionDetails { * GridFS configuration. * @return the GridFS configuration or {@code null} */ - default GridFs getGridFs() { + default @Nullable GridFs getGridFs() { return null; } @@ -62,13 +63,13 @@ public interface MongoConnectionDetails extends ConnectionDetails { * GridFS database name. * @return the GridFS database name or {@code null} */ - String getDatabase(); + @Nullable String getDatabase(); /** * GridFS bucket name. * @return the GridFS bucket name or {@code null} */ - String getBucket(); + @Nullable String getBucket(); /** * Factory method to create a new {@link GridFs} instance. @@ -76,16 +77,16 @@ public interface MongoConnectionDetails extends ConnectionDetails { * @param bucket the bucket name * @return a new {@link GridFs} instance */ - static GridFs of(String database, String bucket) { + static GridFs of(@Nullable String database, @Nullable String bucket) { return new GridFs() { @Override - public String getDatabase() { + public @Nullable String getDatabase() { return database; } @Override - public String getBucket() { + public @Nullable String getBucket() { return bucket; } diff --git a/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/MongoProperties.java b/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/MongoProperties.java index 0c7c038b73e..a55783ffcbe 100644 --- a/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/MongoProperties.java +++ b/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/MongoProperties.java @@ -20,6 +20,7 @@ import java.util.List; import com.mongodb.ConnectionString; import org.bson.UuidRepresentation; +import org.jspecify.annotations.Nullable; import org.springframework.boot.context.properties.ConfigurationProperties; @@ -59,56 +60,56 @@ public class MongoProperties { /** * Mongo server host. Ignored if 'uri' is set. */ - private String host; + private @Nullable String host; /** * Mongo server port. Ignored if 'uri' is set. */ - private Integer port = null; + private @Nullable Integer port; /** * Additional server hosts. Ignored if 'uri' is set or if 'host' is omitted. * Additional hosts will use the default mongo port of 27017. If you want to use a * different port you can use the "host:port" syntax. */ - private List additionalHosts; + private @Nullable List additionalHosts; /** * Mongo database URI. Overrides host, port, username, and password. */ - private String uri; + private @Nullable String uri; /** * Database name. Overrides database in URI. */ - private String database; + private @Nullable String database; /** * Authentication database name. */ - private String authenticationDatabase; + private @Nullable String authenticationDatabase; private final Gridfs gridfs = new Gridfs(); /** * Login user of the mongo server. Ignored if 'uri' is set. */ - private String username; + private @Nullable String username; /** * Login password of the mongo server. Ignored if 'uri' is set. */ - private char[] password; + private char @Nullable [] password; /** * Required replica set name for the cluster. Ignored if 'uri' is set. */ - private String replicaSetName; + private @Nullable String replicaSetName; /** * Fully qualified name of the FieldNamingStrategy to use. */ - private Class fieldNamingStrategy; + private @Nullable Class fieldNamingStrategy; /** * Representation to use when converting a UUID to a BSON binary value. @@ -120,7 +121,7 @@ public class MongoProperties { /** * Whether to enable auto-index creation. */ - private Boolean autoIndexCreation; + private @Nullable Boolean autoIndexCreation; public void setProtocol(String protocol) { this.protocol = protocol; @@ -130,59 +131,59 @@ public class MongoProperties { return this.protocol; } - 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 String getDatabase() { + public @Nullable String getDatabase() { return this.database; } - public void setDatabase(String database) { + public void setDatabase(@Nullable String database) { this.database = database; } - public String getAuthenticationDatabase() { + public @Nullable String getAuthenticationDatabase() { return this.authenticationDatabase; } - public void setAuthenticationDatabase(String authenticationDatabase) { + public void setAuthenticationDatabase(@Nullable String authenticationDatabase) { this.authenticationDatabase = authenticationDatabase; } - public String getUsername() { + public @Nullable String getUsername() { return this.username; } - public void setUsername(String username) { + public void setUsername(@Nullable String username) { this.username = username; } - public char[] getPassword() { + public char @Nullable [] getPassword() { return this.password; } - public void setPassword(char[] password) { + public void setPassword(char @Nullable [] password) { this.password = password; } - public String getReplicaSetName() { + public @Nullable String getReplicaSetName() { return this.replicaSetName; } - public void setReplicaSetName(String replicaSetName) { + public void setReplicaSetName(@Nullable String replicaSetName) { this.replicaSetName = replicaSetName; } - public Class getFieldNamingStrategy() { + public @Nullable Class getFieldNamingStrategy() { return this.fieldNamingStrategy; } - public void setFieldNamingStrategy(Class fieldNamingStrategy) { + public void setFieldNamingStrategy(@Nullable Class fieldNamingStrategy) { this.fieldNamingStrategy = fieldNamingStrategy; } @@ -194,7 +195,7 @@ public class MongoProperties { this.uuidRepresentation = uuidRepresentation; } - public String getUri() { + public @Nullable String getUri() { return this.uri; } @@ -202,15 +203,15 @@ public class MongoProperties { return (this.uri != null) ? this.uri : DEFAULT_URI; } - public void setUri(String uri) { + public void setUri(@Nullable String uri) { this.uri = uri; } - public Integer getPort() { + public @Nullable Integer getPort() { return this.port; } - public void setPort(Integer port) { + public void setPort(@Nullable Integer port) { this.port = port; } @@ -218,26 +219,26 @@ public class MongoProperties { return this.gridfs; } - public String getMongoClientDatabase() { + public @Nullable String getMongoClientDatabase() { if (this.database != null) { return this.database; } return new ConnectionString(determineUri()).getDatabase(); } - public Boolean isAutoIndexCreation() { + public @Nullable Boolean isAutoIndexCreation() { return this.autoIndexCreation; } - public void setAutoIndexCreation(Boolean autoIndexCreation) { + public void setAutoIndexCreation(@Nullable Boolean autoIndexCreation) { this.autoIndexCreation = autoIndexCreation; } - public List getAdditionalHosts() { + public @Nullable List getAdditionalHosts() { return this.additionalHosts; } - public void setAdditionalHosts(List additionalHosts) { + public void setAdditionalHosts(@Nullable List additionalHosts) { this.additionalHosts = additionalHosts; } @@ -250,26 +251,26 @@ public class MongoProperties { /** * GridFS database name. */ - private String database; + private @Nullable String database; /** * GridFS bucket name. */ - private String bucket; + private @Nullable String bucket; - public String getDatabase() { + public @Nullable String getDatabase() { return this.database; } - public void setDatabase(String database) { + public void setDatabase(@Nullable String database) { this.database = database; } - public String getBucket() { + public @Nullable String getBucket() { return this.bucket; } - public void setBucket(String bucket) { + public void setBucket(@Nullable String bucket) { this.bucket = bucket; } @@ -281,12 +282,12 @@ public class MongoProperties { * Whether to enable SSL support. Enabled automatically if "bundle" is provided * unless specified otherwise. */ - private Boolean enabled; + private @Nullable Boolean enabled; /** * SSL bundle name. */ - private String bundle; + private @Nullable String bundle; public boolean isEnabled() { return (this.enabled != null) ? this.enabled : this.bundle != null; @@ -296,11 +297,11 @@ public class MongoProperties { this.enabled = enabled; } - public String getBundle() { + public @Nullable String getBundle() { return this.bundle; } - public void setBundle(String bundle) { + public void setBundle(@Nullable String bundle) { this.bundle = bundle; } diff --git a/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/MongoReactiveAutoConfiguration.java b/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/MongoReactiveAutoConfiguration.java index 9b480f90e33..ba542b4f95c 100644 --- a/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/MongoReactiveAutoConfiguration.java +++ b/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/MongoReactiveAutoConfiguration.java @@ -24,6 +24,7 @@ import io.netty.channel.EventLoopGroup; import io.netty.channel.MultiThreadIoEventLoopGroup; import io.netty.channel.nio.NioIoHandler; import io.netty.channel.socket.SocketChannel; +import org.jspecify.annotations.Nullable; import reactor.core.publisher.Flux; import org.springframework.beans.factory.DisposableBean; @@ -107,7 +108,7 @@ public final class MongoReactiveAutoConfiguration { private final ObjectProvider settings; - private volatile EventLoopGroup eventLoopGroup; + private volatile @Nullable EventLoopGroup eventLoopGroup; NettyDriverMongoClientSettingsBuilderCustomizer(ObjectProvider settings) { this.settings = settings; @@ -130,7 +131,7 @@ public final class MongoReactiveAutoConfiguration { } } - private boolean isCustomTransportConfiguration(MongoClientSettings settings) { + private boolean isCustomTransportConfiguration(@Nullable MongoClientSettings settings) { return settings != null && settings.getTransportSettings() != null; } diff --git a/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/PropertiesMongoConnectionDetails.java b/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/PropertiesMongoConnectionDetails.java index fe8ea936158..f726b199589 100644 --- a/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/PropertiesMongoConnectionDetails.java +++ b/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/PropertiesMongoConnectionDetails.java @@ -22,6 +22,7 @@ import java.util.ArrayList; import java.util.List; import com.mongodb.ConnectionString; +import org.jspecify.annotations.Nullable; import org.springframework.boot.mongodb.autoconfigure.MongoProperties.Ssl; import org.springframework.boot.ssl.SslBundle; @@ -42,9 +43,9 @@ public class PropertiesMongoConnectionDetails implements MongoConnectionDetails private final MongoProperties properties; - private final SslBundles sslBundles; + private final @Nullable SslBundles sslBundles; - public PropertiesMongoConnectionDetails(MongoProperties properties, SslBundles sslBundles) { + public PropertiesMongoConnectionDetails(MongoProperties properties, @Nullable SslBundles sslBundles) { this.properties = properties; this.sslBundles = sslBundles; } @@ -106,7 +107,7 @@ public class PropertiesMongoConnectionDetails implements MongoConnectionDetails } @Override - public SslBundle getSslBundle() { + public @Nullable SslBundle getSslBundle() { Ssl ssl = this.properties.getSsl(); if (!ssl.isEnabled()) { return null; diff --git a/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/StandardMongoClientSettingsBuilderCustomizer.java b/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/StandardMongoClientSettingsBuilderCustomizer.java index 05fe31ed338..745ea3996f2 100644 --- a/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/StandardMongoClientSettingsBuilderCustomizer.java +++ b/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/StandardMongoClientSettingsBuilderCustomizer.java @@ -16,13 +16,11 @@ package org.springframework.boot.mongodb.autoconfigure; -import com.mongodb.ConnectionString; import com.mongodb.MongoClientSettings; import com.mongodb.connection.SslSettings; import org.bson.UuidRepresentation; import org.springframework.boot.ssl.SslBundle; -import org.springframework.boot.ssl.SslBundles; import org.springframework.core.Ordered; import org.springframework.util.Assert; @@ -37,23 +35,14 @@ import org.springframework.util.Assert; */ public class StandardMongoClientSettingsBuilderCustomizer implements MongoClientSettingsBuilderCustomizer, Ordered { - private final ConnectionString connectionString; - private final UuidRepresentation uuidRepresentation; private final MongoConnectionDetails connectionDetails; - private final MongoProperties.Ssl ssl; - - private final SslBundles sslBundles; - private int order = 0; public StandardMongoClientSettingsBuilderCustomizer(MongoConnectionDetails connectionDetails, UuidRepresentation uuidRepresentation) { - this.connectionString = null; - this.ssl = null; - this.sslBundles = null; this.connectionDetails = connectionDetails; this.uuidRepresentation = uuidRepresentation; } @@ -61,26 +50,8 @@ public class StandardMongoClientSettingsBuilderCustomizer implements MongoClient @Override public void customize(MongoClientSettings.Builder settingsBuilder) { settingsBuilder.uuidRepresentation(this.uuidRepresentation); - if (this.connectionDetails != null) { - settingsBuilder.applyConnectionString(this.connectionDetails.getConnectionString()); - settingsBuilder.applyToSslSettings(this::configureSslIfNeeded); - } - else { - settingsBuilder.uuidRepresentation(this.uuidRepresentation); - settingsBuilder.applyConnectionString(this.connectionString); - if (this.ssl.isEnabled()) { - settingsBuilder.applyToSslSettings(this::configureSsl); - } - } - } - - private void configureSsl(SslSettings.Builder settings) { - settings.enabled(true); - if (this.ssl.getBundle() != null) { - SslBundle sslBundle = this.sslBundles.getBundle(this.ssl.getBundle()); - Assert.state(!sslBundle.getOptions().isSpecified(), "SSL options cannot be specified with MongoDB"); - settings.context(sslBundle.createSslContext()); - } + settingsBuilder.applyConnectionString(this.connectionDetails.getConnectionString()); + settingsBuilder.applyToSslSettings(this::configureSslIfNeeded); } private void configureSslIfNeeded(SslSettings.Builder settings) { diff --git a/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/metrics/package-info.java b/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/metrics/package-info.java index e8e3d155c13..a72d99d029a 100644 --- a/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/metrics/package-info.java +++ b/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/metrics/package-info.java @@ -17,4 +17,7 @@ /** * Auto-configuration for MongoDB metrics. */ +@NullMarked package org.springframework.boot.mongodb.autoconfigure.metrics; + +import org.jspecify.annotations.NullMarked; diff --git a/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/package-info.java b/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/package-info.java index 222728ddd49..82cdfe2deeb 100644 --- a/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/package-info.java +++ b/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/package-info.java @@ -17,4 +17,7 @@ /** * Auto-configuration for MongoDB. */ +@NullMarked package org.springframework.boot.mongodb.autoconfigure; + +import org.jspecify.annotations.NullMarked; diff --git a/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/docker/compose/MongoEnvironment.java b/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/docker/compose/MongoEnvironment.java index bb7739b9f80..8b3fd173978 100644 --- a/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/docker/compose/MongoEnvironment.java +++ b/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/docker/compose/MongoEnvironment.java @@ -18,6 +18,8 @@ package org.springframework.boot.mongodb.docker.compose; import java.util.Map; +import org.jspecify.annotations.Nullable; + import org.springframework.util.Assert; /** @@ -30,11 +32,11 @@ import org.springframework.util.Assert; */ class MongoEnvironment { - private final String username; + private final @Nullable String username; - private final String password; + private final @Nullable String password; - private final String database; + private final @Nullable String database; MongoEnvironment(Map env) { Assert.state(!env.containsKey("MONGO_INITDB_ROOT_USERNAME_FILE"), @@ -46,15 +48,15 @@ class MongoEnvironment { this.database = env.getOrDefault("MONGO_INITDB_DATABASE", env.get("MONGODB_DATABASE")); } - String getUsername() { + @Nullable String getUsername() { return this.username; } - String getPassword() { + @Nullable String getPassword() { return this.password; } - String getDatabase() { + @Nullable String getDatabase() { return this.database; } diff --git a/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/docker/compose/package-info.java b/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/docker/compose/package-info.java index f6d86456114..c1667ba4ab9 100644 --- a/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/docker/compose/package-info.java +++ b/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/docker/compose/package-info.java @@ -17,4 +17,7 @@ /** * Support for Docker Compose MongoDB service connections. */ +@NullMarked package org.springframework.boot.mongodb.docker.compose; + +import org.jspecify.annotations.NullMarked; diff --git a/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/testcontainers/AbstractMongoContainerConnectionDetailsFactory.java b/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/testcontainers/AbstractMongoContainerConnectionDetailsFactory.java index 87226e5c867..5f0bcd1b165 100644 --- a/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/testcontainers/AbstractMongoContainerConnectionDetailsFactory.java +++ b/module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/testcontainers/AbstractMongoContainerConnectionDetailsFactory.java @@ -19,6 +19,7 @@ package org.springframework.boot.mongodb.testcontainers; import java.util.function.Function; import com.mongodb.ConnectionString; +import org.jspecify.annotations.Nullable; import org.testcontainers.containers.GenericContainer; import org.springframework.boot.mongodb.autoconfigure.MongoConnectionDetails; @@ -73,7 +74,7 @@ abstract class AbstractMongoContainerConnectionDetailsFactory