Jerome Louvel wrote:
Hi Hendy,
The Restlet API bundle introspects the classpath to find a
META-INF/services/org.restlet.util.Engine file containing the class name
of the API implementation (com.noelios.restlet.Engine in our case).
This seems to work fine for us in Eclipse 3.3. Why wouldn't that work in
your environment? Can't we use such introspection mechanism with OSGi?
Otherwise, there is indeed an assumption that there is only one
implementation of the Restlet API per JVM. Maybe with OSGi we could have
several implementations in isolated classloaders but I'm not sure how to do
this.
Best regards,
Jerome
It might be because org.restlet and com.noelios use different
classloaders (they should, because they live in different bundles).
Either way, would you try
https://scm.ops4j.org/repos/ops4j/laboratory/users/efy/restlet/JettyTest/
? (it's a Eclipse PDE project, you can SVN import it from Eclipse.
I would be eager to know if you can remove the workaround and still working.
I'm not familiar Restlet's decision/rationale of API implementation. But
usually in OSGi a straightforward way for APIs is to have:
- 1 bundle for API (containing interfaces, not classes). The exported
package(s) then exported by consumer bundles to denote requirement of
the API. At runtime, without this bundle, the dependent bundle won't
even load, because its dependencies do not resolve.
- 1 bundle for implementation that implements that interfaces. This
bundle also exposes these classes as OSGi services. These services are
named, at least, corresponding to the interface names (not necessarily
class names, but can be. because one class can export more than one OSGi
service).
At runtime, in order to use the implementation, consumer bundles use
OSGi to getServiceReference and getService the implementation (which
may or may not be installed, but should be if the app developer is
sane). You can use filters to point to a specific service implementation
or configuration. You can also get an array of services
(getAllServiceReferences) which makes it possible to have multiple
implementation (services) of one API.
My take?
- org.restlet should stay as it is
- com.noelios should stay as it is
- com.noelios.ext.osgi should expose the com.noelios as OSGi services
OSGi consumers shouldn't use org.restlet as it is (traditional Restlet
way as described in the docs), but instead going the OSGi way of
getService-ing an org.restlet service to get an implementation (of an
engine, component, whatever). If it so happens to have more than one
restlet implementations, it can choose (or let OSGi runtime choose it).
I would foresee that scenario happening with JSR-311, hence my concern.
(and regarding the base class, it'd be non-beneficial to have
interfaces as abstract classes, because this limits the freedom of
implementation. I'm not sure if restlet API [base classes] wants to
change this policy, but for JSR-311 I think it should use interfaces
than base classes)
However, getService()-ing too, (after further Restlet-OSGi development)
shouldn't be a necessity in order to use Restlet. Rather than consumers
discovering Restlet implementation then attach()-ing resources to it,
the approach preferred by Peter Kriens and Edward Yakop is also the one
I prefer: Restlet implementation should discover exposed Restlet
resources automatically and do appropriate actions (like attach/detach).
BTW, that (whiteboard method) should also solve the problem of resource
loading/unloading. Since OSGi bundles are dynamic, Restlet should be
able to attach/detach resources dynamically.
I hope what I said above is relatively accurate, I would hope Edward
and/or Peter have more thoughts on this.
-Message d'origine-
De : Hendy Irawan [mailto:[EMAIL PROTECTED]
Envoyé : mercredi 23 avril 2008 17:44
À : discuss@restlet.tigris.org
Cc : Edward Yakop
Objet : Restlet in OSGi and implementation
Dear Restlet community, Jerome, and Edward,
Regarding Restlet and OSGi, even with the proper manifest I
still need
to do this:
// Manually set the Restlet implementation, otherwise
it won't
be able to
// find it even though com.noelios.* bundles are installed
org.restlet.util.Engine.setInstance(new
com.noelios.restlet.Engine());
I believe this is a ugly workaround (but yeah..it works), and
should not
be needed. (I think it's not needed for non-OSGi app, but I haven't
tried Restlet without OSGi, big sorry)
Otherwise, Restlet will complain Cannot find implementation thingy.
I suspect this is a problem with Restlet's way of
classloading stuff...
Edward gives another consideration that it makes it impossible (?) to
load more than one implementation at once. (you should be
able to load
more than one implementation of the same API, like logging, http
service, etc. including restlet)
--
Hendy Irawan
www.hendyirawan.com
--
Hendy Irawan
www.hendyirawan.com