quarkusio / quarkus

Quarkus: Supersonic Subatomic Java.
https://quarkus.io
Apache License 2.0
13.44k stars 2.58k forks source link

Documentation: Clarify possible self-invocation as CDI extension #41545

Closed Felk closed 1 month ago

Felk commented 1 month ago

Description

It would be appreciated if some person of authority on the subject (@Ladicek maybe?) could clarify, and maybe even add a section about this to https://quarkus.io/guides/cdi-reference that in Quarkus, beans are indeed intercepted on self-invocation, even though this is not possible with standard CDI. For example, the following code works in Quarkus:

@ApplicationScoped
@Transactional
public class MyService {
    @Transactional(REQUIRES_NEW)
    protected void doStuffInNewTransaction() {
        System.out.println("do stuff, but in a new transaction");
    }

    @Scheduled(every = "PT1S")
    void someSchedule() {
        System.out.println("do stuff");
        // This call goes through a transactional interceptor! (TransactionalInterceptorRequiresNew),
        // even though in pure CDI self-invocation does not perform interception.
        doStuffInNewTransaction();
    }
}

However, in CDI this would not be possible and instead none of the annotations on doStuffInNewTransaction would have any effect for the above invocation. See also CDI-414

Implementation ideas

No response

quarkus-bot[bot] commented 1 month ago

/cc @Ladicek (arc), @manovotn (arc), @mkouba (arc)

Felk commented 1 month ago

I also found this on StackOverflow:

They need to be public, protected or package-private (default visibility). They must not be private. Self-interception works, so you can call a @Transactional method from within the same class and the transactional interceptor will be called, but again, the method must not be private. – Ladicek Jun 29, 2021 at 15:53

but couldn't find any source to verify these claims

mkouba commented 1 month ago

that in Quarkus, beans are indeed intercepted on self-invocation, even though this is not possible with standard CDI.

Keep in mind that this is not codified in the spec. So when you say "it is not possbile" it actually means that the implementation you're using does not support that.

That said, +1 for a new section in the reference guide.

Ladicek commented 1 month ago

Yeah, the situation on the specification(s) side is not very clear. It is a good point that we should make this clear in the documentation.

manovotn commented 1 month ago

However, in CDI this would not be possible and instead none of the annotations on doStuffInNewTransaction would have any effect for the above invocation. See also CDI-414

To be more precise, the CDI specification (and its members) was never unified in this. This might well be because different impls took different views and approaches to it long before the question came up on the spec level. With that in mind, there was never a TCK test for it and so any impl is free to choose how this works for them. You're correct that for instance in Weld the interception won't happen; IIRC, there is in fact a fair amount of special code to prevent that from happening.

add a section about this to https://quarkus.io/guides/cdi-reference that in Quarkus

I definitely agree, I am surprised we didn't mention it already; it came up several times already. We can probably add it under non-standard features; I can send a PR.