You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@openwebbeans.apache.org by Christian Ortlepp <ch...@hypergene.com> on 2025/10/22 07:13:21 UTC

Dependent Bean Destruction

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


Re: Dependent Bean Destruction

Posted by Christian Ortlepp <ch...@hypergene.com>.
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 
>> <ch...@hypergene.com>:
>>
>> 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
>>
>

Re: Dependent Bean Destruction

Posted by Christian Ortlepp <ch...@hypergene.com>.
 > 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 
>> <rm...@gmail.com>:
>>
>> > 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 
>> <ch...@hypergene.com> 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
>>>>     <ch...@hypergene.com>
>>>>     <ma...@hypergene.com>:
>>>>
>>>>     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
>>>>
>>>
>

Re: Dependent Bean Destruction

Posted by Mark Struberg via user <us...@openwebbeans.apache.org>.
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 <rm...@gmail.com>:
> 
> > 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 <christian.ortlepp@hypergene.com <ma...@hypergene.com>> 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 <ch...@hypergene.com> <ma...@hypergene.com>:
>>>> 
>>>> 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
>>>> 
>>> 


Re: Dependent Bean Destruction

Posted by Romain Manni-Bucau <rm...@gmail.com>.
> 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 <
christian.ortlepp@hypergene.com> 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
> <ch...@hypergene.com> <ch...@hypergene.com>:
>
> 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
>
>
>

Re: Dependent Bean Destruction

Posted by Christian Ortlepp <ch...@hypergene.com>.
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 
>> <ch...@hypergene.com>:
>>
>> 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
>>
>

Re: Dependent Bean Destruction

Posted by Mark Struberg via user <us...@openwebbeans.apache.org>.
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 <ch...@hypergene.com>:
> 
> 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
>