diff --git a/.mvn/jvm.config b/.mvn/jvm.config
new file mode 100644
index 00000000..e27f6e8f
--- /dev/null
+++ b/.mvn/jvm.config
@@ -0,0 +1,14 @@
+--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
+--add-opens jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED
+--add-opens jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED
+--add-opens=java.base/java.util=ALL-UNNAMED
+--add-opens=java.base/java.lang.reflect=ALL-UNNAMED
+--add-opens=java.base/java.text=ALL-UNNAMED
+--add-opens=java.desktop/java.awt.font=ALL-UNNAMED
diff --git a/pom.xml b/pom.xml
index 8e228e75..35608a62 100644
--- a/pom.xml
+++ b/pom.xml
@@ -23,6 +23,7 @@
3.27.3
2.31.29
1.80
+ 2.36.0
v1-rev20221013-2.0.0
2.60.0
@@ -39,6 +40,7 @@
1.13.17
5.17.0
4.1.121.Final
+ 0.12.3
3.14.9
7.0.0-M2
2025.1.0-M1
@@ -379,9 +381,22 @@
org.apache.maven.plugins
maven-compiler-plugin
- ${java.version}
- ${java.version}
+ ${java.version}
true
+ ${source.level}
+ true
+
+
+ com.google.errorprone
+ error_prone_core
+ ${errorprone.version}
+
+
+ com.uber.nullaway
+ nullaway
+ ${nullaway.version}
+
+
@@ -398,6 +413,13 @@
compile
+
+
+ -XDcompilePolicy=simple
+ --should-stop=ifError=FLOW
+ -Xplugin:ErrorProne -XepDisableAllChecks -Xep:NullAway:ERROR -XepOpt:NullAway:OnlyNullMarked=true -XepOpt:NullAway:CustomContractAnnotations=org.springframework.lang.Contract
+
+
java-test-compile
diff --git a/spring-vault-core/pom.xml b/spring-vault-core/pom.xml
index 2728e9a3..5caa591e 100644
--- a/spring-vault-core/pom.xml
+++ b/spring-vault-core/pom.xml
@@ -135,6 +135,11 @@
kotlinx-coroutines-reactor
true
+
+ org.jspecify
+ jspecify
+ 1.0.0
+
diff --git a/spring-vault-core/src/main/java/org/springframework/vault/annotation/PropertySourceAotProcessor.java b/spring-vault-core/src/main/java/org/springframework/vault/annotation/PropertySourceAotProcessor.java
index afd76650..156f0ebd 100644
--- a/spring-vault-core/src/main/java/org/springframework/vault/annotation/PropertySourceAotProcessor.java
+++ b/spring-vault-core/src/main/java/org/springframework/vault/annotation/PropertySourceAotProcessor.java
@@ -18,6 +18,8 @@ package org.springframework.vault.annotation;
import java.util.Map.Entry;
import java.util.function.Predicate;
+import org.jspecify.annotations.Nullable;
+
import org.springframework.aot.generate.GenerationContext;
import org.springframework.beans.factory.aot.BeanRegistrationAotContribution;
import org.springframework.beans.factory.aot.BeanRegistrationAotProcessor;
@@ -31,7 +33,6 @@ import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.RegisteredBean;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.javapoet.CodeBlock;
-import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
import org.springframework.vault.core.lease.domain.RequestedSecret;
import org.springframework.vault.core.lease.domain.RequestedSecret.Mode;
@@ -48,7 +49,7 @@ import org.springframework.vault.core.util.PropertyTransformers.NoOpPropertyTran
class PropertySourceAotProcessor implements BeanRegistrationAotProcessor {
@Override
- public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) {
+ public @Nullable BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) {
if (registeredBean.getBeanClass() == org.springframework.vault.core.env.LeaseAwareVaultPropertySource.class) {
return BeanRegistrationAotContribution.withCustomCodeFragments(AotContribution::new);
diff --git a/spring-vault-core/src/main/java/org/springframework/vault/annotation/VaultPropertySource.java b/spring-vault-core/src/main/java/org/springframework/vault/annotation/VaultPropertySource.java
index 2e40b8a7..245259bc 100644
--- a/spring-vault-core/src/main/java/org/springframework/vault/annotation/VaultPropertySource.java
+++ b/spring-vault-core/src/main/java/org/springframework/vault/annotation/VaultPropertySource.java
@@ -113,7 +113,7 @@ public @interface VaultPropertySource {
*/
Renewal renewal() default Renewal.OFF;
- public enum Renewal {
+ enum Renewal {
/**
* Do not renew leases associated with secrets.
diff --git a/spring-vault-core/src/main/java/org/springframework/vault/annotation/VaultPropertySourceRegistrar.java b/spring-vault-core/src/main/java/org/springframework/vault/annotation/VaultPropertySourceRegistrar.java
index 3efba599..34304d32 100644
--- a/spring-vault-core/src/main/java/org/springframework/vault/annotation/VaultPropertySourceRegistrar.java
+++ b/spring-vault-core/src/main/java/org/springframework/vault/annotation/VaultPropertySourceRegistrar.java
@@ -21,6 +21,8 @@ import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
+import org.jspecify.annotations.Nullable;
+
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
@@ -36,7 +38,6 @@ import org.springframework.core.env.Environment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
import org.springframework.core.type.AnnotationMetadata;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.vault.annotation.VaultPropertySource.Renewal;
@@ -200,9 +201,9 @@ class VaultPropertySourceRegistrar
Set result = new LinkedHashSet<>();
addAttributesIfNotNull(result, metadata.getAnnotationAttributes(annotationClassName, false));
- Map container = metadata.getAnnotationAttributes(containerClassName, false);
+ Map container = metadata.getAnnotationAttributes(containerClassName, false);
if (container != null && container.containsKey("value")) {
- for (Map containedAttributes : (Map[]) container.get("value")) {
+ for (Map containedAttributes : (Map[]) container.get("value")) {
addAttributesIfNotNull(result, containedAttributes);
}
}
@@ -210,7 +211,7 @@ class VaultPropertySourceRegistrar
}
private static void addAttributesIfNotNull(Set result,
- @Nullable Map attributes) {
+ @Nullable Map attributes) {
if (attributes != null) {
result.add(AnnotationAttributes.fromMap(attributes));
}
diff --git a/spring-vault-core/src/main/java/org/springframework/vault/annotation/package-info.java b/spring-vault-core/src/main/java/org/springframework/vault/annotation/package-info.java
index 5fef6fd8..08753440 100644
--- a/spring-vault-core/src/main/java/org/springframework/vault/annotation/package-info.java
+++ b/spring-vault-core/src/main/java/org/springframework/vault/annotation/package-info.java
@@ -1,6 +1,5 @@
/**
* Annotation support for the Spring Vault.
*/
-@org.springframework.lang.NonNullApi
-@org.springframework.lang.NonNullFields
+@org.jspecify.annotations.NullMarked
package org.springframework.vault.annotation;
diff --git a/spring-vault-core/src/main/java/org/springframework/vault/aot/VaultRuntimeHints.java b/spring-vault-core/src/main/java/org/springframework/vault/aot/VaultRuntimeHints.java
index 64c9ea1e..fcee7fda 100644
--- a/spring-vault-core/src/main/java/org/springframework/vault/aot/VaultRuntimeHints.java
+++ b/spring-vault-core/src/main/java/org/springframework/vault/aot/VaultRuntimeHints.java
@@ -18,6 +18,8 @@ package org.springframework.vault.aot;
import java.io.IOException;
import java.util.stream.Stream;
+import org.jspecify.annotations.Nullable;
+
import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.ReflectionHints;
import org.springframework.aot.hint.RuntimeHints;
@@ -41,7 +43,7 @@ class VaultRuntimeHints implements RuntimeHintsRegistrar {
private final CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
@Override
- public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
+ public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) {
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(classLoader);
diff --git a/spring-vault-core/src/main/java/org/springframework/vault/aot/package-info.java b/spring-vault-core/src/main/java/org/springframework/vault/aot/package-info.java
index 319ab0f4..c270b6b1 100644
--- a/spring-vault-core/src/main/java/org/springframework/vault/aot/package-info.java
+++ b/spring-vault-core/src/main/java/org/springframework/vault/aot/package-info.java
@@ -1,6 +1,5 @@
/**
* Ahead-of-Time support.
*/
-@org.springframework.lang.NonNullApi
-@org.springframework.lang.NonNullFields
+@org.jspecify.annotations.NullMarked
package org.springframework.vault.aot;
diff --git a/spring-vault-core/src/main/java/org/springframework/vault/authentication/AppRoleAuthentication.java b/spring-vault-core/src/main/java/org/springframework/vault/authentication/AppRoleAuthentication.java
index ee0e3585..a82dc976 100644
--- a/spring-vault-core/src/main/java/org/springframework/vault/authentication/AppRoleAuthentication.java
+++ b/spring-vault-core/src/main/java/org/springframework/vault/authentication/AppRoleAuthentication.java
@@ -20,12 +20,12 @@ import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.jspecify.annotations.Nullable;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.vault.authentication.AppRoleAuthenticationOptions.RoleId;
@@ -214,7 +214,7 @@ public class AppRoleAuthentication implements ClientAuthentication, Authenticati
ResponseEntity entity = this.restOperations.exchange(getRoleIdIdPath(this.options),
HttpMethod.GET, createHttpEntity(token), VaultResponse.class);
- return (String) entity.getBody().getRequiredData().get("role_id");
+ return (String) ResponseUtil.getRequiredData(entity).get("role_id");
}
catch (HttpStatusCodeException e) {
throw new VaultLoginException("Cannot get Role id using AppRole: %s"
@@ -231,7 +231,7 @@ public class AppRoleAuthentication implements ClientAuthentication, Authenticati
ResponseEntity entity = this.restOperations.exchange(unwrappingEndpoints.getPath(),
unwrappingEndpoints.getUnwrapRequestMethod(), createHttpEntity(token), VaultResponse.class);
- VaultResponse response = unwrappingEndpoints.unwrap(entity.getBody());
+ VaultResponse response = unwrappingEndpoints.unwrap(ResponseUtil.getRequiredBody(entity));
return (String) response.getRequiredData().get("role_id");
}
@@ -257,7 +257,7 @@ public class AppRoleAuthentication implements ClientAuthentication, Authenticati
try {
VaultResponse response = this.restOperations.postForObject(getSecretIdPath(this.options),
createHttpEntity(token), VaultResponse.class);
- return (String) response.getRequiredData().get("secret_id");
+ return (String) ResponseUtil.getRequiredData(response).get("secret_id");
}
catch (HttpStatusCodeException e) {
throw new VaultLoginException("Cannot get Secret id using AppRole: %s"
@@ -275,7 +275,7 @@ public class AppRoleAuthentication implements ClientAuthentication, Authenticati
ResponseEntity entity = this.restOperations.exchange(unwrappingEndpoints.getPath(),
unwrappingEndpoints.getUnwrapRequestMethod(), createHttpEntity(token), VaultResponse.class);
- VaultResponse response = unwrappingEndpoints.unwrap(entity.getBody());
+ VaultResponse response = unwrappingEndpoints.unwrap(ResponseUtil.getRequiredBody(entity));
return (String) response.getRequiredData().get("secret_id");
}
diff --git a/spring-vault-core/src/main/java/org/springframework/vault/authentication/AppRoleAuthenticationOptions.java b/spring-vault-core/src/main/java/org/springframework/vault/authentication/AppRoleAuthenticationOptions.java
index a838b2a3..306382fa 100644
--- a/spring-vault-core/src/main/java/org/springframework/vault/authentication/AppRoleAuthenticationOptions.java
+++ b/spring-vault-core/src/main/java/org/springframework/vault/authentication/AppRoleAuthenticationOptions.java
@@ -15,7 +15,8 @@
*/
package org.springframework.vault.authentication;
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
+
import org.springframework.util.Assert;
import org.springframework.vault.authentication.AppRoleTokens.AbsentSecretId;
import org.springframework.vault.authentication.AppRoleTokens.Provided;
diff --git a/spring-vault-core/src/main/java/org/springframework/vault/authentication/AuthenticationSteps.java b/spring-vault-core/src/main/java/org/springframework/vault/authentication/AuthenticationSteps.java
index 3a188b62..89684f09 100644
--- a/spring-vault-core/src/main/java/org/springframework/vault/authentication/AuthenticationSteps.java
+++ b/spring-vault-core/src/main/java/org/springframework/vault/authentication/AuthenticationSteps.java
@@ -24,10 +24,11 @@ import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
+import org.jspecify.annotations.Nullable;
+
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.vault.support.VaultResponse;
import org.springframework.vault.support.VaultToken;
@@ -298,8 +299,7 @@ public class AuthenticationSteps {
@Nullable
String uriTemplate;
- @Nullable
- String[] urlVariables;
+ String @Nullable[] urlVariables;
@Nullable
HttpEntity> entity;
@@ -379,14 +379,14 @@ public class AuthenticationSteps {
this.uri = uri;
}
- private HttpRequestBuilder(HttpMethod method, @Nullable String uriTemplate, @Nullable String[] urlVariables) {
+ private HttpRequestBuilder(HttpMethod method, @Nullable String uriTemplate, String @Nullable[] urlVariables) {
this.method = method;
this.uriTemplate = uriTemplate;
this.urlVariables = urlVariables;
}
private HttpRequestBuilder(HttpMethod method, @Nullable URI uri, @Nullable String uriTemplate,
- @Nullable String[] urlVariables, @Nullable HttpEntity> entity) {
+ String @Nullable[] urlVariables, @Nullable HttpEntity> entity) {
this.method = method;
this.uri = uri;
this.uriTemplate = uriTemplate;
@@ -448,8 +448,8 @@ public class AuthenticationSteps {
@Nullable
final String uriTemplate;
- @Nullable
- final String[] urlVariables;
+
+ final String @Nullable[] urlVariables;
@Nullable
final HttpEntity> entity;
@@ -485,8 +485,7 @@ public class AuthenticationSteps {
return this.uriTemplate;
}
- @Nullable
- String[] getUrlVariables() {
+ String @Nullable[] getUrlVariables() {
return this.urlVariables;
}
diff --git a/spring-vault-core/src/main/java/org/springframework/vault/authentication/AuthenticationStepsExecutor.java b/spring-vault-core/src/main/java/org/springframework/vault/authentication/AuthenticationStepsExecutor.java
index a1219298..1d08dc8d 100644
--- a/spring-vault-core/src/main/java/org/springframework/vault/authentication/AuthenticationStepsExecutor.java
+++ b/spring-vault-core/src/main/java/org/springframework/vault/authentication/AuthenticationStepsExecutor.java
@@ -17,11 +17,11 @@ package org.springframework.vault.authentication;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.jspecify.annotations.Nullable;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.vault.VaultException;
import org.springframework.vault.authentication.AuthenticationSteps.HttpRequest;
@@ -71,7 +71,6 @@ public class AuthenticationStepsExecutor implements ClientAuthentication {
}
@Override
- @SuppressWarnings("unchecked")
public VaultToken login() throws VaultException {
Iterable> steps = this.chain.steps;
diff --git a/spring-vault-core/src/main/java/org/springframework/vault/authentication/AuthenticationStepsOperator.java b/spring-vault-core/src/main/java/org/springframework/vault/authentication/AuthenticationStepsOperator.java
index 7d69969d..d278b87f 100644
--- a/spring-vault-core/src/main/java/org/springframework/vault/authentication/AuthenticationStepsOperator.java
+++ b/spring-vault-core/src/main/java/org/springframework/vault/authentication/AuthenticationStepsOperator.java
@@ -155,6 +155,7 @@ public class AuthenticationStepsOperator implements VaultTokenSupplier {
return state;
}
+ @SuppressWarnings({"NullAway", "DataFlowIssue"})
private Mono