GH-1192 - Migrate code base to jSpecify for nullness verification.
This commit is contained in:
2
.github/workflows/build.yaml
vendored
2
.github/workflows/build.yaml
vendored
@@ -31,4 +31,4 @@ jobs:
|
||||
ARTIFACTORY_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
|
||||
ARTIFACTORY_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }}
|
||||
DEVELOCITY_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_SECRET_ACCESS_KEY }}
|
||||
run: ./mvnw -B clean deploy -Pci,artifactory
|
||||
run: ./mvnw -B clean deploy -Pci,artifactory,nullaway
|
||||
|
||||
10
.mvn/jvm.config
Normal file
10
.mvn/jvm.config
Normal file
@@ -0,0 +1,10 @@
|
||||
--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
|
||||
50
pom.xml
50
pom.xml
@@ -37,10 +37,12 @@
|
||||
|
||||
<archunit.version>1.4.0</archunit.version>
|
||||
<artifactory-maven-plugin.version>3.6.2</artifactory-maven-plugin.version>
|
||||
<errorprone.version>2.36.0</errorprone.version>
|
||||
<flapdoodle-mongodb.version>4.16.1</flapdoodle-mongodb.version>
|
||||
<jgit.version>7.0.0.202409031743-r</jgit.version>
|
||||
<jgrapht.version>1.5.2</jgrapht.version>
|
||||
<jmolecules-bom.version>2023.3.1</jmolecules-bom.version>
|
||||
<nullaway.version>0.12.7</nullaway.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<spring-boot.version>4.0.0-SNAPSHOT</spring-boot.version>
|
||||
@@ -431,6 +433,54 @@ limitations under the License.
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>nullaway</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<showWarnings>true</showWarnings>
|
||||
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>default-compile</id>
|
||||
<phase>none</phase>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>java-compile</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<annotationProcessorPaths>
|
||||
<path>
|
||||
<groupId>com.google.errorprone</groupId>
|
||||
<artifactId>error_prone_core</artifactId>
|
||||
<version>${errorprone.version}</version>
|
||||
</path>
|
||||
<path>
|
||||
<groupId>com.uber.nullaway</groupId>
|
||||
<artifactId>nullaway</artifactId>
|
||||
<version>${nullaway.version}</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
<compilerArgs>
|
||||
<arg>-XDcompilePolicy=simple</arg>
|
||||
<arg>--should-stop=ifError=FLOW</arg>
|
||||
<arg>-Xplugin:ErrorProne -XepDisableAllChecks -Xep:NullAway:ERROR -XepOpt:NullAway:OnlyNullMarked=true -XepOpt:NullAway:CustomContractAnnotations=org.springframework.lang.Contract</arg>
|
||||
</compilerArgs>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
</profiles>
|
||||
|
||||
<dependencies>
|
||||
|
||||
@@ -16,6 +16,11 @@
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jspecify</groupId>
|
||||
<artifactId>jspecify</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.modulith</groupId>
|
||||
<artifactId>spring-modulith-runtime</artifactId>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Autoconfiguration for Spring Modulith actuators.
|
||||
*/
|
||||
@org.springframework.lang.NonNullApi
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.modulith.actuator.autoconfigure;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Spring Boot actuator support for Spring Modulith.
|
||||
*/
|
||||
@org.springframework.lang.NonNullApi
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.modulith.actuator;
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jspecify</groupId>
|
||||
<artifactId>jspecify</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-autoconfigure</artifactId>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Core abstractions of Spring Modulith. To be referred to in user applications.
|
||||
*/
|
||||
@org.springframework.lang.NonNullApi
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.modulith;
|
||||
|
||||
@@ -21,6 +21,10 @@
|
||||
<artifactId>aptk-tools</artifactId>
|
||||
<version>0.29.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jspecify</groupId>
|
||||
<artifactId>jspecify</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
||||
@@ -19,6 +19,7 @@ import io.toolisticon.aptk.tools.ElementUtils;
|
||||
import io.toolisticon.aptk.tools.wrapper.ElementWrapper;
|
||||
import io.toolisticon.aptk.tools.wrapper.ExecutableElementWrapper;
|
||||
import io.toolisticon.aptk.tools.wrapper.TypeElementWrapper;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
@@ -50,7 +51,6 @@ import javax.tools.Diagnostic.Kind;
|
||||
import javax.tools.StandardLocation;
|
||||
|
||||
import org.springframework.boot.json.JsonWriter;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.modulith.docs.metadata.MethodMetadata;
|
||||
import org.springframework.modulith.docs.metadata.TypeMetadata;
|
||||
import org.springframework.modulith.docs.util.BuildSystemUtils;
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jspecify</groupId>
|
||||
<artifactId>jspecify</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.modulith</groupId>
|
||||
<artifactId>spring-modulith-api</artifactId>
|
||||
|
||||
@@ -36,7 +36,7 @@ import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.modulith.core.Types.JMoleculesTypes;
|
||||
import org.springframework.modulith.core.Types.JavaTypes;
|
||||
import org.springframework.modulith.core.Types.SpringTypes;
|
||||
@@ -427,7 +427,7 @@ public class ApplicationModule implements Comparable<ApplicationModule> {
|
||||
|
||||
var candidatePackageName = PackageName.ofType(candidate);
|
||||
|
||||
return (candidatePackageName.isEmpty() || basePackage.getPackageName().contains(candidatePackageName))
|
||||
return (PackageName.isDefault(candidatePackageName) || basePackage.getPackageName().contains(candidatePackageName))
|
||||
&& getType(candidate).isPresent();
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -172,7 +173,7 @@ public class ApplicationModuleDependencies {
|
||||
* @param name must not be {@literal null} or empty.
|
||||
* @return will never be {@literal null}.
|
||||
*/
|
||||
public ApplicationModule getModuleByType(String name) {
|
||||
public @Nullable ApplicationModule getModuleByType(String name) {
|
||||
|
||||
Assert.hasText(name, "Name must not be null or empty!");
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.modulith.ApplicationModule;
|
||||
import org.springframework.modulith.core.Types.JMoleculesTypes;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -240,7 +241,7 @@ public class ApplicationModuleSource {
|
||||
* @param delegates must not be {@literal null}.
|
||||
* @return will never be {@literal null}.
|
||||
*/
|
||||
private static ApplicationModuleSourceMetadata delegating(ApplicationModuleSourceMetadata... delegates) {
|
||||
private static ApplicationModuleSourceMetadata delegating(@Nullable ApplicationModuleSourceMetadata... delegates) {
|
||||
|
||||
return new ApplicationModuleSourceMetadata() {
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* SPI to allow build units contribute additional {@link ApplicationModuleSource}s in the form of either declaring them
|
||||
|
||||
@@ -32,9 +32,9 @@ import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.aot.generate.Generated;
|
||||
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.function.SingletonSupplier;
|
||||
@@ -61,7 +61,7 @@ public class ApplicationModules implements Iterable<ApplicationModule> {
|
||||
private static final Map<CacheKey, ApplicationModules> CACHE = new ConcurrentHashMap<>();
|
||||
|
||||
private static final ImportOption IMPORT_OPTION = new ImportOption.DoNotIncludeTests();
|
||||
private static final DescribedPredicate<CanBeAnnotated> IS_GENERATED;
|
||||
private static final @Nullable DescribedPredicate<CanBeAnnotated> IS_GENERATED;
|
||||
private static final DescribedPredicate<HasName> IS_SPRING_CGLIB_PROXY = nameContaining("$$SpringCGLIB$$");
|
||||
|
||||
static {
|
||||
@@ -624,9 +624,9 @@ public class ApplicationModules implements Iterable<ApplicationModule> {
|
||||
* {@literal null} or its type does not reside in any module.
|
||||
*
|
||||
* @param object can be {@literal null}.
|
||||
* @return
|
||||
* @return can be {@literal null}.
|
||||
*/
|
||||
private Integer getModuleIndexFor(@Nullable Object object) {
|
||||
private @Nullable Integer getModuleIndexFor(@Nullable Object object) {
|
||||
|
||||
return Optional.ofNullable(object)
|
||||
.map(it -> Class.class.isInstance(it) ? Class.class.cast(it) : it.getClass())
|
||||
@@ -778,7 +778,7 @@ public class ApplicationModules implements Iterable<ApplicationModule> {
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
|
||||
if (obj == this) {
|
||||
return true;
|
||||
|
||||
@@ -20,6 +20,7 @@ import static org.springframework.modulith.core.Types.JavaXTypes.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@@ -676,7 +677,9 @@ public abstract class ArchitecturallyEvidentType {
|
||||
var attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(method.reflect(),
|
||||
SpringTypes.AT_EVENT_LISTENER, false, false);
|
||||
|
||||
return List.of(attributes.getClassArray("classes"));
|
||||
return attributes == null
|
||||
? Collections.emptyList()
|
||||
: List.of(attributes.getClassArray("classes"));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -29,7 +29,7 @@ import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -75,7 +75,12 @@ public interface ModulithMetadata {
|
||||
return SpringBootModulithMetadata.of(javaPackage);
|
||||
}
|
||||
|
||||
var className = candidates.iterator().next().getBeanClassName();
|
||||
var definition = candidates.iterator().next();
|
||||
var className = definition.getBeanClassName();
|
||||
|
||||
if (className == null) {
|
||||
throw new IllegalStateException("No bean class name found on BeanDefinition %s!".formatted(definition));
|
||||
}
|
||||
|
||||
return of(ClassUtils.resolveClassName(className, ModulithMetadata.class.getClassLoader()));
|
||||
}
|
||||
|
||||
@@ -298,6 +298,10 @@ public class NamedInterfaces implements Iterable<NamedInterface> {
|
||||
var annotation = AnnotatedElementUtils.getMergedAnnotation(it.reflect(),
|
||||
org.springframework.modulith.NamedInterface.class);
|
||||
|
||||
if (annotation == null) {
|
||||
throw new IllegalStateException("No @NamedInterface annotation found!");
|
||||
}
|
||||
|
||||
NamedInterface.getDefaultedNames(annotation, it.getPackageName())
|
||||
.forEach(name -> mappings.add(name, it));
|
||||
});
|
||||
|
||||
@@ -18,10 +18,11 @@ package org.springframework.modulith.core;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
@@ -34,6 +35,8 @@ import org.springframework.util.ClassUtils;
|
||||
*/
|
||||
public class PackageName implements Comparable<PackageName> {
|
||||
|
||||
public static final String DEFAULT = "<<default>>";
|
||||
|
||||
private static final Map<String, PackageName> PACKAGE_NAMES = new HashMap<>();
|
||||
|
||||
private final String name;
|
||||
@@ -77,6 +80,20 @@ public class PackageName implements Comparable<PackageName> {
|
||||
return PackageName.of(ClassUtils.getPackageName(fullyQualifiedName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link PackageName} for the given fully-qualified type name.
|
||||
*
|
||||
* @param fullyQualifiedName must not be {@literal null} or empty.
|
||||
* @return will never be {@literal null}.
|
||||
* @since 2.0
|
||||
*/
|
||||
public static PackageName ofType(Class<?> type) {
|
||||
|
||||
Assert.notNull(type, "Type must not be null!");
|
||||
|
||||
return PackageName.of(ClassUtils.getPackageName(type));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link PackageName} with the given name.
|
||||
*
|
||||
@@ -88,7 +105,9 @@ public class PackageName implements Comparable<PackageName> {
|
||||
|
||||
Assert.notNull(name, "Name must not be null!");
|
||||
|
||||
return PACKAGE_NAMES.computeIfAbsent(name, PackageName::new);
|
||||
var defaulted = name.isBlank() ? DEFAULT : name;
|
||||
|
||||
return PACKAGE_NAMES.computeIfAbsent(defaulted, PackageName::new);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -107,6 +126,16 @@ public class PackageName implements Comparable<PackageName> {
|
||||
return PACKAGE_NAMES.computeIfAbsent(name, it -> new PackageName(name, segments));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given {@link PackageName} is the default package name (logically an empty string).
|
||||
*
|
||||
* @param name must not be {@literal null}.
|
||||
* @since 2.0
|
||||
*/
|
||||
static boolean isDefault(PackageName name) {
|
||||
return name.hasName(DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of the package name.
|
||||
*
|
||||
@@ -281,7 +310,9 @@ public class PackageName implements Comparable<PackageName> {
|
||||
return Stream.of(reference);
|
||||
}
|
||||
|
||||
return Stream.concat(expandUntil(reference.getParent()), Stream.of(reference));
|
||||
var parent = Objects.requireNonNull(reference.getParent());
|
||||
|
||||
return Stream.concat(expandUntil(parent), Stream.of(reference));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -318,7 +349,7 @@ public class PackageName implements Comparable<PackageName> {
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
|
||||
if (obj == this) {
|
||||
return true;
|
||||
|
||||
@@ -21,8 +21,8 @@ import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.modulith.core.Types.SpringTypes;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -34,20 +34,21 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
class SpringBootModulithMetadata implements ModulithMetadata {
|
||||
|
||||
private static final Class<? extends Annotation> AT_SPRING_BOOT_APPLICATION = Types
|
||||
private static final @Nullable Class<? extends Annotation> AT_SPRING_BOOT_APPLICATION = Types
|
||||
.loadIfPresent(SpringTypes.AT_SPRING_BOOT_APPLICATION);
|
||||
|
||||
private final @NonNull Object source;
|
||||
private final String systemName, basePackage;
|
||||
private final Object source;
|
||||
private final String basePackage;
|
||||
private final @Nullable String systemName;
|
||||
|
||||
/**
|
||||
* Creates a new {@link SpringBootModulithMetadata} for the given source.
|
||||
*
|
||||
* @param source must not be {@literal null}.
|
||||
* @param systemName can be {@literal null}.
|
||||
* @param basePackage must not be {@literal null}.
|
||||
* @param systemName can be {@literal null}.
|
||||
*/
|
||||
private SpringBootModulithMetadata(Object source, String systemName, String basePackage) {
|
||||
private SpringBootModulithMetadata(Object source, String basePackage, @Nullable String systemName) {
|
||||
|
||||
Assert.notNull(source, "Source must not be null!");
|
||||
Assert.notNull(basePackage, "Base package must not be null!");
|
||||
@@ -71,7 +72,7 @@ class SpringBootModulithMetadata implements ModulithMetadata {
|
||||
|
||||
return Optional.ofNullable(AT_SPRING_BOOT_APPLICATION) //
|
||||
.filter(it -> AnnotatedElementUtils.hasAnnotation(annotated, it)) //
|
||||
.map(__ -> new SpringBootModulithMetadata(annotated, annotated.getSimpleName(), annotated.getPackageName()));
|
||||
.map(__ -> new SpringBootModulithMetadata(annotated, annotated.getPackageName(), annotated.getSimpleName()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -84,7 +85,7 @@ class SpringBootModulithMetadata implements ModulithMetadata {
|
||||
|
||||
Assert.hasText(javaPackage, "Package name must not be null or empty!");
|
||||
|
||||
return new SpringBootModulithMetadata(javaPackage, null, javaPackage);
|
||||
return new SpringBootModulithMetadata(javaPackage, javaPackage, null);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -26,7 +26,7 @@ import java.util.function.Predicate;
|
||||
import org.jmolecules.archunit.JMoleculesArchitectureRules;
|
||||
import org.jmolecules.archunit.JMoleculesDddRules;
|
||||
import org.jmolecules.ddd.annotation.Module;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.modulith.PackageInfo;
|
||||
import org.springframework.modulith.core.ApplicationModuleSource.ApplicationModuleSourceMetadata;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -82,7 +82,7 @@ public class Types {
|
||||
static final String AT_DOMAIN_EVENT = BASE_PACKAGE + ".event.annotation.DomainEvent";
|
||||
static final String DOMAIN_EVENT = BASE_PACKAGE + ".event.types.DomainEvent";
|
||||
|
||||
private static Collection<ArchRule> RULES;
|
||||
private static @Nullable Collection<ArchRule> RULES;
|
||||
|
||||
/**
|
||||
* Returns whether jMolecules is generally present.
|
||||
@@ -123,34 +123,38 @@ public class Types {
|
||||
*/
|
||||
public static Collection<ArchRule> getRules() {
|
||||
|
||||
if (RULES == null) {
|
||||
var rules = RULES;
|
||||
|
||||
if (rules == null) {
|
||||
|
||||
var classLoader = JMoleculesTypes.class.getClassLoader();
|
||||
RULES = new ArrayList<ArchRule>();
|
||||
rules = new ArrayList<ArchRule>();
|
||||
|
||||
if (ClassUtils.isPresent(DDD_RULES, classLoader)) {
|
||||
RULES.add(JMoleculesDddRules.all());
|
||||
rules.add(JMoleculesDddRules.all());
|
||||
}
|
||||
|
||||
if (!ClassUtils.isPresent(ARCHITECTURE_RULES, classLoader)) {
|
||||
return RULES;
|
||||
return rules;
|
||||
}
|
||||
|
||||
if (ClassUtils.isPresent(HEXAGONAL, classLoader)) {
|
||||
RULES.add(JMoleculesArchitectureRules.ensureHexagonal());
|
||||
rules.add(JMoleculesArchitectureRules.ensureHexagonal());
|
||||
}
|
||||
|
||||
if (ClassUtils.isPresent(LAYERED, classLoader)) {
|
||||
RULES.add(JMoleculesArchitectureRules.ensureLayering());
|
||||
rules.add(JMoleculesArchitectureRules.ensureLayering());
|
||||
}
|
||||
|
||||
if (ClassUtils.isPresent(ONION, classLoader)) {
|
||||
RULES.add(JMoleculesArchitectureRules.ensureOnionClassical());
|
||||
RULES.add(JMoleculesArchitectureRules.ensureOnionSimple());
|
||||
rules.add(JMoleculesArchitectureRules.ensureOnionClassical());
|
||||
rules.add(JMoleculesArchitectureRules.ensureOnionSimple());
|
||||
}
|
||||
|
||||
RULES = rules;
|
||||
}
|
||||
|
||||
return RULES;
|
||||
return rules;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Core configuration abstractions of Spring Modulith.
|
||||
*/
|
||||
@org.springframework.lang.NonNullApi
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.modulith.core.config;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Core, internal abstractions of Spring Modulith.
|
||||
*/
|
||||
@org.springframework.lang.NonNullApi
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.modulith.core;
|
||||
|
||||
@@ -80,4 +80,12 @@ class ApplicationModulesUnitTests {
|
||||
it -> assertThat(it).contains("Invalid", "'invalid'", "'ni.nested.b.first'"),
|
||||
it -> assertThat(it).contains("Invalid", "'ni'", "'ni.nested.b.first'"));
|
||||
}
|
||||
|
||||
@Test // GH-1192
|
||||
void findsTypeBySimpleName() {
|
||||
|
||||
assertThat(modules.getModuleByName("ni")).hasValueSatisfying(it -> {
|
||||
assertThat(it.contains("RootType")).isTrue();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jspecify</groupId>
|
||||
<artifactId>jspecify</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>spring-modulith-core</artifactId>
|
||||
|
||||
@@ -25,9 +25,9 @@ import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.modulith.core.ApplicationModule;
|
||||
import org.springframework.modulith.core.ApplicationModuleDependency;
|
||||
import org.springframework.modulith.core.ApplicationModules;
|
||||
|
||||
@@ -23,9 +23,9 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.modulith.core.ApplicationModule;
|
||||
import org.springframework.modulith.docs.ConfigurationProperties.ConfigurationProperty;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -124,7 +124,6 @@ class ConfigurationProperties implements Iterable<ConfigurationProperty> {
|
||||
static record ConfigurationProperty(String name, @Nullable String description, String type, String sourceType,
|
||||
@Nullable String defaultValue) {
|
||||
|
||||
@SuppressWarnings("null")
|
||||
static Stream<ConfigurationProperty> of(Map<String, Object> source) {
|
||||
|
||||
String sourceType = getAsString(source, "sourceType");
|
||||
@@ -133,9 +132,9 @@ class ConfigurationProperties implements Iterable<ConfigurationProperty> {
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
ConfigurationProperty property = new ConfigurationProperty(getAsString(source, "name"),
|
||||
ConfigurationProperty property = new ConfigurationProperty(getRequiredAsString(source, "name"),
|
||||
getAsString(source, "description"),
|
||||
getAsString(source, "type"),
|
||||
getRequiredAsString(source, "type"),
|
||||
sourceType,
|
||||
getAsString(source, "defaultValue"));
|
||||
|
||||
@@ -146,6 +145,15 @@ class ConfigurationProperties implements Iterable<ConfigurationProperty> {
|
||||
return StringUtils.hasText(sourceType);
|
||||
}
|
||||
|
||||
private static String getRequiredAsString(Map<String, Object> source, String key) {
|
||||
|
||||
var value = getAsString(source, key);
|
||||
|
||||
Assert.notNull(value, "No value found for key %s in %s!".formatted(key, source));
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
private static @Nullable String getAsString(Map<String, Object> source, String key) {
|
||||
|
||||
Object value = source.get(key);
|
||||
|
||||
@@ -36,7 +36,8 @@ import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.lang.Contract;
|
||||
import org.springframework.modulith.core.ApplicationModule;
|
||||
import org.springframework.modulith.core.ApplicationModules;
|
||||
import org.springframework.modulith.core.DependencyDepth;
|
||||
@@ -98,7 +99,7 @@ public class Documenter {
|
||||
|
||||
private boolean cleared;
|
||||
|
||||
private Map<ApplicationModule, Component> components;
|
||||
private @Nullable Map<ApplicationModule, Component> components;
|
||||
|
||||
/**
|
||||
* Creates a new {@link Documenter} for the {@link ApplicationModules} created for the given modulith type in the
|
||||
@@ -223,6 +224,7 @@ public class Documenter {
|
||||
* @return the current instance, will never be {@literal null}.
|
||||
* @since 1.2.2
|
||||
*/
|
||||
@Contract("_, _ -> this")
|
||||
public Documenter writeAggregatingDocument(DiagramOptions diagramOptions, CanvasOptions canvasOptions) {
|
||||
|
||||
Assert.notNull(diagramOptions, "DiagramOptions must not be null!");
|
||||
@@ -485,18 +487,19 @@ public class Documenter {
|
||||
.forEach(it -> it.addTags(DependencyType.USES_COMPONENT.toString()));
|
||||
}
|
||||
|
||||
@SuppressWarnings("null")
|
||||
private Map<ApplicationModule, Component> getComponents(DiagramOptions options) {
|
||||
|
||||
if (components == null) {
|
||||
if (this.components == null) {
|
||||
|
||||
this.components = modules.stream() //
|
||||
.collect(Collectors.toMap(Function.identity(),
|
||||
it -> container.addComponent(options.defaultDisplayName.apply(it), "", "Module")));
|
||||
|
||||
this.components.forEach((key, value) -> addDependencies(key, value, options));
|
||||
components.forEach((key, value) -> addDependencies(key, value, options));
|
||||
}
|
||||
|
||||
return components;
|
||||
return this.components;
|
||||
}
|
||||
|
||||
private void addComponentsToView(ApplicationModule module, ComponentView view, DiagramOptions options) {
|
||||
@@ -643,6 +646,11 @@ public class Documenter {
|
||||
Styles styles) {
|
||||
|
||||
var component = components.get(module);
|
||||
|
||||
if (component == null) {
|
||||
throw new IllegalStateException("Couldn't find component for module %s!".formatted(module));
|
||||
}
|
||||
|
||||
var selector = options.colorSelector;
|
||||
|
||||
// Apply custom color if configured
|
||||
@@ -1061,6 +1069,7 @@ public class Documenter {
|
||||
return new CanvasOptions(groupers, apiBase, targetFileName, hideInternals, hideEmptyLines);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
String getApiBase() {
|
||||
return apiBase;
|
||||
}
|
||||
@@ -1083,7 +1092,10 @@ public class Documenter {
|
||||
|
||||
// Wipe entries without any beans
|
||||
new HashSet<>(result.keySet()).forEach(key -> {
|
||||
if (result.get(key).isEmpty()) {
|
||||
|
||||
var value = result.get(key);
|
||||
|
||||
if (value != null && value.isEmpty()) {
|
||||
result.remove(key);
|
||||
}
|
||||
});
|
||||
@@ -1161,10 +1173,10 @@ public class Documenter {
|
||||
*
|
||||
* @param name must not be {@literal null} or empty.
|
||||
* @param predicate must not be {@literal null}.
|
||||
* @param description must not be {@literal null} or empty.
|
||||
* @param description can be {@literal null}.
|
||||
* @return will never be {@literal null}.
|
||||
*/
|
||||
public static Grouping of(String name, Predicate<SpringBean> predicate, String description) {
|
||||
public static Grouping of(String name, Predicate<SpringBean> predicate, @Nullable String description) {
|
||||
return new Grouping(name, predicate, description);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,9 +23,9 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.boot.json.BasicJsonParser;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.modulith.docs.metadata.MethodMetadata;
|
||||
import org.springframework.modulith.docs.metadata.TypeMetadata;
|
||||
import org.springframework.modulith.docs.util.BuildSystemUtils;
|
||||
@@ -134,28 +134,39 @@ class SpringModulithDocumentationSource implements DocumentationSource {
|
||||
@SuppressWarnings("unchecked")
|
||||
private static TypeMetadata typeMetadata(Map<String, Object> source) {
|
||||
|
||||
var methods = source.containsKey("methods")
|
||||
? ((List<Map<String, Object>>) source.get("methods")).stream()
|
||||
.map(SpringModulithDocumentationSource::methodMetadata)
|
||||
.toList()
|
||||
var sourceMethods = (List<Map<String, Object>>) source.get("methods");
|
||||
|
||||
var methods = sourceMethods != null
|
||||
? sourceMethods.stream().map(SpringModulithDocumentationSource::methodMetadata).toList()
|
||||
: Collections.<MethodMetadata> emptyList();
|
||||
|
||||
return new TypeMetadata(
|
||||
source.get("name").toString(),
|
||||
getString(source, "comment"),
|
||||
methods);
|
||||
var name = source.get("name");
|
||||
|
||||
if (name == null) {
|
||||
throw new IllegalArgumentException("Source map does not contain a name entry! %s".formatted(source));
|
||||
}
|
||||
|
||||
return new TypeMetadata(name.toString(), getString(source, "comment"), methods);
|
||||
}
|
||||
|
||||
private static MethodMetadata methodMetadata(Map<String, Object> source) {
|
||||
|
||||
return new MethodMetadata(
|
||||
source.get("name").toString(),
|
||||
source.get("signature").toString(),
|
||||
getString(source, "comment"));
|
||||
var name = source.get("name");
|
||||
|
||||
if (name == null) {
|
||||
throw new IllegalArgumentException("No name found in source map! %s".formatted(source));
|
||||
}
|
||||
|
||||
var signature = source.get("signature");
|
||||
|
||||
if (signature == null) {
|
||||
throw new IllegalArgumentException("No signature found in source map! %s".formatted(source));
|
||||
}
|
||||
|
||||
return new MethodMetadata(name.toString(), signature.toString(), getString(source, "comment"));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getString(Map<String, Object> source, String key) {
|
||||
private static @Nullable String getString(Map<String, Object> source, String key) {
|
||||
|
||||
Object result = source.get(key);
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,7 +17,7 @@ package org.springframework.modulith.docs.metadata;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Metadata about a Java type.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Documentation support for Spring Modulith.
|
||||
*/
|
||||
@org.springframework.lang.NonNullApi
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.modulith.docs;
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jspecify</groupId>
|
||||
<artifactId>jspecify</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.modulith</groupId>
|
||||
<artifactId>spring-modulith-api</artifactId>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* AMQP event externalization support.
|
||||
*/
|
||||
@org.springframework.lang.NonNullApi
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.modulith.events.amqp;
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jspecify</groupId>
|
||||
<artifactId>jspecify</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
|
||||
@@ -25,6 +25,7 @@ import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.modulith.events.RoutingTarget.ParsedRoutingTarget;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
@@ -45,7 +46,7 @@ class AnnotationTargetLookup implements Supplier<Optional<ParsedRoutingTarget>>
|
||||
|
||||
private static Map<Class<?>, AnnotationTargetLookup> LOOKUPS = new ConcurrentReferenceHashMap<>(25);
|
||||
private static final String JMOLECULES_EXTERNALIZED = "org.jmolecules.event.annotation.Externalized";
|
||||
private static final Class<? extends Annotation> JMOLECULES_ANNOTATION = loadJMoleculesExternalizedIfPresent();
|
||||
private static final @Nullable Class<? extends Annotation> JMOLECULES_ANNOTATION = loadJMoleculesExternalizedIfPresent();
|
||||
|
||||
private final Class<?> type;
|
||||
private final Supplier<Optional<ParsedRoutingTarget>> lookup;
|
||||
@@ -159,7 +160,7 @@ class AnnotationTargetLookup implements Supplier<Optional<ParsedRoutingTarget>>
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static Class<? extends Annotation> loadJMoleculesExternalizedIfPresent() {
|
||||
private static @Nullable Class<? extends Annotation> loadJMoleculesExternalizedIfPresent() {
|
||||
|
||||
var classLoader = DefaultEventExternalizationConfiguration.class.getClassLoader();
|
||||
|
||||
|
||||
@@ -28,8 +28,8 @@ import java.util.function.BiPredicate;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.modulith.events.RoutingTarget.ParsedRoutingTarget;
|
||||
import org.springframework.modulith.events.RoutingTarget.RoutingTargetBuilder;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -359,7 +359,16 @@ public interface EventExternalizationConfiguration {
|
||||
}
|
||||
|
||||
private static <T extends Annotation> T findAnnotation(Object event, Class<T> annotationType) {
|
||||
return findMergedAnnotation(event.getClass(), annotationType);
|
||||
|
||||
var type = event.getClass();
|
||||
var result = findMergedAnnotation(type, annotationType);
|
||||
|
||||
if (result == null) {
|
||||
throw new IllegalStateException(
|
||||
"Couldn't find annotation %s on type %s!".formatted(annotationType, type));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,9 +17,10 @@ package org.springframework.modulith.events;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.ResolvableTypeProvider;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -103,7 +104,7 @@ public class EventExternalized<S, T> implements ResolvableTypeProvider {
|
||||
*
|
||||
* @return can be {@literal null}.
|
||||
*/
|
||||
public T getBrokerResult() {
|
||||
public @Nullable T getBrokerResult() {
|
||||
return brokerResult;
|
||||
}
|
||||
|
||||
@@ -112,7 +113,7 @@ public class EventExternalized<S, T> implements ResolvableTypeProvider {
|
||||
* @see org.springframework.core.ResolvableTypeProvider#getResolvableType()
|
||||
*/
|
||||
@Override
|
||||
public ResolvableType getResolvableType() {
|
||||
public @NonNull ResolvableType getResolvableType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ package org.springframework.modulith.events;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -238,14 +238,14 @@ public class RoutingTarget {
|
||||
/**
|
||||
* @return the target
|
||||
*/
|
||||
public String getTarget() {
|
||||
public @Nullable String getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the key
|
||||
*/
|
||||
public String getKey() {
|
||||
public @Nullable String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* API of the event publication registry abstraction.
|
||||
*/
|
||||
@org.springframework.lang.NonNullApi
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.modulith.events;
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jspecify</groupId>
|
||||
<artifactId>jspecify</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.modulith</groupId>
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.modulith.events.aot;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.aot.hint.ExecutableMode;
|
||||
import org.springframework.aot.hint.RuntimeHints;
|
||||
import org.springframework.aot.hint.RuntimeHintsRegistrar;
|
||||
@@ -32,7 +33,7 @@ public class ApplicationListenerMethodAdapterRuntimeHints implements RuntimeHint
|
||||
* @see org.springframework.aot.hint.RuntimeHintsRegistrar#registerHints(org.springframework.aot.hint.RuntimeHints, java.lang.ClassLoader)
|
||||
*/
|
||||
@Override
|
||||
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
|
||||
public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) {
|
||||
|
||||
var reflection = hints.reflection();
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ package org.springframework.modulith.events.aot;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.aot.hint.MemberCategory;
|
||||
@@ -43,7 +44,7 @@ public class TransactionalEventListenerAotProcessor implements BeanRegistrationA
|
||||
* @see org.springframework.beans.factory.aot.BeanRegistrationAotProcessor#processAheadOfTime(org.springframework.beans.factory.support.RegisteredBean)
|
||||
*/
|
||||
@Override
|
||||
public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) {
|
||||
public @Nullable BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) {
|
||||
|
||||
Class<?> type = registeredBean.getBeanType().resolve(Object.class);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* AOT support for the Event Publication Registry.
|
||||
*/
|
||||
@org.springframework.lang.NonNullApi
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.modulith.events.aot;
|
||||
|
||||
@@ -19,6 +19,7 @@ import java.time.Clock;
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
@@ -37,7 +38,6 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.context.annotation.Role;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.modulith.events.config.EventPublicationAutoConfiguration.AsyncEnablingConfiguration;
|
||||
import org.springframework.modulith.events.core.DefaultEventPublicationRegistry;
|
||||
import org.springframework.modulith.events.core.EventPublicationRegistry;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Spring configuration for the Event Publication Registry.
|
||||
*/
|
||||
@org.springframework.lang.NonNullApi
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.modulith.events.config;
|
||||
|
||||
@@ -20,7 +20,7 @@ import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
|
||||
@@ -27,10 +27,10 @@ import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.modulith.events.CompletedEventPublications;
|
||||
import org.springframework.modulith.events.EventPublication;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
|
||||
@@ -21,8 +21,8 @@ import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.modulith.events.EventPublication;
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,7 +17,7 @@ package org.springframework.modulith.events.core;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* The event publication registry abstraction.
|
||||
*/
|
||||
@org.springframework.lang.NonNullApi
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.modulith.events.core;
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
*/
|
||||
package org.springframework.modulith.events.support;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.common.TemplateParserContext;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.modulith.events.RoutingTarget;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
|
||||
@@ -22,6 +22,8 @@ import java.util.function.Supplier;
|
||||
import org.aopalliance.aop.Advice;
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.aop.MethodMatcher;
|
||||
@@ -31,7 +33,6 @@ import org.springframework.aop.support.StaticMethodMatcher;
|
||||
import org.springframework.aop.support.annotation.AnnotationMatchingPointcut;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.modulith.events.core.EventPublicationRegistry;
|
||||
import org.springframework.modulith.events.core.PublicationTargetIdentifier;
|
||||
import org.springframework.transaction.event.TransactionPhase;
|
||||
@@ -160,7 +161,7 @@ public class CompletionRegisteringAdvisor extends AbstractPointcutAdvisor {
|
||||
* @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 {
|
||||
|
||||
Object result = null;
|
||||
var method = invocation.getMethod();
|
||||
@@ -232,9 +233,8 @@ public class CompletionRegisteringAdvisor extends AbstractPointcutAdvisor {
|
||||
registry.get().markFailed(event, identifier);
|
||||
}
|
||||
|
||||
@SuppressWarnings("null")
|
||||
private static String lookupListenerId(Method method) {
|
||||
return new TransactionalApplicationListenerMethodAdapter(null, method.getDeclaringClass(), method)
|
||||
return new TransactionalApplicationListenerMethodAdapter("¯\\_(ツ)_/¯", method.getDeclaringClass(), method)
|
||||
.getListenerId();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,12 +19,15 @@ import java.lang.reflect.Method;
|
||||
import java.time.Duration;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.SmartInitializingSingleton;
|
||||
@@ -36,8 +39,6 @@ import org.springframework.context.event.ApplicationListenerMethodAdapter;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.modulith.events.EventPublication;
|
||||
import org.springframework.modulith.events.IncompleteEventPublications;
|
||||
import org.springframework.modulith.events.core.ConditionalEventListener;
|
||||
@@ -64,10 +65,12 @@ public class PersistentApplicationEventMulticaster extends AbstractApplicationEv
|
||||
implements IncompleteEventPublications, SmartInitializingSingleton {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(PersistentApplicationEventMulticaster.class);
|
||||
private static final Method LEGACY_SHOULD_HANDLE = ReflectionUtils.findMethod(ApplicationListenerMethodAdapter.class,
|
||||
"shouldHandle", ApplicationEvent.class, Object[].class);
|
||||
private static final Method SHOULD_HANDLE = ReflectionUtils.findMethod(ApplicationListenerMethodAdapter.class,
|
||||
"shouldHandle", ApplicationEvent.class);
|
||||
private static final Method LEGACY_SHOULD_HANDLE = Objects
|
||||
.requireNonNull(ReflectionUtils.findMethod(ApplicationListenerMethodAdapter.class,
|
||||
"shouldHandle", ApplicationEvent.class, Object[].class));
|
||||
private static final Method SHOULD_HANDLE = Objects
|
||||
.requireNonNull(ReflectionUtils.findMethod(ApplicationListenerMethodAdapter.class,
|
||||
"shouldHandle", ApplicationEvent.class));
|
||||
|
||||
static final String REPUBLISH_ON_RESTART = "spring.modulith.events.republish-outstanding-events-on-restart";
|
||||
static final String REPUBLISH_ON_RESTART_LEGACY = "spring.modulith.republish-outstanding-events-on-restart";
|
||||
@@ -251,16 +254,19 @@ public class PersistentApplicationEventMulticaster extends AbstractApplicationEv
|
||||
* @param payload the actual payload, must not be {@literal null}.
|
||||
* @return whether the event should be handled by the given candidate.
|
||||
*/
|
||||
@SuppressWarnings("null")
|
||||
private static boolean invokeShouldHandle(ApplicationListener<?> candidate, ApplicationEvent event, Object payload) {
|
||||
|
||||
if (!(candidate instanceof ApplicationListenerMethodAdapter listener)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return SHOULD_HANDLE != null
|
||||
? listener.shouldHandle(event)
|
||||
: (boolean) ReflectionUtils.invokeMethod(LEGACY_SHOULD_HANDLE, candidate, event, new Object[] { payload });
|
||||
if (SHOULD_HANDLE != null) {
|
||||
return listener.shouldHandle(event);
|
||||
}
|
||||
|
||||
var result = ReflectionUtils.invokeMethod(LEGACY_SHOULD_HANDLE, candidate, event, new Object[] { payload });
|
||||
|
||||
return result == null ? false : (boolean) result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Spring Framework extensions to integrate the event publication registry.
|
||||
*/
|
||||
@org.springframework.lang.NonNullApi
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.modulith.events.support;
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.time.Instant;
|
||||
import java.time.ZoneId;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
@@ -35,7 +36,6 @@ import org.springframework.boot.test.context.assertj.AssertableApplicationContex
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.boot.test.context.runner.ContextConsumer;
|
||||
import org.springframework.context.annotation.AdviceMode;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.modulith.events.CompletedEventPublications;
|
||||
import org.springframework.modulith.events.IncompleteEventPublications;
|
||||
import org.springframework.modulith.events.config.EventPublicationAutoConfiguration.AsyncPropertiesDefaulter;
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jspecify</groupId>
|
||||
<artifactId>jspecify</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.modulith</groupId>
|
||||
<artifactId>spring-modulith-events-core</artifactId>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* A Jackson based implementation of the {@link org.springframework.modulith.events.core.EventSerializer}.
|
||||
*/
|
||||
@org.springframework.lang.NonNullApi
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.modulith.events.jackson;
|
||||
|
||||
@@ -29,6 +29,11 @@
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jspecify</groupId>
|
||||
<artifactId>jspecify</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>spring-modulith-events-core</artifactId>
|
||||
@@ -51,7 +56,6 @@
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- Testing -->
|
||||
|
||||
<dependency>
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package org.springframework.modulith.events.jdbc;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
@@ -39,7 +40,8 @@ class DatabaseSchemaInitializer implements InitializingBean {
|
||||
private final JdbcOperations jdbcOperations;
|
||||
private final JdbcRepositorySettings settings;
|
||||
|
||||
DatabaseSchemaInitializer(DataSource dataSource, ResourceLoader resourceLoader, JdbcOperations jdbcOperations, JdbcRepositorySettings settings) {
|
||||
DatabaseSchemaInitializer(DataSource dataSource, ResourceLoader resourceLoader, JdbcOperations jdbcOperations,
|
||||
JdbcRepositorySettings settings) {
|
||||
|
||||
this.dataSource = dataSource;
|
||||
this.resourceLoader = resourceLoader;
|
||||
@@ -63,7 +65,7 @@ class DatabaseSchemaInitializer implements InitializingBean {
|
||||
|
||||
if (useSchema) { // A schema name has been specified.
|
||||
|
||||
if (eventPublicationTableExists(schemaName)) {
|
||||
if (eventPublicationTableExists(Objects.requireNonNull(schemaName))) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,10 +15,10 @@
|
||||
*/
|
||||
package org.springframework.modulith.events.jdbc;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.bind.ConstructorBinding;
|
||||
import org.springframework.boot.context.properties.bind.DefaultValue;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Configuration properties for JDBC.
|
||||
@@ -30,7 +30,7 @@ import org.springframework.lang.Nullable;
|
||||
class JdbcConfigurationProperties {
|
||||
|
||||
private final SchemaInitialization schemaInitialization;
|
||||
private final String schema;
|
||||
private final @Nullable String schema;
|
||||
|
||||
/**
|
||||
* Creates a new {@link JdbcConfigurationProperties} instance.
|
||||
@@ -57,8 +57,7 @@ class JdbcConfigurationProperties {
|
||||
*
|
||||
* @return can be {@literal null}.
|
||||
*/
|
||||
@Nullable
|
||||
public String getSchema() {
|
||||
public @Nullable String getSchema() {
|
||||
return schema;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,11 +29,11 @@ import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import org.springframework.jdbc.core.JdbcOperations;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.modulith.events.core.EventPublicationRepository;
|
||||
import org.springframework.modulith.events.core.EventSerializer;
|
||||
import org.springframework.modulith.events.core.PublicationTargetIdentifier;
|
||||
@@ -150,7 +150,7 @@ class JdbcEventPublicationRepository implements EventPublicationRepository, Bean
|
||||
INSERT INTO %s (ID, LISTENER_ID, EVENT_TYPE, SERIALIZED_EVENT, PUBLICATION_DATE, COMPLETION_DATE)
|
||||
SELECT ID, LISTENER_ID, EVENT_TYPE, SERIALIZED_EVENT, PUBLICATION_DATE, ?
|
||||
FROM %s
|
||||
WHERE ID = ?
|
||||
WHERE ID = ?
|
||||
AND NOT EXISTS (SELECT 1 FROM %s WHERE ID = EVENT_PUBLICATION.ID)
|
||||
""";
|
||||
|
||||
@@ -161,7 +161,7 @@ class JdbcEventPublicationRepository implements EventPublicationRepository, Bean
|
||||
FROM %s
|
||||
WHERE LISTENER_ID = ?
|
||||
AND SERIALIZED_EVENT = ?
|
||||
AND NOT EXISTS (SELECT 1 FROM %s WHERE ID = EVENT_PUBLICATION.ID)
|
||||
AND NOT EXISTS (SELECT 1 FROM %s WHERE ID = EVENT_PUBLICATION.ID)
|
||||
""";
|
||||
|
||||
private static final int DELETE_BATCH_SIZE = 100;
|
||||
@@ -170,7 +170,7 @@ class JdbcEventPublicationRepository implements EventPublicationRepository, Bean
|
||||
private final EventSerializer serializer;
|
||||
private final JdbcRepositorySettings settings;
|
||||
|
||||
private ClassLoader classLoader;
|
||||
private @Nullable ClassLoader classLoader;
|
||||
|
||||
private final String sqlStatementInsert,
|
||||
sqlStatementFindCompleted,
|
||||
@@ -222,8 +222,10 @@ class JdbcEventPublicationRepository implements EventPublicationRepository, Bean
|
||||
this.sqlStatementDeleteById = SQL_STATEMENT_DELETE_BY_ID.formatted(table);
|
||||
this.sqlStatementDeleteCompleted = SQL_STATEMENT_DELETE_COMPLETED.formatted(completedTable);
|
||||
this.sqlStatementDeleteCompletedBefore = SQL_STATEMENT_DELETE_COMPLETED_BEFORE.formatted(completedTable);
|
||||
this.sqlStatementCopyToArchive = SQL_STATEMENT_COPY_TO_ARCHIVE_BY_ID.formatted(completedTable, table, completedTable);
|
||||
this.sqlStatementCopyToArchiveByEventAndListenerId = SQL_STATEMENT_COPY_TO_ARCHIVE_BY_EVENT_AND_LISTENER_ID.formatted(completedTable, table, completedTable);
|
||||
this.sqlStatementCopyToArchive = SQL_STATEMENT_COPY_TO_ARCHIVE_BY_ID.formatted(completedTable, table,
|
||||
completedTable);
|
||||
this.sqlStatementCopyToArchiveByEventAndListenerId = SQL_STATEMENT_COPY_TO_ARCHIVE_BY_EVENT_AND_LISTENER_ID
|
||||
.formatted(completedTable, table, completedTable);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -342,9 +344,11 @@ class JdbcEventPublicationRepository implements EventPublicationRepository, Bean
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
@SuppressWarnings("null")
|
||||
public List<TargetEventPublication> findIncompletePublications() {
|
||||
return operations.query(sqlStatementFindUncompleted, this::resultSetToPublications);
|
||||
|
||||
var result = operations.query(sqlStatementFindUncompleted, this::resultSetToPublications);
|
||||
|
||||
return result == null ? Collections.emptyList() : result;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -428,8 +432,7 @@ class JdbcEventPublicationRepository implements EventPublicationRepository, Bean
|
||||
* @return can be {@literal null}.
|
||||
* @throws SQLException
|
||||
*/
|
||||
@Nullable
|
||||
private TargetEventPublication resultSetToPublication(ResultSet rs) throws SQLException {
|
||||
private @Nullable TargetEventPublication resultSetToPublication(ResultSet rs) throws SQLException {
|
||||
|
||||
var id = getUuidFromResultSet(rs);
|
||||
var eventClass = loadClass(id, rs.getString("EVENT_TYPE"));
|
||||
@@ -456,8 +459,7 @@ class JdbcEventPublicationRepository implements EventPublicationRepository, Bean
|
||||
return settings.getDatabaseType().databaseToUUID(rs.getObject("ID"));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Class<?> loadClass(UUID id, String className) {
|
||||
private @Nullable Class<?> loadClass(UUID id, String className) {
|
||||
|
||||
try {
|
||||
return ClassUtils.forName(className, classLoader);
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package org.springframework.modulith.events.jdbc;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.modulith.events.support.CompletionMode;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -29,7 +29,7 @@ import org.springframework.util.Assert;
|
||||
public class JdbcRepositorySettings {
|
||||
|
||||
private final DatabaseType databaseType;
|
||||
private final String schema;
|
||||
private final @Nullable String schema;
|
||||
private final CompletionMode completionMode;
|
||||
|
||||
/**
|
||||
@@ -67,8 +67,7 @@ public class JdbcRepositorySettings {
|
||||
*
|
||||
* @return can be {@literal null}.
|
||||
*/
|
||||
@Nullable
|
||||
public String getSchema() {
|
||||
public @Nullable String getSchema() {
|
||||
return schema;
|
||||
}
|
||||
|
||||
@@ -82,10 +81,14 @@ public class JdbcRepositorySettings {
|
||||
/**
|
||||
* Returns whether we use the archiving completion mode.
|
||||
*/
|
||||
public boolean isArchiveCompletion() { return completionMode == CompletionMode.ARCHIVE; }
|
||||
public boolean isArchiveCompletion() {
|
||||
return completionMode == CompletionMode.ARCHIVE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether we use the updating completion mode.
|
||||
*/
|
||||
public boolean isUpdateCompletion() { return completionMode == CompletionMode.UPDATE; }
|
||||
public boolean isUpdateCompletion() {
|
||||
return completionMode == CompletionMode.UPDATE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* JDBC integration for {@link org.springframework.modulith.events.core.EventPublicationRepository}.
|
||||
*/
|
||||
@org.springframework.lang.NonNullApi
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.modulith.events.jdbc;
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jspecify</groupId>
|
||||
<artifactId>jspecify</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.modulith</groupId>
|
||||
<artifactId>spring-modulith-api</artifactId>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* JMS event externalization support.
|
||||
*/
|
||||
@org.springframework.lang.NonNullApi
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.modulith.events.jms;
|
||||
|
||||
@@ -18,6 +18,11 @@
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jspecify</groupId>
|
||||
<artifactId>jspecify</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>spring-modulith-events-core</artifactId>
|
||||
|
||||
@@ -23,6 +23,8 @@ import java.time.Instant;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.jspecify.annotations.NullUnmarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.modulith.events.jpa.archiving.ArchivedJpaEventPublication;
|
||||
import org.springframework.modulith.events.jpa.updating.DefaultJpaEventPublication;
|
||||
import org.springframework.modulith.events.support.CompletionMode;
|
||||
@@ -45,7 +47,7 @@ public abstract class JpaEventPublication {
|
||||
final String serializedEvent;
|
||||
final Class<?> eventType;
|
||||
|
||||
protected Instant completionDate;
|
||||
protected @Nullable Instant completionDate;
|
||||
|
||||
/**
|
||||
* Creates a new {@link JpaEventPublication} for the given publication date, listener id, serialized event and event
|
||||
@@ -72,6 +74,7 @@ public abstract class JpaEventPublication {
|
||||
this.eventType = eventType;
|
||||
}
|
||||
|
||||
@NullUnmarked
|
||||
protected JpaEventPublication() {
|
||||
|
||||
this.id = null;
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.modulith.events.core.EventPublicationRepository;
|
||||
import org.springframework.modulith.events.core.EventSerializer;
|
||||
import org.springframework.modulith.events.core.PublicationTargetIdentifier;
|
||||
@@ -383,7 +384,7 @@ class JpaEventPublicationRepository implements EventPublicationRepository {
|
||||
|
||||
private final JpaEventPublication publication;
|
||||
private final EventSerializer serializer;
|
||||
private Object deserializedEvent;
|
||||
private @Nullable Object deserializedEvent;
|
||||
|
||||
/**
|
||||
* Creates a new {@link JpaEventPublicationAdapter} for the given {@link JpaEventPublication} and
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
/**
|
||||
* JPA integration for {@link org.springframework.modulith.events.core.EventPublicationRepository}.
|
||||
*/
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.modulith.events.jpa.archiving;
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* JPA integration for {@link org.springframework.modulith.events.core.EventPublicationRepository}.
|
||||
*/
|
||||
@org.springframework.lang.NonNullApi
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.modulith.events.jpa;
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
/**
|
||||
* JPA integration for {@link org.springframework.modulith.events.core.EventPublicationRepository}.
|
||||
*/
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.modulith.events.jpa.updating;
|
||||
@@ -17,6 +17,11 @@
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jspecify</groupId>
|
||||
<artifactId>jspecify</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.modulith</groupId>
|
||||
<artifactId>spring-modulith-api</artifactId>
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.modulith.events.kafka;
|
||||
|
||||
import org.jspecify.annotations.NullUnmarked;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
@@ -53,6 +54,7 @@ class KafkaEventExternalizerConfiguration {
|
||||
private static final Logger logger = LoggerFactory.getLogger(KafkaEventExternalizerConfiguration.class);
|
||||
|
||||
@Bean
|
||||
@NullUnmarked
|
||||
DelegatingEventExternalizer kafkaEventExternalizer(EventExternalizationConfiguration configuration,
|
||||
KafkaOperations<Object, Object> operations, BeanFactory factory) {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Kafka event externalization support.
|
||||
*/
|
||||
@org.springframework.lang.NonNullApi
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.modulith.events.kafka;
|
||||
|
||||
@@ -22,12 +22,12 @@ import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.kafka.core.KafkaOperations;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.support.MessageBuilder;
|
||||
import org.springframework.modulith.events.EventExternalizationConfiguration;
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jspecify</groupId>
|
||||
<artifactId>jspecify</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.modulith</groupId>
|
||||
<artifactId>spring-modulith-api</artifactId>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Messaging event externalization support.
|
||||
*/
|
||||
@org.springframework.lang.NonNullApi
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.modulith.events.messaging;
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jspecify</groupId>
|
||||
<artifactId>jspecify</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>spring-modulith-events-core</artifactId>
|
||||
@@ -26,6 +31,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb</artifactId>
|
||||
<version>5.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
@@ -18,9 +18,9 @@ package org.springframework.modulith.events.mongodb;
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.data.annotation.PersistenceCreator;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -85,7 +85,6 @@ class MongoDbEventPublication {
|
||||
MongoDbEventPublication markCompleted(Instant instant) {
|
||||
|
||||
Assert.notNull(instant, "Instant must not be null!");
|
||||
|
||||
this.completionDate = instant;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* MongoDB integration for {@link org.springframework.modulith.events.core.EventPublicationRepository}.
|
||||
*/
|
||||
@org.springframework.lang.NonNullApi
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.modulith.events.mongodb;
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jspecify</groupId>
|
||||
<artifactId>jspecify</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>spring-modulith-events-core</artifactId>
|
||||
@@ -59,4 +64,5 @@
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.modulith.events.neo4j;
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* The event publication entity definition.
|
||||
|
||||
@@ -29,6 +29,7 @@ import java.util.UUID;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.neo4j.cypherdsl.core.Cypher;
|
||||
import org.neo4j.cypherdsl.core.Node;
|
||||
import org.neo4j.cypherdsl.core.ResultStatement;
|
||||
@@ -40,7 +41,6 @@ import org.neo4j.driver.Values;
|
||||
import org.neo4j.driver.types.TypeSystem;
|
||||
import org.springframework.data.neo4j.core.Neo4jClient;
|
||||
import org.springframework.data.util.Lazy;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.modulith.events.core.EventPublicationRepository;
|
||||
import org.springframework.modulith.events.core.EventSerializer;
|
||||
import org.springframework.modulith.events.core.PublicationTargetIdentifier;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Neo4j integration for {@link org.springframework.modulith.events.core.EventPublicationRepository}.
|
||||
*/
|
||||
@org.springframework.lang.NonNullApi
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.modulith.events.neo4j;
|
||||
|
||||
@@ -118,6 +118,11 @@
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jspecify</groupId>
|
||||
<artifactId>jspecify</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
|
||||
@@ -4,5 +4,5 @@
|
||||
*
|
||||
* @see example.inventory.InventoryInternal
|
||||
*/
|
||||
@org.springframework.lang.NonNullApi
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package example.inventory;
|
||||
|
||||
@@ -4,5 +4,5 @@
|
||||
*
|
||||
* @see example.ModularityTests
|
||||
*/
|
||||
@org.springframework.lang.NonNullApi
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package example.order;
|
||||
|
||||
@@ -4,5 +4,5 @@
|
||||
*
|
||||
* @see example.inventory.InventoryInternal
|
||||
*/
|
||||
@org.springframework.lang.NonNullApi
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package example.inventory;
|
||||
|
||||
@@ -4,5 +4,5 @@
|
||||
*
|
||||
* @see example.ModularityTests
|
||||
*/
|
||||
@org.springframework.lang.NonNullApi
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package example.order;
|
||||
|
||||
@@ -4,5 +4,5 @@
|
||||
*
|
||||
* @see example.inventory.InventoryInternal
|
||||
*/
|
||||
@org.springframework.lang.NonNullApi
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package example.inventory;
|
||||
|
||||
@@ -4,5 +4,5 @@
|
||||
*
|
||||
* @see example.ModularityTests
|
||||
*/
|
||||
@org.springframework.lang.NonNullApi
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package example.order;
|
||||
|
||||
@@ -4,5 +4,5 @@
|
||||
*
|
||||
* @see example.inventory.InventoryInternal
|
||||
*/
|
||||
@org.springframework.lang.NonNullApi
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package example.inventory;
|
||||
|
||||
@@ -4,5 +4,5 @@
|
||||
*
|
||||
* @see example.ModularityTests
|
||||
*/
|
||||
@org.springframework.lang.NonNullApi
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package example.order;
|
||||
|
||||
@@ -4,5 +4,5 @@
|
||||
*
|
||||
* @see example.ModularityTests
|
||||
*/
|
||||
@org.springframework.lang.NonNullApi
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package example.order;
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jspecify</groupId>
|
||||
<artifactId>jspecify</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>spring-modulith-core</artifactId>
|
||||
|
||||
@@ -17,6 +17,10 @@
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jspecify</groupId>
|
||||
<artifactId>jspecify</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jgit</groupId>
|
||||
<artifactId>org.eclipse.jgit</artifactId>
|
||||
@@ -51,5 +55,4 @@
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
</project>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user