Reputation: 1192
How do I find the bundle that exports a package?
I am using felix and I have a string like "com.test", how do I know which bundle exports that package?
I don't want to use PackageAdmin as it has been deprecated, and I don't really want to get the Export-Package header for each bundle and parse it.
Any ideas?
Upvotes: 8
Views: 7563
Reputation: 15372
A quick solution is to iterate over the bundles, list the id and the export package header.
g! each (bundles) { echo ($it bundleId) (($it headers) get Export-Package) }
Note that you need to put spaces around the {
and }
! This prints for each bundle, its id and its Export-Package header. You can put this in a cmd:
g! exports= { each (bundles) { echo ($it bundleId) (($it headers) get Export-Package) } }
You can then use it easier with grep
:
g! exports | grep webconsole
12 org.apache.felix.webconsole;version="3.3.0";uses:="javax.servlet,javax.servlet.http,org.osgi.framework",org.apache.felix.webconsole.bundleinfo;version="1.0.0";uses:="org.osgi.framework",org.apache.felix.webconsole.i18n;version="1.0.0";uses:="org.osgi.framework"
true
The official command for exported packages is inspect
g! inspect cap osgi.wiring.package
However, the output is very messy and hard to grep. However, if you know the package name then you can ask (deprecated) Package Admin.
g! r=servicereference org.osgi.service.packageadmin.PackageAdmin
....
g! pa=service $r
org.apache.felix.framework.PackageAdminImpl@2c7b40e3
g! $pa exportedpackages org.osgi.framework
org.osgi.framework; version=1.10.0
org.osgi.framework; version=1.9.0
org.osgi.framework; version=1.10.0
org.osgi.framework; version=1.9.0
g! each ($pa exportedpackages org.osgi.framework) { $it exportingbundle }
0|Active | 0|org.apache.felix.framework (0.1.0.SNAPSHOT)
Unfortunately, the Package Admin methods are overloaded and Gogo picks the first one that matches, otherwise it would be a lot easier :-(
If you have the set of bundles then the bnd
command line can be useful. You can install it here.
You can then do:
$ bnd find -e "com.example*" jars/*.jar
or
$ bnd grep -e "com.example*" jars/*.jar
Upvotes: 5
Reputation: 626
It sounds like you want to do this programmatically, not at the Gogo shell ... at least I'll assume that from wording of your question.
There is no real way to say "which bundle" exports a given package since there can be many bundles exporting any given package and that package can be in use from many bundles by many bundles. If you have a specific bundle and you want to know which bundle provides package com.test
to it, you can get the importing bundle's wiring Bundle.adapt(BundleWiring.class)
and then use BundleWiring.getRequiredWires()
to get the providers of all of the bundle's dependencies.
From there you just need to find the wire of osgi.wiring.package
namespace for the package you want, then the provider of that wire will be a BundleCapability
of a BundleRevision
of the bundle you are interested in.
Upvotes: 12
Reputation: 6100
Recent versions of the Apache Felix OSGi console include a "dependency finder" plugin which lists the bundle(s) that export a given package or class. There are some screenshots at http://www.6dlabs.com/blog/dklco/2012-05-04/new-cq-55-dependency-finder (which mention CQ5 but the plugin does not depend on that).
That's useful at the admin level, and if you need to find that out in code you could have a look at that plugin's source code, see https://issues.apache.org/jira/browse/FELIX-3045
Upvotes: 3