From 97ad5cb2043ba138b286565a5f4eb18c4da445fd Mon Sep 17 00:00:00 2001 From: Moritz Halbritter Date: Fri, 1 Aug 2025 14:49:05 +0200 Subject: [PATCH] Add nullability annotations to module/spring-boot-ldap See gh-46587 --- .../autoconfigure/LdapConnectionDetails.java | 8 ++-- .../ldap/autoconfigure/LdapProperties.java | 38 ++++++++++--------- .../PropertiesLdapConnectionDetails.java | 8 ++-- .../EmbeddedLdapAutoConfiguration.java | 25 +++++++----- .../embedded/EmbeddedLdapProperties.java | 20 +++++----- .../autoconfigure/embedded/package-info.java | 3 ++ .../autoconfigure/health/package-info.java | 3 ++ .../boot/ldap/autoconfigure/package-info.java | 3 ++ .../ldap/docker/compose/package-info.java | 3 ++ .../boot/ldap/health/LdapHealthIndicator.java | 4 +- .../boot/ldap/health/package-info.java | 3 ++ .../ldap/testcontainers/package-info.java | 3 ++ 12 files changed, 78 insertions(+), 43 deletions(-) diff --git a/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/LdapConnectionDetails.java b/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/LdapConnectionDetails.java index f43734cf08d..334e3e0a7e1 100644 --- a/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/LdapConnectionDetails.java +++ b/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/LdapConnectionDetails.java @@ -16,6 +16,8 @@ package org.springframework.boot.ldap.autoconfigure; +import org.jspecify.annotations.Nullable; + import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails; /** @@ -36,7 +38,7 @@ public interface LdapConnectionDetails extends ConnectionDetails { * Base suffix from which all operations should originate. * @return base suffix */ - default String getBase() { + default @Nullable String getBase() { return null; } @@ -44,7 +46,7 @@ public interface LdapConnectionDetails extends ConnectionDetails { * Login username of the server. * @return login username */ - default String getUsername() { + default @Nullable String getUsername() { return null; } @@ -52,7 +54,7 @@ public interface LdapConnectionDetails extends ConnectionDetails { * Login password of the server. * @return login password */ - default String getPassword() { + default @Nullable String getPassword() { return null; } diff --git a/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/LdapProperties.java b/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/LdapProperties.java index 9e2ac29929b..56d99836bca 100644 --- a/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/LdapProperties.java +++ b/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/LdapProperties.java @@ -19,6 +19,8 @@ package org.springframework.boot.ldap.autoconfigure; import java.util.HashMap; import java.util.Map; +import org.jspecify.annotations.Nullable; + import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.core.env.Environment; import org.springframework.ldap.ReferralException; @@ -40,34 +42,34 @@ public class LdapProperties { /** * LDAP URLs of the server. */ - private String[] urls; + private String @Nullable [] urls; /** * Base suffix from which all operations should originate. */ - private String base; + private @Nullable String base; /** * Login username of the server. */ - private String username; + private @Nullable String username; /** * Login password of the server. */ - private String password; + private @Nullable String password; /** * Whether read-only operations should use an anonymous environment. Disabled by * default unless a username is set. */ - private Boolean anonymousReadOnly; + private @Nullable Boolean anonymousReadOnly; /** * Specify how referrals encountered by the service provider are to be processed. If * not specified, the default is determined by the provider. */ - private Referral referral; + private @Nullable Referral referral; /** * LDAP specification settings. @@ -76,51 +78,51 @@ public class LdapProperties { private final Template template = new Template(); - public String[] getUrls() { + public String @Nullable [] getUrls() { return this.urls; } - public void setUrls(String[] urls) { + public void setUrls(String @Nullable [] urls) { this.urls = urls; } - public String getBase() { + public @Nullable String getBase() { return this.base; } - public void setBase(String base) { + public void setBase(@Nullable String base) { this.base = base; } - 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 String getPassword() { + public @Nullable String getPassword() { return this.password; } - public void setPassword(String password) { + public void setPassword(@Nullable String password) { this.password = password; } - public Boolean getAnonymousReadOnly() { + public @Nullable Boolean getAnonymousReadOnly() { return this.anonymousReadOnly; } - public void setAnonymousReadOnly(Boolean anonymousReadOnly) { + public void setAnonymousReadOnly(@Nullable Boolean anonymousReadOnly) { this.anonymousReadOnly = anonymousReadOnly; } - public Referral getReferral() { + public @Nullable Referral getReferral() { return this.referral; } - public void setReferral(Referral referral) { + public void setReferral(@Nullable Referral referral) { this.referral = referral; } diff --git a/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/PropertiesLdapConnectionDetails.java b/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/PropertiesLdapConnectionDetails.java index 433994841d3..e419570f667 100644 --- a/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/PropertiesLdapConnectionDetails.java +++ b/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/PropertiesLdapConnectionDetails.java @@ -16,6 +16,8 @@ package org.springframework.boot.ldap.autoconfigure; +import org.jspecify.annotations.Nullable; + import org.springframework.core.env.Environment; /** @@ -40,17 +42,17 @@ class PropertiesLdapConnectionDetails implements LdapConnectionDetails { } @Override - public String getBase() { + public @Nullable String getBase() { return this.properties.getBase(); } @Override - public String getUsername() { + public @Nullable String getUsername() { return this.properties.getUsername(); } @Override - public String getPassword() { + public @Nullable String getPassword() { return this.properties.getPassword(); } diff --git a/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/embedded/EmbeddedLdapAutoConfiguration.java b/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/embedded/EmbeddedLdapAutoConfiguration.java index edadbb47545..823ab1dd3e5 100644 --- a/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/embedded/EmbeddedLdapAutoConfiguration.java +++ b/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/embedded/EmbeddedLdapAutoConfiguration.java @@ -28,6 +28,7 @@ import com.unboundid.ldap.listener.InMemoryListenerConfig; import com.unboundid.ldap.sdk.LDAPException; import com.unboundid.ldap.sdk.schema.Schema; import com.unboundid.ldif.LDIFReader; +import org.jspecify.annotations.Nullable; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.RuntimeHintsRegistrar; @@ -83,7 +84,7 @@ public final class EmbeddedLdapAutoConfiguration implements DisposableBean { private final EmbeddedLdapProperties embeddedProperties; - private InMemoryDirectoryServer server; + private @Nullable InMemoryDirectoryServer server; EmbeddedLdapAutoConfiguration(EmbeddedLdapProperties embeddedProperties) { this.embeddedProperties = embeddedProperties; @@ -93,16 +94,17 @@ public final class EmbeddedLdapAutoConfiguration implements DisposableBean { InMemoryDirectoryServer directoryServer(ApplicationContext applicationContext) throws LDAPException { String[] baseDn = StringUtils.toStringArray(this.embeddedProperties.getBaseDn()); InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig(baseDn); - if (this.embeddedProperties.getCredential().isAvailable()) { - config.addAdditionalBindCredentials(this.embeddedProperties.getCredential().getUsername(), - this.embeddedProperties.getCredential().getPassword()); + String username = this.embeddedProperties.getCredential().getUsername(); + String password = this.embeddedProperties.getCredential().getPassword(); + if (StringUtils.hasText(username) && StringUtils.hasText(password)) { + config.addAdditionalBindCredentials(username, password); } setSchema(config); InMemoryListenerConfig listenerConfig = InMemoryListenerConfig.createLDAPConfig("LDAP", this.embeddedProperties.getPort()); config.setListenerConfigs(listenerConfig); this.server = new InMemoryDirectoryServer(config); - importLdif(applicationContext); + importLdif(this.server, applicationContext); this.server.startListening(); setPortProperty(applicationContext, this.server.getListenPort()); return this.server; @@ -123,21 +125,26 @@ public final class EmbeddedLdapAutoConfiguration implements DisposableBean { try { Schema defaultSchema = Schema.getDefaultStandardSchema(); Schema schema = Schema.getSchema(resource.getInputStream()); - config.setSchema(Schema.mergeSchemas(defaultSchema, schema)); + if (schema == null) { + config.setSchema(defaultSchema); + } + else { + config.setSchema(Schema.mergeSchemas(defaultSchema, schema)); + } } catch (Exception ex) { throw new IllegalStateException("Unable to load schema " + resource.getDescription(), ex); } } - private void importLdif(ApplicationContext applicationContext) { + private void importLdif(InMemoryDirectoryServer server, ApplicationContext applicationContext) { String location = this.embeddedProperties.getLdif(); if (StringUtils.hasText(location)) { try { Resource resource = applicationContext.getResource(location); if (resource.exists()) { try (InputStream inputStream = resource.getInputStream()) { - this.server.importFromLDIF(true, new LDIFReader(inputStream)); + server.importFromLDIF(true, new LDIFReader(inputStream)); } } } @@ -221,7 +228,7 @@ public final class EmbeddedLdapAutoConfiguration implements DisposableBean { static class EmbeddedLdapAutoConfigurationRuntimeHints implements RuntimeHintsRegistrar { @Override - public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) { hints.resources() .registerPatternIfPresent(classLoader, "schema.ldif", (hint) -> hint.includes("schema.ldif")); } diff --git a/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/embedded/EmbeddedLdapProperties.java b/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/embedded/EmbeddedLdapProperties.java index e5b7fc97d77..5259660da3d 100644 --- a/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/embedded/EmbeddedLdapProperties.java +++ b/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/embedded/EmbeddedLdapProperties.java @@ -19,6 +19,8 @@ package org.springframework.boot.ldap.autoconfigure.embedded; import java.util.ArrayList; import java.util.List; +import org.jspecify.annotations.Nullable; + import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.convert.Delimiter; import org.springframework.core.io.Resource; @@ -101,26 +103,26 @@ public class EmbeddedLdapProperties { /** * Embedded LDAP username. */ - private String username; + private @Nullable String username; /** * Embedded LDAP password. */ - private String password; + private @Nullable String password; - 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 String getPassword() { + public @Nullable String getPassword() { return this.password; } - public void setPassword(String password) { + public void setPassword(@Nullable String password) { this.password = password; } @@ -140,7 +142,7 @@ public class EmbeddedLdapProperties { /** * Path to the custom schema. */ - private Resource schema; + private @Nullable Resource schema; public boolean isEnabled() { return this.enabled; @@ -150,11 +152,11 @@ public class EmbeddedLdapProperties { this.enabled = enabled; } - public Resource getSchema() { + public @Nullable Resource getSchema() { return this.schema; } - public void setSchema(Resource schema) { + public void setSchema(@Nullable Resource schema) { this.schema = schema; } diff --git a/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/embedded/package-info.java b/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/embedded/package-info.java index 6f280abd4db..914b93fc59e 100644 --- a/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/embedded/package-info.java +++ b/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/embedded/package-info.java @@ -17,4 +17,7 @@ /** * Auto-configuration for embedded LDAP. */ +@NullMarked package org.springframework.boot.ldap.autoconfigure.embedded; + +import org.jspecify.annotations.NullMarked; diff --git a/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/health/package-info.java b/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/health/package-info.java index 73189bd89d3..86958e05730 100644 --- a/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/health/package-info.java +++ b/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/health/package-info.java @@ -17,4 +17,7 @@ /** * Auto-configuration for LDAP health. */ +@NullMarked package org.springframework.boot.ldap.autoconfigure.health; + +import org.jspecify.annotations.NullMarked; diff --git a/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/package-info.java b/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/package-info.java index ade61fdf0e1..b9866c2a4a9 100644 --- a/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/package-info.java +++ b/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/autoconfigure/package-info.java @@ -17,4 +17,7 @@ /** * Auto-configuration for LDAP. */ +@NullMarked package org.springframework.boot.ldap.autoconfigure; + +import org.jspecify.annotations.NullMarked; diff --git a/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/docker/compose/package-info.java b/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/docker/compose/package-info.java index 705f92e30d8..7f392d765dc 100644 --- a/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/docker/compose/package-info.java +++ b/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/docker/compose/package-info.java @@ -17,4 +17,7 @@ /** * Support for Docker Compose LDAP service connections. */ +@NullMarked package org.springframework.boot.ldap.docker.compose; + +import org.jspecify.annotations.NullMarked; diff --git a/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/health/LdapHealthIndicator.java b/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/health/LdapHealthIndicator.java index 6865b5814a9..bb3b9747713 100644 --- a/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/health/LdapHealthIndicator.java +++ b/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/health/LdapHealthIndicator.java @@ -19,6 +19,8 @@ package org.springframework.boot.ldap.health; import javax.naming.NamingException; import javax.naming.directory.DirContext; +import org.jspecify.annotations.Nullable; + import org.springframework.boot.health.contributor.AbstractHealthIndicator; import org.springframework.boot.health.contributor.Health; import org.springframework.boot.health.contributor.HealthIndicator; @@ -54,7 +56,7 @@ public class LdapHealthIndicator extends AbstractHealthIndicator { private static final class VersionContextExecutor implements ContextExecutor { @Override - public String executeWithContext(DirContext ctx) throws NamingException { + public @Nullable String executeWithContext(DirContext ctx) throws NamingException { Object version = ctx.getEnvironment().get("java.naming.ldap.version"); if (version != null) { return (String) version; diff --git a/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/health/package-info.java b/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/health/package-info.java index 427c1cc0874..3085fd0590b 100644 --- a/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/health/package-info.java +++ b/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/health/package-info.java @@ -17,4 +17,7 @@ /** * Health integration for LDAP. */ +@NullMarked package org.springframework.boot.ldap.health; + +import org.jspecify.annotations.NullMarked; diff --git a/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/testcontainers/package-info.java b/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/testcontainers/package-info.java index d4242633be4..fae0792c8e0 100644 --- a/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/testcontainers/package-info.java +++ b/module/spring-boot-ldap/src/main/java/org/springframework/boot/ldap/testcontainers/package-info.java @@ -17,4 +17,7 @@ /** * Support for testcontainers Ldap service connections. */ +@NullMarked package org.springframework.boot.ldap.testcontainers; + +import org.jspecify.annotations.NullMarked;