We now consider all methods that are (meta-)annotated with Spring Messaging's @MessageMapping which is consistently used in a lot of broker annotations such as @(Rabbit|Kafka)Listener etc.
We now properly translate jMolecules' @Module declaration configuring the id attribute explicitly into the identifier used for an application module.
Introduce @ApplicationModule(id = …) for Spring Modulith-native identifier customization.
Introduced ApplicationModuleIdentifier that ensures that identifiers chosen for application modules do not contain a double colon (::) as we need those as separator characters for manual dependency declarations referring to named interfaces.
As @Module is absent from the Kotlin flavor of jMolecules, code that refers to that is now guarded with a more specific check for that type in particular.
ApplicationModule now exposes both getDirectDependencies(…) and getAllDependencies(…), the former as alias for the now deprecated getDependencies(…) for symmetry reasons. The latter recursively resolves transitive dependencies.
We now optimize the dependency analysis by skipping types residing java and javax packages as they're not relevant to our dependency arrangement model. A few additional optimizations in ApplicationModuleDependencies to avoid iterating over each establishing dependency if all we need to look at is the general module dependency arrangement.
Improve performance of ApplicationModule.contains(…) checks by checking whether the given type can even live inside the package space of the module.
We now expose ApplicationModuleSourceFactory as Spring Factories-based SPI interface to further contribute ApplicationModuleSource instances either from a provided root package subject for module detection through a (potentially customized) ApplicationModuleDetectionStrategy or by explicitly listing particular module base packages.
The ApplicationModules bootstrap now triggers the module base package detection, followed by a new, additional pass of detecting nested application module packages. Those packages are now added to the ones we create ApplicationModule instances for and also handed into the module instance creation step as exclusions to make sure that parent modules do not include code residing in sub-modules.
The bootstrap of ApplicationModules now uses a dedicated ApplicationModuleSource to allow calculating a default module name relative to the application base package.
Each module now operates on the Classes instance obtained from the JavaPackage instance that constitutes the module's base package but filtered by the given exclusions.
If named interfaces are declared in nested packages, the name detection might accidentally pick up the names declared in child packages. We now deliberately only inspect the base package.
As we process a type's entire type hierarchy for dependencies we might discover a foreign module's internal dependencies for modules that declare allowed dependencies explicitly. Explicitly declared dependencies so far solely verified the target being explicitly listed, which, for internal dependencies does not make sense. We now immediately start checking the source and target modules to be equivalent, in which case we can skip any further processing.
We now expose a configuration property spring.modulith.detection-strategy that can take either of the two prepared values "direct-sub-packages" (default) or "explicitly-annotated", or a fully qualified class name of the strategy to use.
Removed ApplicationModuleStrategies enum to avoid exposing the enum values as additional implementations. Those are now held as inline lambda expression in the factory methods on ApplicationModuleStrategy. Extracted the lookup of the strategy to use into ApplicationModuleDetectionStrategyLookup for easier testability.
The previous change unfortunately altered the CacheKey type in a way that it does not result in equal instances for the same set of parameters, primarily because SingletonSupplier does not implement equals(…)/hashCode(). We now resort to include the ModulithMetadata source in the equals(…) / hashCode() calculation rather than the ModulithMetadata instance itself. This also avoids annotation processing during CacheKey instance creation.
Previously, we had a variety of places calculating the overall packages to inspect for types. This is now all consolidated into the ModulithMetadata abstraction exposing them directly.
When defining allowed application module dependencies to named interfaces, the asterisk can now be used to allow referencing all named interfaces declared by the target module.