Skip to content

@DomainEvent detection does not work with inheritance #1118

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
ajax-semenov-y opened this issue Mar 20, 2025 · 4 comments
Open

@DomainEvent detection does not work with inheritance #1118

ajax-semenov-y opened this issue Mar 20, 2025 · 4 comments

Comments

@ajax-semenov-y
Copy link

Hello. I use a custom domain event system in my service, and all domain events share the same root interface. I have annotated this interface with the org.jmolecules.event.annotation.DomainEvent annotation:

@DomainEvent
interface DomainEvent

I then have a more specific interface for a subtype of my domain events:

sealed interface PaymentEvent : DomainEvent {

And a concrete event implementation:

data class PaymentCompletedEvent(
    ....
) : PaymentEvent {

However, the ApplicationModule#publishedEvents remains empty. When I add the @DomainEvent annotation directly to PaymentCompletedEvent, it works.

@ajax-semenov-y
Copy link
Author

ajax-semenov-y commented Mar 20, 2025

I also encountered a similar problem with the @DomainEventHandler annotation. Here is the structure I use for handlers:

interface DomainEventHandler<EventT : DomainEvent, ReturnT : Any> : Ordered {
    // ...
    @DomainEventHandler
    fun handle(event: DomainEvent): ReturnT
    // ...
}
interface BaseDomainEventHandler<EventT : DomainEvent> : DomainEventHandler<EventT, Mono<Unit>> {

    override fun handle(event: DomainEvent): Mono<Unit> {
        // ...
        // some custom logic that calls doHandle
    }

    fun doHandle(event: EventT): Mono<Unit>
}
@Component
internal class DoSomethingOnPaymentCompletedEvent(
    // ...
) : BaseDomainEventHandler<PaymentCompletedEvent> {
    
    override fun doHandle(event: PaymentCompletedEvent): Mono<Unit> {
        // ...
    }
}

The DoSomethingOnPaymentCompletedEvent is not recognized as a domain event listener. I believe the issue lies in JMoleculesArchitecturallyEvidentType#isEventListener, which uses .getMethods() instead of .getAllMethods(). As a result, it only sees the methods within DoSomethingOnPaymentCompletedEvent itself and not all the methods available through the interfaces it implements.

@ajax-semenov-y
Copy link
Author

And also a similar problem with the @NamedInterface annotation. I've created a wrapper annotation:

@NamedInterface("module-api")
annotation class ModuleApi

When I annotate a class with @ModuleApi, it does not recognize it as marked with @NamedInterface, causing the test to fail.

@ajax-semenov-y
Copy link
Author

@odrotbohm could you please assist me in understanding whether this is the expected behavior or not?

@odrotbohm
Copy link
Member

For the jMolecules annotations, it's both. Unexpected from a developer's point of view, but expected from the annotation definition's perspective, as they are currently not declared as @Inherited. While we can certainly work around that limitation in Spring Modulith, I'll discuss this with the jMolecules team to see whether we can fix this at its core.

For @NamedInterface this should actually work as we use AnnotatedElementUtils.getMergedAnnotation(…) that traverses the annotation hierarchy. GH-1052 recently tweaked an edge-case in which we didn't consider meta-annotations. Can you make sure that you are on 1.3.3 or 1.4 M2 at least? If that's the case, and you still don't see this working, please open a separate ticket and ideally attach a reproducer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants