From 21978cab222638f2a52da260ff56ad44a32d4b98 Mon Sep 17 00:00:00 2001 From: Robert Winch <362503+rwinch@users.noreply.github.com> Date: Thu, 19 Feb 2026 10:17:27 -0600 Subject: [PATCH] Fix Build Errors for Improve AOT RuntimeHits - Saml2RuntimeHints consistently uses String in separate method for to ensure no classpath issues - Fix Whitespace/Checkstyle - Add Missing Nullability Annotations --- .../acls/aot/hint/AclRuntimeHints.java | 43 +++++---- .../security/acls/aot/hint/package-info.java | 3 + .../aot/hint/CoreSecurityRuntimeHints.java | 87 +++++++++++-------- .../kerberos/aot/hint/package-info.java | 3 + .../aot/hint/OAuth2ClientRuntimeHints.java | 10 +-- .../saml2/aot/hint/Saml2RuntimeHints.java | 69 +++++++-------- .../security/saml2/aot/hint/package-info.java | 3 + 7 files changed, 122 insertions(+), 96 deletions(-) diff --git a/acl/src/main/java/org/springframework/security/acls/aot/hint/AclRuntimeHints.java b/acl/src/main/java/org/springframework/security/acls/aot/hint/AclRuntimeHints.java index 7436fdc80a..aed920818b 100644 --- a/acl/src/main/java/org/springframework/security/acls/aot/hint/AclRuntimeHints.java +++ b/acl/src/main/java/org/springframework/security/acls/aot/hint/AclRuntimeHints.java @@ -16,17 +16,27 @@ package org.springframework.security.acls.aot.hint; +import java.util.stream.Stream; + import org.jspecify.annotations.Nullable; + import org.springframework.aot.hint.MemberCategory; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.RuntimeHintsRegistrar; import org.springframework.aot.hint.TypeReference; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; -import org.springframework.security.acls.domain.*; -import org.springframework.security.acls.model.*; - -import java.util.stream.Stream; +import org.springframework.security.acls.domain.AclImpl; +import org.springframework.security.acls.domain.AuditLogger; +import org.springframework.security.acls.domain.BasePermission; +import org.springframework.security.acls.domain.GrantedAuthoritySid; +import org.springframework.security.acls.domain.ObjectIdentityImpl; +import org.springframework.security.acls.domain.PrincipalSid; +import org.springframework.security.acls.model.AccessControlEntry; +import org.springframework.security.acls.model.Acl; +import org.springframework.security.acls.model.AuditableAccessControlEntry; +import org.springframework.security.acls.model.ObjectIdentity; +import org.springframework.security.acls.model.Sid; /** * {@link RuntimeHintsRegistrar} for ACL (Access Control List) classes. @@ -43,26 +53,21 @@ class AclRuntimeHints implements RuntimeHintsRegistrar { private void registerAclDomainHints(RuntimeHints hints) { // Register core ACL domain types - Stream.of(Acl.class, AccessControlEntry.class, AuditableAccessControlEntry.class, - ObjectIdentity.class, Sid.class, AclImpl.class, AccessControlEntry.class, - AuditLogger.class, ObjectIdentityImpl.class, PrincipalSid.class, GrantedAuthoritySid.class, BasePermission.class) - .forEach(c -> hints.reflection().registerType(TypeReference.of(c), builder -> - builder.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, + Stream + .of(Acl.class, AccessControlEntry.class, AuditableAccessControlEntry.class, ObjectIdentity.class, Sid.class, + AclImpl.class, AccessControlEntry.class, AuditLogger.class, ObjectIdentityImpl.class, + PrincipalSid.class, GrantedAuthoritySid.class, BasePermission.class) + .forEach((c) -> hints.reflection() + .registerType(TypeReference.of(c), + (builder) -> builder.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.INVOKE_DECLARED_METHODS, MemberCategory.ACCESS_DECLARED_FIELDS))); - } private void registerJdbcSchemaHints(RuntimeHints hints) { - String[] sqlFiles = new String[]{ - "createAclSchema.sql", - "createAclSchemaMySQL.sql", - "createAclSchemaOracle.sql", - "createAclSchemaPostgres.sql", - "createAclSchemaSqlServer.sql", - "createAclSchemaWithAclClassIdType.sql", - "select.sql" - }; + String[] sqlFiles = new String[] { "createAclSchema.sql", "createAclSchemaMySQL.sql", + "createAclSchemaOracle.sql", "createAclSchemaPostgres.sql", "createAclSchemaSqlServer.sql", + "createAclSchemaWithAclClassIdType.sql", "select.sql" }; for (String sqlFile : sqlFiles) { Resource sqlResource = new ClassPathResource(sqlFile); if (sqlResource.exists()) { diff --git a/acl/src/main/java/org/springframework/security/acls/aot/hint/package-info.java b/acl/src/main/java/org/springframework/security/acls/aot/hint/package-info.java index a8d87f146d..cf340d848f 100644 --- a/acl/src/main/java/org/springframework/security/acls/aot/hint/package-info.java +++ b/acl/src/main/java/org/springframework/security/acls/aot/hint/package-info.java @@ -17,4 +17,7 @@ /** * AOT and native image hint support for ACLs. */ +@NullMarked package org.springframework.security.acls.aot.hint; + +import org.jspecify.annotations.NullMarked; diff --git a/core/src/main/java/org/springframework/security/aot/hint/CoreSecurityRuntimeHints.java b/core/src/main/java/org/springframework/security/aot/hint/CoreSecurityRuntimeHints.java index a7b912f56d..fce8006f74 100644 --- a/core/src/main/java/org/springframework/security/aot/hint/CoreSecurityRuntimeHints.java +++ b/core/src/main/java/org/springframework/security/aot/hint/CoreSecurityRuntimeHints.java @@ -16,23 +16,40 @@ package org.springframework.security.aot.hint; +import java.util.List; +import java.util.stream.Stream; + import org.jspecify.annotations.Nullable; + import org.springframework.aot.hint.MemberCategory; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.RuntimeHintsRegistrar; import org.springframework.aot.hint.TypeReference; import org.springframework.security.access.expression.SecurityExpressionOperations; import org.springframework.security.access.expression.SecurityExpressionRoot; -import org.springframework.security.authentication.*; -import org.springframework.security.authentication.event.*; +import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.authentication.AccountExpiredException; +import org.springframework.security.authentication.AuthenticationServiceException; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.CredentialsExpiredException; +import org.springframework.security.authentication.DisabledException; +import org.springframework.security.authentication.LockedException; +import org.springframework.security.authentication.ProviderNotFoundException; +import org.springframework.security.authentication.RememberMeAuthenticationToken; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.authentication.event.AuthenticationFailureBadCredentialsEvent; +import org.springframework.security.authentication.event.AuthenticationFailureCredentialsExpiredEvent; +import org.springframework.security.authentication.event.AuthenticationFailureDisabledEvent; +import org.springframework.security.authentication.event.AuthenticationFailureExpiredEvent; +import org.springframework.security.authentication.event.AuthenticationFailureLockedEvent; +import org.springframework.security.authentication.event.AuthenticationFailureProviderNotFoundEvent; +import org.springframework.security.authentication.event.AuthenticationFailureProxyUntrustedEvent; +import org.springframework.security.authentication.event.AuthenticationFailureServiceExceptionEvent; import org.springframework.security.authentication.ott.OneTimeTokenAuthentication; import org.springframework.security.core.context.SecurityContextImpl; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl; -import java.util.List; -import java.util.stream.Stream; - /** * {@link RuntimeHintsRegistrar} for core classes * @@ -54,41 +71,41 @@ class CoreSecurityRuntimeHints implements RuntimeHintsRegistrar { private void registerMethodSecurityHints(RuntimeHints hints) { hints.reflection() - .registerType( - TypeReference - .of("org.springframework.security.access.expression.method.MethodSecurityExpressionRoot"), - (builder) -> builder.withMembers(MemberCategory.INVOKE_PUBLIC_METHODS)); + .registerType( + TypeReference + .of("org.springframework.security.access.expression.method.MethodSecurityExpressionRoot"), + (builder) -> builder.withMembers(MemberCategory.INVOKE_PUBLIC_METHODS)); hints.reflection() - .registerType(AbstractAuthenticationToken.class, - (builder) -> builder.withMembers(MemberCategory.INVOKE_PUBLIC_METHODS)); + .registerType(AbstractAuthenticationToken.class, + (builder) -> builder.withMembers(MemberCategory.INVOKE_PUBLIC_METHODS)); } private void registerExpressionEvaluationHints(RuntimeHints hints) { hints.reflection() - .registerTypes( - List.of(TypeReference.of(SecurityExpressionOperations.class), - TypeReference.of(SecurityExpressionRoot.class)), - (builder) -> builder.withMembers(MemberCategory.ACCESS_DECLARED_FIELDS, - MemberCategory.INVOKE_DECLARED_METHODS)); + .registerTypes( + List.of(TypeReference.of(SecurityExpressionOperations.class), + TypeReference.of(SecurityExpressionRoot.class)), + (builder) -> builder.withMembers(MemberCategory.ACCESS_DECLARED_FIELDS, + MemberCategory.INVOKE_DECLARED_METHODS)); } private void registerExceptionEventsHints(RuntimeHints hints) { hints.reflection() - .registerTypes(getDefaultAuthenticationExceptionEventPublisherTypes(), - (builder) -> builder.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)); + .registerTypes(getDefaultAuthenticationExceptionEventPublisherTypes(), + (builder) -> builder.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)); } private List getDefaultAuthenticationExceptionEventPublisherTypes() { return Stream - .of(AuthenticationFailureBadCredentialsEvent.class, AuthenticationFailureCredentialsExpiredEvent.class, - AuthenticationFailureDisabledEvent.class, AuthenticationFailureExpiredEvent.class, - AuthenticationFailureLockedEvent.class, AuthenticationFailureProviderNotFoundEvent.class, - AuthenticationFailureProxyUntrustedEvent.class, AuthenticationFailureServiceExceptionEvent.class, - AuthenticationServiceException.class, AccountExpiredException.class, BadCredentialsException.class, - CredentialsExpiredException.class, DisabledException.class, LockedException.class, - UsernameNotFoundException.class, ProviderNotFoundException.class) - .map(TypeReference::of) - .toList(); + .of(AuthenticationFailureBadCredentialsEvent.class, AuthenticationFailureCredentialsExpiredEvent.class, + AuthenticationFailureDisabledEvent.class, AuthenticationFailureExpiredEvent.class, + AuthenticationFailureLockedEvent.class, AuthenticationFailureProviderNotFoundEvent.class, + AuthenticationFailureProxyUntrustedEvent.class, AuthenticationFailureServiceExceptionEvent.class, + AuthenticationServiceException.class, AccountExpiredException.class, BadCredentialsException.class, + CredentialsExpiredException.class, DisabledException.class, LockedException.class, + UsernameNotFoundException.class, ProviderNotFoundException.class) + .map(TypeReference::of) + .toList(); } private void registerDefaultJdbcSchemaFileHint(RuntimeHints hints) { @@ -97,19 +114,21 @@ class CoreSecurityRuntimeHints implements RuntimeHintsRegistrar { private void registerSecurityContextHints(RuntimeHints hints) { hints.reflection() - .registerType(SecurityContextImpl.class, - (builder) -> builder.withMembers(MemberCategory.INVOKE_PUBLIC_METHODS)); + .registerType(SecurityContextImpl.class, + (builder) -> builder.withMembers(MemberCategory.INVOKE_PUBLIC_METHODS)); } private void registerAdditionalAuthenticationTypes(RuntimeHints hints) { // RememberMeAuthenticationToken can be stored in the HTTP session and // deserialized via Jackson (RememberMeAuthenticationTokenMixin exists for both // Jackson 2 and 3), so it needs reflection hints in all native image scenarios. - Stream.of(RememberMeAuthenticationToken.class, OneTimeTokenAuthentication.class, UsernamePasswordAuthenticationToken.class) - .map(TypeReference::of) - .forEach(it -> - hints.reflection().registerType(it, (builder) -> builder.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, - MemberCategory.INVOKE_DECLARED_METHODS, MemberCategory.ACCESS_DECLARED_FIELDS))); + Stream + .of(RememberMeAuthenticationToken.class, OneTimeTokenAuthentication.class, + UsernamePasswordAuthenticationToken.class) + .map(TypeReference::of) + .forEach((it) -> hints.reflection() + .registerType(it, (builder) -> builder.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, + MemberCategory.INVOKE_DECLARED_METHODS, MemberCategory.ACCESS_DECLARED_FIELDS))); } } diff --git a/kerberos/kerberos-core/src/main/java/org/springframework/security/kerberos/aot/hint/package-info.java b/kerberos/kerberos-core/src/main/java/org/springframework/security/kerberos/aot/hint/package-info.java index e959cb9795..cc7e53db5a 100644 --- a/kerberos/kerberos-core/src/main/java/org/springframework/security/kerberos/aot/hint/package-info.java +++ b/kerberos/kerberos-core/src/main/java/org/springframework/security/kerberos/aot/hint/package-info.java @@ -17,4 +17,7 @@ /** * AOT and native image hint support for Kerberos authentication. */ +@NullMarked package org.springframework.security.kerberos.aot.hint; + +import org.jspecify.annotations.NullMarked; diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/aot/hint/OAuth2ClientRuntimeHints.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/aot/hint/OAuth2ClientRuntimeHints.java index 92cc5abd78..4dd6c4a397 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/aot/hint/OAuth2ClientRuntimeHints.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/aot/hint/OAuth2ClientRuntimeHints.java @@ -65,12 +65,10 @@ class OAuth2ClientRuntimeHints implements RuntimeHintsRegistrar { // Register OAuth2 client types that may be serialized in R2DBC scenarios hints.reflection() - .registerTypes( - java.util.List.of( - TypeReference - .of("org.springframework.security.oauth2.client.OAuth2AuthorizedClient"), - TypeReference - .of("org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken")), + .registerTypes(java.util.List.of( + TypeReference.of("org.springframework.security.oauth2.client.OAuth2AuthorizedClient"), + TypeReference + .of("org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken")), (builder) -> builder.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.INVOKE_DECLARED_METHODS, MemberCategory.ACCESS_DECLARED_FIELDS)); } diff --git a/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/aot/hint/Saml2RuntimeHints.java b/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/aot/hint/Saml2RuntimeHints.java index b0508e32b0..2a6a1bfc61 100644 --- a/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/aot/hint/Saml2RuntimeHints.java +++ b/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/aot/hint/Saml2RuntimeHints.java @@ -17,13 +17,19 @@ package org.springframework.security.saml2.aot.hint; import org.jspecify.annotations.Nullable; + import org.springframework.aot.hint.MemberCategory; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.RuntimeHintsRegistrar; import org.springframework.aot.hint.TypeReference; import org.springframework.security.saml2.core.Saml2Error; -import org.springframework.security.saml2.jackson2.Saml2Jackson2Module; -import org.springframework.security.saml2.provider.service.authentication.*; +import org.springframework.security.saml2.provider.service.authentication.DefaultSaml2AuthenticatedPrincipal; +import org.springframework.security.saml2.provider.service.authentication.Saml2AssertionAuthentication; +import org.springframework.security.saml2.provider.service.authentication.Saml2Authentication; +import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationException; +import org.springframework.security.saml2.provider.service.authentication.Saml2PostAuthenticationRequest; +import org.springframework.security.saml2.provider.service.authentication.Saml2RedirectAuthenticationRequest; +import org.springframework.security.saml2.provider.service.authentication.Saml2ResponseAssertion; import org.springframework.security.saml2.provider.service.authentication.logout.Saml2LogoutRequest; import org.springframework.util.ClassUtils; @@ -54,46 +60,35 @@ class Saml2RuntimeHints implements RuntimeHintsRegistrar { private void registerAuthenticationHints(RuntimeHints hints) { hints.reflection() - .registerTypes( - java.util.List.of(TypeReference.of(Saml2Authentication.class), - TypeReference.of(Saml2AssertionAuthentication.class), - TypeReference.of(DefaultSaml2AuthenticatedPrincipal.class), - TypeReference.of(Saml2PostAuthenticationRequest.class), - TypeReference.of(Saml2RedirectAuthenticationRequest.class), - TypeReference.of(Saml2ResponseAssertion.class), - TypeReference.of(Saml2LogoutRequest.class), TypeReference.of(Saml2Error.class), - TypeReference.of(Saml2AuthenticationException.class)), - (builder) -> builder.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, - MemberCategory.INVOKE_DECLARED_METHODS, MemberCategory.ACCESS_DECLARED_FIELDS)); + .registerTypes( + java.util.List.of(TypeReference.of(Saml2Authentication.class), + TypeReference.of(Saml2AssertionAuthentication.class), + TypeReference.of(DefaultSaml2AuthenticatedPrincipal.class), + TypeReference.of(Saml2PostAuthenticationRequest.class), + TypeReference.of(Saml2RedirectAuthenticationRequest.class), + TypeReference.of(Saml2ResponseAssertion.class), TypeReference.of(Saml2LogoutRequest.class), + TypeReference.of(Saml2Error.class), TypeReference.of(Saml2AuthenticationException.class)), + (builder) -> builder.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, + MemberCategory.INVOKE_DECLARED_METHODS, MemberCategory.ACCESS_DECLARED_FIELDS)); } private void registerJacksonHints(RuntimeHints hints) { // Jackson 2 Module if (jackson2Present) { - hints.reflection() - .registerType(Saml2Jackson2Module.class, - (builder) -> builder.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, - MemberCategory.INVOKE_DECLARED_METHODS, MemberCategory.ACCESS_DECLARED_FIELDS)); - // Register mixins for Jackson 2 registerJackson2Mixins(hints); } // Jackson 3 Module if (jackson3Present) { - hints.reflection() - .registerType( - TypeReference.of("org.springframework.security.saml2.jackson.Saml2JacksonModule"), - (builder) -> builder.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, - MemberCategory.INVOKE_DECLARED_METHODS, MemberCategory.ACCESS_DECLARED_FIELDS)); - // Register mixins for Jackson 3 registerJackson3Mixins(hints); } } private void registerJackson2Mixins(RuntimeHints hints) { - String[] mixinClasses = {"org.springframework.security.saml2.jackson2.Saml2AuthenticationMixin", + String[] mixinClasses = { "org.springframework.security.saml2.jackson2.Saml2AuthenticationMixin", + "org.springframework.security.saml2.jackson2.Saml2JacksonModule", "org.springframework.security.saml2.jackson2.Saml2AssertionAuthenticationMixin", "org.springframework.security.saml2.jackson2.SimpleSaml2ResponseAssertionAccessorMixin", "org.springframework.security.saml2.jackson2.DefaultSaml2AuthenticatedPrincipalMixin", @@ -101,40 +96,40 @@ class Saml2RuntimeHints implements RuntimeHintsRegistrar { "org.springframework.security.saml2.jackson2.Saml2RedirectAuthenticationRequestMixin", "org.springframework.security.saml2.jackson2.Saml2PostAuthenticationRequestMixin", "org.springframework.security.saml2.jackson2.Saml2ErrorMixin", - "org.springframework.security.saml2.jackson2.Saml2AuthenticationExceptionMixin"}; + "org.springframework.security.saml2.jackson2.Saml2AuthenticationExceptionMixin" }; for (String mixinClass : mixinClasses) { hints.reflection() - .registerType(TypeReference.of(mixinClass), - (builder) -> builder.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, - MemberCategory.INVOKE_DECLARED_METHODS, MemberCategory.ACCESS_DECLARED_FIELDS)); + .registerType(TypeReference.of(mixinClass), + (builder) -> builder.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, + MemberCategory.INVOKE_DECLARED_METHODS, MemberCategory.ACCESS_DECLARED_FIELDS)); } } private void registerJackson3Mixins(RuntimeHints hints) { - String[] mixinClasses = {"org.springframework.security.saml2.jackson.Saml2AuthenticationMixin", + String[] mixinClasses = { "org.springframework.security.saml2.jackson.Saml2AuthenticationMixin", "org.springframework.security.saml2.jackson.Saml2AssertionAuthenticationMixin", + "org.springframework.security.saml2.jackson.Saml2JacksonModule", "org.springframework.security.saml2.jackson.SimpleSaml2ResponseAssertionAccessorMixin", "org.springframework.security.saml2.jackson.DefaultSaml2AuthenticatedPrincipalMixin", "org.springframework.security.saml2.jackson.Saml2LogoutRequestMixin", "org.springframework.security.saml2.jackson.Saml2RedirectAuthenticationRequestMixin", "org.springframework.security.saml2.jackson.Saml2PostAuthenticationRequestMixin", "org.springframework.security.saml2.jackson.Saml2ErrorMixin", - "org.springframework.security.saml2.jackson.Saml2AuthenticationExceptionMixin"}; + "org.springframework.security.saml2.jackson.Saml2AuthenticationExceptionMixin" }; for (String mixinClass : mixinClasses) { hints.reflection() - .registerType(TypeReference.of(mixinClass), - (builder) -> builder.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, - MemberCategory.INVOKE_DECLARED_METHODS, MemberCategory.ACCESS_DECLARED_FIELDS)); + .registerType(TypeReference.of(mixinClass), + (builder) -> builder.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, + MemberCategory.INVOKE_DECLARED_METHODS, MemberCategory.ACCESS_DECLARED_FIELDS)); } } private void registerJdbcSchemaHints(RuntimeHints hints) { hints.resources() - .registerPattern("org/springframework/security/saml2/saml2-asserting-party-metadata-schema.sql") - .registerPattern( - "org/springframework/security/saml2/saml2-asserting-party-metadata-schema-postgres.sql"); + .registerPattern("org/springframework/security/saml2/saml2-asserting-party-metadata-schema.sql") + .registerPattern("org/springframework/security/saml2/saml2-asserting-party-metadata-schema-postgres.sql"); } } diff --git a/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/aot/hint/package-info.java b/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/aot/hint/package-info.java index ef093afd5b..b6f337acc3 100644 --- a/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/aot/hint/package-info.java +++ b/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/aot/hint/package-info.java @@ -17,4 +17,7 @@ /** * AOT and native image hint support for SAML2. */ +@NullMarked package org.springframework.security.saml2.aot.hint; + +import org.jspecify.annotations.NullMarked;