RE: Restlet in OSGi and implementation
Hi Hendy, Thanks for the detailed thoughts about the integration solutions. Now that normal Restlet usage is working with OSGi (see other reply to Edward), I can focus on facilitating the deployment of Restlet Applications/Resources on an OSGi runtime. BTW, I have just read the paper on the Whiteboard pattern and it makes a lot of sense. Definitely the way to go... Best regards, Jerome _ De : Hendy Irawan [mailto:[EMAIL PROTECTED] Envoyé : jeudi 24 avril 2008 10:53 À : discuss@restlet.tigris.org Cc : 'Edward Yakop'; Peter Kriens; [EMAIL PROTECTED] Objet : Re: Restlet in OSGi and implementation 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
RE: Restlet in OSGi and implementation
Hi Edward, I've confirmed that this doesn't work in equinox. It hink the reason why it doesn't work because of the recent changes from Require-Bundle - Import-Package. One way to get around this issue is for [com.noelios.restlet] Bundle to have an activator and when the bundle start, org.restlet.util.Engine.setInstance( new com.noelios.restlet.Engine() ); The com.noelios.restlet bundle/JAR now has an OSGi activator (com.noelios.restlet.Activator class), that registers the engine with the Restlet API bundle. Let me know if it works. As it is a separate class, it doesn't introduce a dependency on additional JAR for people not using OSGi at all. I think it is a good compromise. Probably we could follow the same approach for all the pluggable connectors and pluggable authentication helpers. What do you think? And in regards to progress, * I have sample servlet tested inside lifecycleTest integration test. This code runs properly in equinox. Jerome if u have time please review it and tell me what should be the next feature to integrate. Thanks! I have retrieved your project and will have a closer look at it soon. First, I want to define the design of our OSGi services via the Wiki page. * I also tries to run the integration test inside felix container. I get this error. [...] As suggested, I have added import statements for javax.security.auth.login. Best regards, Jerome
RE: Restlet in OSGi and implementation
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 -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
Re: Restlet in OSGi and implementation
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
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