Hi David,

It is probably better to continue this discussion in the
[email protected] list. I'll reply there :)

Best regards,
Jerome Louvel
--
Restlet ~ Founder and Lead developer ~ http://www.restlet.org
Noelios Technologies ~ Co-founder ~ http://www.noelios.com


-----Message d'origine-----
De : David Fogel [mailto:[email protected]] 
Envoyé : mercredi 18 mars 2009 08:01
À : [email protected]
Objet : RE: OSGi vs. Service Provider patterns

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=13460
07

------------------------------------------------------
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=1415814

Reply via email to