We now explicitly handle CompletableFuture instances returned from transactional event listeners by registering the completion handlers only on success, the debug logging on failure and immediately return the decorated instance.
Previously, a failed CompletableFuture instance would still have the publication marked completed as it doesn't cause any exception being thrown and thus ultimately ending up in the code path that issues the completion.
We now propagate potentially occurring exceptions in CompletionRegisteringAdvisor to make sure the standard exception handling facilities kick in, both for synchronous and asynchronous listener invocations.
This implies that during republication we need to handle exceptions to make sure that failing synchronous listeners to not prevent the submission of subsequent publications. We currently log such exceptions into error.
We now register a BeanFactoryInitializationAotProcessor to generate the actuator endpoint content representing the application module structure at AOT processing time. That file is then preferred over bootstrapping an ApplicationModules instance when bootstrapping the endpoint.
We now skip the defaulting to wait of the pool shutdown termination on Spring Framework 6.1, as on that, pools implement Lifecycle and we need to wait for complete shutdown during Lifecycle.stop() already and setting the flag would delay that wait to the actual destruction phase.
The maintain general compatibility with Spring Framework 6.0, we issue a few reflective inspections on ApplicationListenerMethodAdapter. To make this work properly in native images, we now register those methods for GraalVM reflection.
If Spring Modulith packages were explicitly configured as autoconfiguration or entity scan packages, the test autoconfiguration would fail as it previously attempted to manipulate an immutable list. We now create a copy of that list to fix this.
We now gracefully fall back to reflective invocation of the application event listener shouldHandle(…) method if we're not on Spring Framework 6.2. If we are, we invoke the newly introduced method directly.
This allows projects to upgrade to Spring Modulith 1.1 without necessarily upgrading to Boot 3.2.
DelegatingEventExternalizer.externalize(…) flavors now return a CompletableFuture to allow the target APIs to use asynchronous message sending and to transparently return a result from those invocations.
Removed the inclusion of the spring-modulith-runtime artifact from the …-starter-core one to avoid issues in native images in a Spring Modulith default setup. As the artifact is still needed to support ApplicationModuleInitializer implementations, we now explicitly check for the presence of those and verify the artifact is actually available and hint the user at explicitly adding it if missing.
We now expose spring.modulith.events.externalization.enabled that can be set to false to disable the event externalization completely. Useful in test cases, for example.
We now skip configuration classes for observability-related proxying as it's hard to detect those during the ProxyFactory setup to configure target class proxying. Also, configuration classes are usually no targets of inter-module communication and thus don't need to be observed at all.
We now skip infrastructure role beans during the processing of beans that could be subject to inter-module interaction observability. Previously, we could accidentally trigger a dependency cycle if the ModuleTracingBeanPostProcessor triggered the initial creation of AutoConfigurationPackages as that would then trigger the PostProcessor in turn which would try to lookup the ACP bean again to determine whether it should post process that to apply observability.