Hi Kobe, Thanks for the detailed email. Note that the generated JARs are also Eclipse plugins which should/could be compatible with other OSGi environments. What OSGi environment are you actually using?
I understand the problems related to using the current thread's classloader for any dynamic class loading. I have just changed the way the SPI selects the classloader for dynamic loadings: - org.restlet.spi.Factory now has static get/setClassLoader() methods - by default the classloader property is set to the classloader used to load the Factory's class, instead of the current thread - all dynamic class loadings (Factory implementation and connectors) are done using this classloader set on org.restlet.spi.Factory. - if the loading fails, the current thread's classloader is used, then the system's classloader. Checked in SVN. New snapshot at: http://www.restlet.org/downloads/current.zip Best regards, Jerome > -----Message d'origine----- > De : [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] De la part de Kabe > Envoyé : samedi 28 octobre 2006 21:04 > À : [email protected] > Objet : SPI Factory + OSGi > > 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 > > > >

