> Afair they already do use Instance<T>, but without a proper destroy. And that exactly created the issue, right?

Yes, exactly.

> Note that the destroy of Dependent Scoped beans in Instance only got pinned down in later CDI versions. So maybe the old OWB version did _not_ store the CreationalContexts but due to updating to a newer version it now does.

Ah that makes sense, maybe that's how we got into this situation.

> If it's just about thread safety, then what about moving those classes to @RequestScoped?

I'll have to think about it some more, but I don't (immediatly) see why not. Thanks, that sounds like the easiest option

> The solution with reflection is one to avoid. Rather use the proper Instance<T>:destroy as Romain mentioned. That will properly clean up, making sure any @PreDestroy will properly called, Interceptors get cleaned up etc. This is really important. With just blasting away the map content you'll loose all those potentially important cleanup tasks. Think about one of your @Dependent scoped beans opens a file handle or has some open cache etc.

Yeah, I know. We currently don't experience these problems because it has always (not) worked this way in our application, hence we don't rely on it. But I want to stop using this solution precisely for those reasons, and also because it's obviously not portable to other CDI implementations and may stop working at any time if OWB decides to move things around internally.


Thanks to both of you for your suggestions!


Best,

Christian


On 10/24/25 10:20, Mark Struberg via user wrote:
External Message - Please be cautious when opening links or attachments

Afair they already do use Instance<T>, but without a proper destroy. And that exactly created the issue, right?

Note that the destroy of Dependent Scoped beans in Instance only got pinned down in later CDI versions. So maybe the old OWB version did _not_ store the CreationalContexts but due to updating to a newer version it now does.

If it's just about thread safety, then what about moving those classes to @RequestScoped? If you have something with state then still you might have to deal with 'leftovers' from previous invocations. But at least thread-safety is not a concern anymore. RequestScoped beans get destroyed when the servlet request ends or when the Thread gets properly terminated. If you handle the Thread creation/destroy yourself then make sure that you use e.g. the RequestContextController.

The solution with reflection is one to avoid. Rather use the proper Instance<T>:destroy as Romain mentioned. That will properly clean up, making sure any @PreDestroy will properly called, Interceptors get cleaned up etc. This is really important. With just blasting away the map content you'll loose all those potentially important cleanup tasks. Think about one of your @Dependent scoped beans opens a file handle or has some open cache etc.


Next step imo: verify if @RequestScoped would be doable.

LieGrue,
strub



Am 24.10.2025 um 09:58 schrieb Romain Manni-Bucau <[email protected]>:

> Now every time the @Singleton accesses its @Dependent member, the instance creates a new Object

No, every time the enclosing instance is created, so once for a singleton - this is even a perf optim to inject a dependent bean in a singleton, you have yet another singleton but without proxy.
The "every time" is "per lookup/injection" time.

If you need to create a new one every time inject a Provider<YourDep> or Instance<YourDep>, just do not forget to call destroy yourself (https://docs.jboss.org/cdi/api/2.0/javax/enterprise/inject/Instance.html#destroy-T-).

Romain Manni-Bucau
@rmannibucau <https://x.com/rmannibucau> | .NET Blog <https://dotnetbirdie.github.io/> | Blog <https://rmannibucau.github.io/> | Old Blog <http://rmannibucau.wordpress.com/> | Github <https://github.com/rmannibucau> | LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book <https://www.packtpub.com/en-us/product/java-ee-8-high-performance-9781788473064>
Javaccino founder (Java/.NET service - contact via linkedin)


Le ven. 24 oct. 2025 à 09:02, Christian Ortlepp <[email protected]> a écrit :

    Good Morning Mark,

    first of all thanks for the swift and detailed answer! Since this
    list has been quiet for a while I wasn't sure if there even was
    someone reading it ^^. I also read the article you suggested,
    while most of it wasn't new to me it was a really nice way to
    brush up on the foundational concepts again, thanks!

    So my concrete scenario as I understand it is the following (if
    I'm making any incorrect assumptions please do correct me): We
    have an @ApplicationScoped/@Singleton bean which has @Dependent
    bean members that are accessed via Instances/Providers. Now every
    time the @Singleton accesses its @Dependent member, the instance
    creates a new Object (as is specified by @Dependent) and
    remembers this object in its creationalContext. Since the "owner"
    of this is instance is very long lived (i.e. the lifetime of the
    application), that owner will never be destroyed by  OWB, and
    therefore it's member instances (including our @Dependent one
    with all the object it still references) won't either. Thus we
    have a memory leak (if we don't clean up the objects manually,
    which we do not). And as I understand the spec this is exactly
    how OWB (or any compliant application) should behave, we are just
    using it wrong. But since we have been doing so for decades,
    making this right is no easy feat.

    You suggested that most often the @Dependent beans should
    actually be @ApplicationScoped. I believe that in my application
    they didn't want to use that scope, as it would have required
    them to make the implementations thread-safe. Whether that was a
    good decision is a different question.

    Our current solution intercepts any @Singleton/@ApplicationScoped
    Provider/Instance injections, and then replaces (via reflection)
    the creationalContext in the instance implementation with a dummy
    map which does not remember any items that are put into it. Thus
    making sure that no references to our objects can hang around in
    there, but also breaking @PreDestroy hooks (and possibly other
    features / internal assumptions of OWB). We don't really need
    @PreDestroy there so this solution works for us, but the fact
    that we meddle in the internals of a third-party library via
    reflection is just ... not how I like to do things.

    I'm not really sure what my ideal solution would like though.
    Initially I thought that I would like the injected object to be
    an "instance singleton" (keeping with your terminology in the
    article), i.e. unique to its injection point. I realize now that
    that would create problems if the beans are not
    thread-safe (which is very likely the case) and we're injecting
    into a @Singleton. Another idea was to re-implement the current
    behavior using normal jakarta APIs, i.e. implementing a custom
    scope that does not remember created instances. This should
    mostly work, the only obstacle that I see for that is that we
    still have some modules that use `bean-discovery-mode="all"` in
    their beans.xml, and those beans would then still use the
    standard @Dependent scope (but this is probably fixable with an
    acceptable amount of work). Another version of that last option
    would be to only create new objects for every thread (thus
    ensuring thread safety and at the same time limiting the number
    of new objects that are created). But especially in the advent of
    VirtualThreads I don't think it's a good idea to build new things
    on top of ThreadLocal.


    I hope that my explanation of the situation was clear and I'm
    looking forward to any questions/suggestions you may have.


    Best,

    Christian


    On 10/23/25 07:53, Mark Struberg via user wrote:
    External Message - Please be cautious when opening links or
    attachments

    Good morning Christian!

    Dependent Scoped beans get destroyed whenever either the cleanup
    gets invoked manually or (that's the most important use case)
    when the CreationalContext it is contained gets destroyed. This
    is usually the CreationalContext of the NormalScoped bean it got
    injected into.

    Often people make Dependent Scoped beans without thinking about
    what lifecycle the instances should have. Many times it is plain
    wrong and they should rather have used @ApplicationScoped
    instead. I don't know how much contact you already had with the
    CDI spec, so please excuse if I explain things you already know.
    But my experience is that people often use advanced technology
    (CDI, JPA, etc) without ever learning about the very mechanics.
    Maybe it helps to go back and read that very old (but mostly
    still valid) article I wrote together with my fellow CDI spec
    author Pete Muir:
    
https://entwickler.de/java/tutorial-introduction-to-cdi-contexts-and-dependency-injection-for-java-ee-jsr-299-104536

    In short: if you do NOT use a @Dependent scoped bean in a
    NormalScoped bean, EJB, Servlet Filter or any other EE instance
    which is defined to support CDI, then we also do not store it's
    CreationalContext. Thus there should also be no mem leak.

    I'm interested to learn about how your scenario looks like and
    where the references pile up. Maybe there was some 'workaround'
    implemented which is really not needed at all if CDI is used
    properly?

    txs and LieGrue,
    strub




    Am 22.10.2025 um 09:13 schrieb Christian Ortlepp
    <[email protected]>
    <mailto:[email protected]>:

    Hey,

    I have a question about the implementation of @Dependent bean
    destruction in OpenWebBeans. As per 2.5.4.2. of the cdi spec
    (https://jakarta.ee/specifications/cdi/4.0/jakarta-cdi-spec-4.0.pdf
    page 77) "Finally, the container is permitted to destroy any
    @Dependent scoped contextual instance at any time if the
    instance is no longer referenced by the application (excluding
    weak, soft and phantom references).". Is this implemented in
    OpenWebBeans, and if so is it enabled by default or do I have
    to configure it?


    My motivation for having something like this is the following:
    In the application I am working on @Dependent beans are pretty
    widely used (I'm guessing because by using them one didn't have
    to think about lifetimes/thread safety so much). The developers
    that did this however usually did not remember to call
    `instance.destroy(bean)` after they were done using that
    object. This lead to memory leaks (because the OpenWebBeans
    Instance kept references to those objects, as it should if I
    understood the spec correctly) and my application has some
    pretty horrible workarounds in place to make those memory leaks
    go away. I would like to get rid of those workarounds, or at
    least use a less horrible one. The workarounds we have in place
    are also very old and were originally written for (I believe)
    OWB 1.x. It may very much be that the current version (which we
    are using) no longer needs (some of) the workarounds, my goal
    is to get a better understanding of what should be happening.


    Practically what I'm looking for is a way to declare a bean in
    a way that if I get() it via an instance, that instance will
    immediately forget about the bean after handing it to me so
    that the bean can be garbage collected once I'm done using it.
    If anybody has an idea how to achieve this either with built-in
    means or with extensions I would appreciate any ideas or
    further resources.


    Best,

    Christian


Reply via email to