Hi Jerome, Rob- I've been thinking about Restlet's osgi deployment issues, and experimenting with a few things. (Jerome, please let me know if this sort of post is more appropriate for the restlet.code list than the restlet.discuss one- I'm happy to post to either...)
If Restlet is commited to using the ServiceLoader pattern (/META-INF/services/ approach) for it's extension-binding facility, and you don't want to use the whiteboard pattern in osgi, then I think there may be a better way to handle osgi deployment, one where you can remove the need for the internal Activator entirely. The solution is to make the connector extension bundles into Bundle Fragments. This involves only adding an additional Manifest header to the extension bundle Manifests like so: Fragment-Host: org.restlet This declares that the bundle is a fragment, and that its "host" bundle is the main org.restlet bundle. Being a fragment means that at runtime the contents of the fragment get added in to the host, and become effectively part of the host bundle. All of the fragment's resources and classes become accessible through the host bundle's classloader. This means that when the main restlet's Engine class goes through its standard discovery process, it will find the extension's /META-INF/services/Helper resources, and load the extension like normal. Getting rid of the org.restlet Activator has the additional benefit of fixing a nasty bundle-ordering dependency which exists now (where the org.restlet bundle must not only be installed but also STARTED before any client code can access it's packages, otherwise the connectors won't be loaded yet). Any thoughts? Does anyone know any reasons why using fragments in this way is a bad idea? Oh, and by the way, the org.restlet.engine.internal.Activator actually has a bug with respect to how it iterates over the available bundles (and how it reacts to Bundle events). It's algorithm is to ask each bundle whether it contains an "entry" for a resource name "/META-INF/services/SomeTypeOfHelper", and if it does it attempts to load the class specified inside that entry. This is too permissive- it's important to filter out bundle types/states that won't work. In particular, any bundle which is in the INSTALLED state and is unable to be RESOLVED (due to missing dependencies), or an bundle which is UNINSTALLED, or any bundle which is a "Fragment" bundle, will throw an exception when bundle.loadClass() is called on it. The first few cases can be checked for by looking at the bundle state. Whether a bundle is a Fragment can be checked by getting an instance of the PackageAdmin service (a built-in framework service) and calling packageAdmin.getBundleType(bundle). In order for the fragment solution I describe above to work, the activator must be removed or fixed to not blow up on encountering a fragment... -Dave ------------------------------------------------------ http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=1346007

