Kabe, The SPI pattern is the standard mechanism used in all standard Java libraries like JDBC, JNDI, NIO, etc. The Restlet API was designed with the application developer as the main user. It does has the ability to create embedded containers, but it does try to hide as much complexity as possible and to provide pluggable implementations while maintaining applications portability.
In your case, you may have to customize the NRE implementation. This shouldn't be too complex. For example if you want to provide a custom mechanism to load server connectors: - override "public org.restlet.spi.Helper createHelper(Server server)" in the NRE's Factory class - return an instance of com.noelios.restlet.impl.http.HttpServerConverter, or more likely a subclass like com.noelios.restlet.ext.simple.HttpServerHelper - adjust your META-INF/services/org.restlet.spi.Factory file The org.restlet.Server class is a very thin class, it delegates all the hard stuff to an Helper class. So it has the advantages of interfaces without the inconvenient. We had many discussions in this list regarding the usage of classes vs. interfaces, you might want to refer to them. I think that you should replace your steps by: 1) Create Container (it automatically creates a context) 2) Create Server (will actually create a Simple server if that's the available implementation) 3) Set/Add Server to Container 4) Create Restlet 5) Add Restlet as target in the Container (other routers/apps would exist as well) I don't see where you loose flexibility. In addition, you gain portability from on API implementation to another (even your own if necessary). Concerning classloaders, I have a plan in 1.1 to allow the deployment of multiple applications, following the WAR packaging style, that would require each application to live in its own classloader. There would probably be a parent classloader to provide the API classes and implementations and one child loader for each application. This way, each application could have its own version of similar libraries, without any potential conflict. There is a related issue in the issues database if you are interested: http://restlet.tigris.org/issues/show_bug.cgi?id=76 There is also a RFE for OSGi support, see: http://restlet.tigris.org/issues/show_bug.cgi?id=83 Best regards, Jerome > -----Message d'origine----- > De : [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] De la part de Kabe > Envoyé : dimanche 29 octobre 2006 05:23 > À : [email protected] > Objet : Re: SPI Factory + OSGi > > Well the issues don't stop there. It is becoming increasingly > frustrating that support for directly created and wiring was > removed. The SPI model is a poor model for more modern IoC > containers and/or models where implementations of the API > classes very and may be provided at different points > throughout the lifecycle of the server. > > Also it is frustrating to see that the "Restlet API" is not > really a thin API as such, where i would expect to see every > single element as an Interface, but rather a set of classes > that use the SPI model to delegate work to a single implementation. > > In short, what i want to be able to do is create instances of > various classes and use Dependency Injection to define my > wiring as, and when, i need it. So for example, i want to > create an instance of a connector backed by the "simple > framework" implementation and use DI to provide it as a > connection for my container. However the Container and all of > the rest of the Restlet API classes use a delegation model > for all of their work that delegates to an SPI Factory that > then requires all implementations of the API classes also use > the SPI model and be available at Factory creation time. This > prevents me from creating connectors at runtime and adding > them to the container. > > 1) Create Context > 2) Create Container, setContext on Container > 3) Create SimpleServer > 4) Set/Add SimpleServer to Container > 5) Create Restlet > 6) Add Restlet as target in the Container (other routers/apps > would exist as well) > > Note that #1, #2, #3, and #5 could (and will) all be done in > different class loaders and at various times in the lifecycle > of the server/process. > > The only thing i can think of doing right now is creating a > new implementation of Factory that does not itself (although > locating it would) use the SPI model. I think this is going > to be a lot of work, and it feels like i'm working around > something that many others will also face when they try to > use the Restlet library in anything other then the monolithic > way it is done now. > > Can you give me some insight into the reasons you chose the > SPI model, and what requirments you have/had that lead to > that choice. Also, are you open to changes that would give > users options to use Dependency Injection rather then SPI Delegation? > > .... > Kabe > > > > On 10/28/06, Kabe <[EMAIL PROTECTED]> wrote: > > I'm using the Restlet library in an OSGi Execution > Environment and i have found the SPI Factory to be currently > unsuitable for this type of work. The reason for this is that > the Factory currently uses the current thread's context > ClassLoader. When using the Restlet library as a library > bundle that exports the public interfaces for other classes > to use, this becomes a problem because when they try to > create an instance of any of the classes in the API, the > Factory will try and locate the API Implementation on the > class loader of the thread doing the calling, which will > resolve to the bundle that is using the API and not the one > that is providing it. > > Now i don't have a perfect solution where the API and > Implementation are separate, but if you bundle both of them > together into a Restlet bundle (which i'm doing) then the > Factory should resolve against its own classloader and not > that of the calling thread. This works for me, and i think > the change is general enough that it provides more robustness > and isn't specifically a fix for any single usecase. All i > have done is optional try and locate the Provider Resources > via the Factory class's ClassLoader if it could not be found > in the thread context ClassLoader. In the case of an OSGi > bundle where the API and NRE implementation are in a single > bundle, this works very well. > > Do you have any thoughts on this subject? Currently the > whole SPI model is not very OSGi friendly, so providing the > API and the Implementation (such as NRE) in seperate bundles > is not something i can see doing very easily. If you think my > workaround is suitable, can you add it (or a modified version > that meets your taste) in. > > --- > plugins/internal/org.restlet/src/org/restlet/spi/Factory.java > (revision 1057) > +++ > plugins/internal/org.restlet/src/org/restlet/spi/Factory.java > (working copy) > @@ -66,6 +66,9 @@ > /** The registered factory. */ > private static Factory instance = null; > > + /** Provider resource. */ > + private static String providerResource = > "META-INF/services/org.restlet.spi.Factory"; > + > /** > * Returns the factory of the Restlet implementation. > * @return The factory of the Restlet implementation. > @@ -81,7 +84,12 @@ > > // Find the factory class name > ClassLoader cl = Thread.currentThread > ().getContextClassLoader(); > - URL configURL = > cl.getResource("META-INF/services/org.restlet.spi.Factory"); > + URL configURL = cl.getResource(providerResource); > + if(configURL == null) > + { > + cl = Factory.class.getClassLoader(); > + configURL = cl.getResource(providerResource); > + } > if(configURL != null) > { > try > > > > >

