> 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]> <[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