OSGi feature uninstall works, but bundles are still installed
EDIT: updated this question with latest information...
I'm having issues running back-to-back "features:uninstall" commands for dependent features. OSGi responds back with "State change in progress...", but by accepting other requests, we run into issues.
Strangely, this results in successful feature uninstalls, but unsuccessful bundle uninstalls. We are addressing this by trying to order uninstall requests appropriately and adding a delay between steps, but I'm hoping for a more robust solution.
As suggested, I also tried adding "osgi:refresh" in between steps...same behavior. Is there another way to detect that "Refresh Packages" is still running to delay subsequent requests, etc?
Here are the details...
karaf@root> features:uninstall PolicyUtil
karaf@root> features:uninstall Policy1
karaf@root> features:uninstall Policy2
State change in progress for bundle "file:/policy2.jar" by thread "Refresh Packages".
karaf@root> features:uninstall Policy3
State change in progress for bundle "file:/policy3.jar" by thread "Refresh Packages".
karaf@root> features:uninstall Policy4
karaf@root> features:uninstall Enabler1
State change in progress for bundle "file:/enabler1.jar" by thread "Refresh Packages".
karaf@root> features:uninstall Enabler2
State change in progress for bundle "file:/enabler2.jar" by thread "Refresh Packages".
afterwards...we end up with features uninstalled (correct), but some bundles still installed (incorrect)
osgi:list
[ 277] [Installed ] [ ] [ ] [ 60] Policy2
[ 278] [Installed ] [ ] [ ] [ 60] Policy3
[ 280] [Installed ] [ ] [ ] [ 60] Enabler1
[ 281] [Installed ] [ ] [ ] [ 60] Enabler2
features:list
[uninstalled] [1.0 ] PolicyUtil repo-0
[uninstalled] [1.0 ] Policy1 repo-0
[uninstalled] [1.0 ] Policy2 repo-0
[uninstalled] [1.0 ] Policy3 repo-0
[uninstalled] [1.0 ] Enabler1 repo-0
[uninstalled] [1.0 ] Enabler2 re开发者_如何学Gopo-0
I'm not sure what kind of exception you will get, but you should be aware of one thing: when you uninstall a bundle using a shell command like osgi:uninstall
, you effectively call Bundle.uninstall()
. As you can read in the Javadoc there, this is not the entire story.
The framework favors operations that have minimal impact on the rest of the framework, so it can uninstall a bundle without removing all related packages. If you really want to remove all of them, you should use a osgi:refresh
command. For more information on this, see the Felix FAQ.
The best advice I can give is to not issue multiple uninstall
requests that can cross each other. If you want to remove a set of bundles, I would fire off non-crossing uninstall()
requests, followed by a single refreshPackages()
. Also, I would not mix bundle management using the 'regular' console and Karaf in a single system.
You could also consider using an external manager for installing and removing bundles. If you want remote management, you could go for Apache ACE (disclosure: I'm an Apache ACE committer).
Oor ... you can simple uninstall your app with this command:
karaf 2.2.x:
osgi:uninstall --force yourapp-feature/0.0.1.SNAPSHOT
Alright, I've been digging into this and I think I understand the issue and the options...thanks for the responses.
When "features:uninstall [name]" is executed, it calls bundle.uninstall(), then refreshPackages() for each bundle in the features. Then, after all bundles are uninstalled, it calls refreshPackages() for all bundles. The issue is that refreshPackages() is asynchronous (per the OSGi spec) and leaves bundles in a resolving state. Subsequent requests to uninstall resolving features/bundles fail to complete as expected.
If there is sufficient delay in between uninstalls or if a later uninstall is executed (after the refreshPackages() has completed)...everything works as expected.
Options...
- order dependent features/bundles during uninstallation (difficult to control)
- put a delay in between uninstall commands (not exact)
- verify expected features/bundles are uninstalled (or continue waiting)
- listen for FrameworkEvent.PACKAGES_REFRESHED events (complex and not guaranteed because events are container wide, see this example)
- modify Karaf/Felix to support an option for synchronously refreshing packages (see this issue/resolution for Karaf 2.1.3)
In my experience this happens when a resource of a bundle is still referenced or used by another bundle. In this case the framework is not able to remove the bundle and the whole jar file is still processed by the VM.
Have a look and be sure that all references are removed. A common mistake is also still running thread in one of the objects instantiated in the bundle. This also counts as a resource still in use ad which cannot be removed.
In my case i have uninstalled the feature and noticed the hanging bundle numbers and then shutdown karaf (3.x). Then i have removed the subfolders of folder [karaf-install]/data/cache/[hanging-bundle-number]. Now i restart karaf and the bundle wars not shown in the bundle:list.
精彩评论