As far as I know this is not possible in CDI/Weld (provided you're talking about a bean definition, not a bean instance). However CDI 1.1 allows to destroy a contextual bean instance via AlterableContext.destroy()  or Instance.destroy() for instances obtained via the Instance interface .
Thanks quick reply!
I am implementing some dynamic bean adding from another Bean Manager by CDI extension. My implementing way is by the following:
((BeanManagerImpl)bm).addBean(bean); ----> bm is a host BeanManager, bean is from another Bean Manager.
This looks well, and ran well too. I think that this way should be related to bean definition just you said.
However, while the another Bean Manager left runtime(eg. by uninstalling bundle related to the another Bean Manager), I need to update the host BeanManager to remove those invalid beans.
So, I come up with the question. I do not know whether I said clearly, ?
Hm, I don't think adding/removing beans in this way is a good idea... anyway as I said before: it's not possible to remove a CDI bean definition in CDI.
This is a very wrong approach. BMI.addBean() should only ever be called by Weld at bootstrap. If you use this from your code at runtime there are no guarantees that Weld will function properly.
you can for example create a CDI context to manage such beans and tie it to a scope(eg:@BundleScoped) then you can remove the bean with bean.destroy(instance,creationalContext) when the context doesnt make sense anymore(eg. uninstalling the bundle).
take a look here for a concrete example: http://rpestano.wordpress.com/2013/06/30/cdi-custom-scope/
maybe it helps.
Firstly, thanks all replies so far. I wish this discuss can continue...
Secondly, I must state the background in detailed for this issue,
An user is trying to build some dynamic Java EE app using JSF 2 + CDI + OSGi, and he wants to reach the following effect,
1) building a web application bundle(called "wab1") which does not contain any concrete content or module.
Eg. imagining that we are building a portal which divides main page into different blocks and each block represents a concrete content.
Or, a mission-critical application maybe needs to add a new function(module) , however, we can not stop jvm or appserver's instance...
The wab uses and extends JSF to locate external resources which come from those concrete modules, and also uses EL and CDI in JSF files.
2) after we deployed the wab, a bean manager(called "bm1") has been created, and while accessing the wab's main page, no any content is displayed.
3) well, we start to build a new wab(called "wab2") with concrete content(still using CDI+JSF) and we wish wab1 can use wab2's resource including beans. Thus, after deploying wab2, a bean manager(called "bm2") has been created too, while accessing wab1's main page, we wish that wab2's contents can be displayed and work normally.
If you understand what I said above, you should know why I want to merge the two bean manager's contents, and while undeploying wab2, I also need to destroy some invalid beans from wab1.
I know such a merge has a very big risk because bean's creation is related to context and others(just as jozef said), also knows Rafael's suggestion because I myself am also contributing GlassFish CDI module.
What I want to express is that in current status(Bean Manager is virtually static because it has been formed on deploying), whether having some better doing to finish such dynamic effect?
I am very sorry for spending your much time on the issue.
what's the difference between your solution and Weld-osgi(RFC 193)?
as i see in the Hotels example from weld-osgi branch there is a main web application(war) which has a bean(HotelsBean) that get hotels from Hotel providers(OSGi bundles) via Service injection and show information about them in the main web app. With your approach you will have the ability to get information directly from any bean in any installed OSGi bundle(wab) without the need inject them in a main web application. That is it? that can't be done with weld-osgi?
Do you have any code to share? i'm really interested in modular JavaEE applications and would like to help.
I am glad to re-focus to RFC 193,
>what's the difference between your solution and Weld-osgi(RFC 193)?
There are some important difference between my background and RFC 193 as following,
1. RFC 193 focuses on OSGi Service's injection and publishing by means of CDI, instead, my background is that we do not use OSGi Service and only use OSGi modularization to implement dynamic CDI.
2. HotelsBean only uses OSGi Services to obtain Hotel while having a new Hotel Provider Bundle is deployed, the new Hotel Provider Bundle is only a plain OSGi bundle with CDI, if seeing the following, similar to Hotel Provider Bundle's role, however, my module2 is formed by a war structure, it has itself's JSF file and backing beans. Well, what I wish is that for an user , he can access module2's resource from main wab's context rather than a separate context, what's more, I wish module2's beans can be available in main wab's context(using EL) too.
Whether you have understood the scene enough?
sure, it was more or less what i thought.
I will try to summarize.
So we have two approaches, in fact there are others but lets focus on this topic:
- use OSGi service injection/publication via CDI(RFC 193) and use them to show information in a main application
- use multiple OSGi modules(wabs) and access them directly in the main application through CDI
problems with the first way:
- deal with OSGi dynamism in CDI beans
problems with second way:
- data is managed only by main application, for example i can't create a CRUD per bundle and plug them in the main application (thats right?)
- the bundles are not high coesive cause eg: i cant test a bundle JSF page without plugging it in the main application
advantages of first approach:
- problems of the second approach are solved(thats right?)
advantages of second approach:
- service dinamism integrated with CDI
anything else? did i misunderstand something?
I will take a look at your sample Tang but i think what i'm looking for is a fusion of both approaches, see yaa.
i wasnt able to run your sample Tang. I got classcastException in bundleContextProducer, do i have to configure anything else to get it running? i tried with lastest build of Glassfish v4.0.1 and 18.104.22.168.
I also tried to deploy Weld-OSGi Hotels application in glassfish via deploy(type=osgi) and through OSGi web console in glassfish without success.
Thanks your effort so far, and I have some things not stating clearly,
1. About my sample running
Needing more , pl. waiting until tommorrow and I will give you detailed steps and send you some jars which is in my local harddisk.
2. About the issue
I have filed a issue into OSGi JIRA, we should move our focus into that jira, however, I will let the weld thread open, maybe in the future, once having any result, we will come back the thread.
I have uploaded all related bundles into the following,
Pl. reading https://github.com/tangyong/GlassFishOSGiJavaEESample/blob/master/incubation/deploying_running in order to run the sample correctly.
BTW: I also uploaded patches related the issue and if you can see how I modify.