GH-1192 - Migrate code base to jSpecify for nullness verification.

This commit is contained in:
Oliver Drotbohm
2025-02-17 17:10:47 +01:00
parent a136ff920b
commit 9ea2b24b53
134 changed files with 548 additions and 211 deletions

View File

@@ -22,6 +22,11 @@
<dependencies>
<dependency>
<groupId>org.jspecify</groupId>
<artifactId>jspecify</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.modulith</groupId>
<artifactId>spring-modulith-core</artifactId>

View File

@@ -1,5 +1,5 @@
/**
* Autoconfiguration for the observability integration.
*/
@org.springframework.lang.NonNullApi
@org.jspecify.annotations.NullMarked
package org.springframework.modulith.observability.autoconfigure;

View File

@@ -1,5 +1,5 @@
/**
* Support for application module observability.
*/
@org.springframework.lang.NonNullApi
@org.jspecify.annotations.NullMarked
package org.springframework.modulith.observability;

View File

@@ -19,6 +19,7 @@ import java.lang.reflect.Method;
import java.util.Arrays;
import org.aopalliance.intercept.MethodInvocation;
import org.jspecify.annotations.Nullable;
import org.springframework.aop.ProxyMethodInvocation;
import org.springframework.aop.framework.Advised;
import org.springframework.aop.support.AopUtils;
@@ -111,9 +112,9 @@ class DefaultObservedModule implements ObservedModule {
/*
* (non-Javadoc)
* @see org.springframework.modulith.observability.ObservedModule#getInterceptionConfiguration(java.lang.Class, org.springframework.modulith.model.Modules)
* @see org.springframework.modulith.observability.support.ObservedModule#getObservedModuleType(java.lang.Class, org.springframework.modulith.core.ApplicationModules)
*/
public ObservedModuleType getObservedModuleType(Class<?> type, ApplicationModules modules) {
public @Nullable ObservedModuleType getObservedModuleType(Class<?> type, ApplicationModules modules) {
Assert.notNull(type, "Type must not be null!");
Assert.notNull(modules, "ApplicationModules must not be null!");
@@ -161,7 +162,7 @@ class DefaultObservedModule implements ObservedModule {
var advised = (Advised) ((ProxyMethodInvocation) invocation).getProxy();
var targetClass = advised.getTargetClass();
if (module.contains(targetClass)) {
if (targetClass != null && module.contains(targetClass)) {
return AopUtils.getMostSpecificMethod(method, targetClass);
}

View File

@@ -25,10 +25,10 @@ import java.util.Objects;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.Environment;
import org.springframework.lang.Nullable;
import org.springframework.modulith.core.ApplicationModuleIdentifier;
import org.springframework.modulith.observability.support.ModulithObservations.LowKeys;
import org.springframework.util.Assert;
@@ -69,11 +69,11 @@ class ModuleEntryInterceptor implements MethodInterceptor {
*
* @param module must not be {@literal null}.
* @param observationRegistry must not be {@literal null}.
* @param custom must not be {@literal null}.
* @param custom can be {@literal null}.
* @param environment must not be {@literal null}.
*/
private ModuleEntryInterceptor(ObservedModule module, ObservationRegistry observationRegistry,
ModulithObservationConvention custom, Environment environment) {
@Nullable ModulithObservationConvention custom, Environment environment) {
Assert.notNull(module, "ObservedModule must not be null!");
Assert.notNull(observationRegistry, "ObservationRegistry must not be null!");
@@ -90,7 +90,7 @@ class ModuleEntryInterceptor implements MethodInterceptor {
}
public static ModuleEntryInterceptor of(ObservedModule module, ObservationRegistry observationRegistry,
ModulithObservationConvention custom, Environment environment) {
@Nullable ModulithObservationConvention custom, Environment environment) {
return CACHE.computeIfAbsent(module.getIdentifier(), __ -> {
return new ModuleEntryInterceptor(module, observationRegistry, custom, environment);
@@ -102,7 +102,7 @@ class ModuleEntryInterceptor implements MethodInterceptor {
* @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
*/
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
public @Nullable Object invoke(MethodInvocation invocation) throws Throwable {
var moduleIdentifier = module.getIdentifier();
var currentObservation = observationRegistry.getCurrentObservation();

View File

@@ -17,6 +17,7 @@ package org.springframework.modulith.observability.support;
import java.util.function.Consumer;
import org.jspecify.annotations.Nullable;
import org.springframework.aop.Advisor;
import org.springframework.aop.framework.Advised;
import org.springframework.aop.framework.ProxyFactory;
@@ -24,7 +25,6 @@ import org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.lang.Nullable;
import org.springframework.scheduling.annotation.AsyncAnnotationAdvisor;
/**

View File

@@ -18,6 +18,7 @@ package org.springframework.modulith.observability.support;
import io.micrometer.observation.Observation.Context;
import org.aopalliance.intercept.MethodInvocation;
import org.jspecify.annotations.Nullable;
import org.springframework.core.env.Environment;
import org.springframework.util.Assert;
@@ -32,7 +33,7 @@ public class ModulithContext extends Context {
private final ObservedModule module;
private final MethodInvocation invocation;
private final String applicationName;
private final @Nullable String applicationName;
/**
* Creates a new {@link ModulithContext} for the given {@link ObservedModule}, {@link MethodInvocation} and
@@ -61,7 +62,7 @@ public class ModulithContext extends Context {
return invocation;
}
public String getApplicationName() {
public @Nullable String getApplicationName() {
return applicationName;
}
}

View File

@@ -18,7 +18,7 @@ package org.springframework.modulith.observability.support;
import java.lang.reflect.Method;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.lang.Nullable;
import org.jspecify.annotations.Nullable;
import org.springframework.modulith.core.ApplicationModule;
import org.springframework.modulith.core.ApplicationModuleIdentifier;
import org.springframework.modulith.core.ApplicationModules;

View File

@@ -21,6 +21,7 @@ import java.util.function.Supplier;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.jspecify.annotations.Nullable;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
@@ -28,7 +29,6 @@ import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.env.Environment;
import org.springframework.data.rest.webmvc.BasePathAwareController;
import org.springframework.data.rest.webmvc.RootResourceInformation;
import org.springframework.lang.Nullable;
import org.springframework.modulith.core.ApplicationModule;
import org.springframework.modulith.core.ApplicationModules;
import org.springframework.modulith.runtime.ApplicationModulesRuntime;
@@ -114,7 +114,7 @@ public class SpringDataRestModuleObservabilityBeanPostProcessor extends ModuleOb
* @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
*/
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
public @Nullable Object invoke(MethodInvocation invocation) throws Throwable {
var module = getModuleFrom(invocation.getArguments());

View File

@@ -1,5 +1,5 @@
/**
* Support for application module observability.
*/
@org.springframework.lang.NonNullApi
@org.jspecify.annotations.NullMarked
package org.springframework.modulith.observability.support;