Hmmm, yeah, the way SPI Fly currently works is to facilitate ServiceLoader.load(class), so the overload that doesn't specify the classloader. SPI Fly uses bytecode manipulation to set the TCCL just before that call and to set it back just after.
One option would be to extend SPI Fly to also support ServiceLoader.load(class, classloader) in that it would replace the original value of the classloader with another one. It would require enhancing the bytecode manipulation somewhat but it could be a fun project ;) Cheers, David On 9 October 2013 10:48, Bram Gadeyne <[email protected]> wrote: > Hi David, > > Thank You for this reply. > > I can't change the way the load method is called since it's in an external > library. > > Based on your explenation I assume my conclusion is correct. Since the > ClassLoader of the interface (abstract class) is used, it can't access the > implementation in the other bundle. > > With kind regards > > > Bram Gadeyne > Department of Information Technology > Internet Based Communication Networks and Services (IBCN) > Ghent University - iMinds > Gaston Crommenlaan 8 (Bus 201), B-9050 Gent, Belgium > T: +32 (0)9 33 20497 > T Secr: +32 (0)9 33 14900 > F: +32 (0)9 33 14899 > E: [email protected] > W : www.ibcn.intec.UGent.be > > On 10/9/2013 11:28 AM, David Bosschaert wrote: >> >> Hi Bram, >> >> If you use the right classloader with ServiceLoader.load(class, >> classLoader) you shouldn't really need SPI Fly at all. >> The classloader that you pass in to it should be the classloader of >> the bundle that hosts the service implementation (not the service >> API). You can get that classloader by calling: >> bundle.adapt(BundleWiring.class).getClassLoader() >> >> Hope this helps, >> >> David >> >> On 9 October 2013 09:40, Bram Gadeyne <[email protected]> wrote: >>> >>> Hi, >>> >>> Should SPI-fly also work when a bundle uses the ServiceLoader.load(class, >>> class.getClassLoader) function? >>> >>> Specifically I'm trying to convert org.openrdf to an osgi bundle. >>> >>> A bundle org.openrdf.query.parser looks for implementations of >>> org.openrdf.query.parser.QueryParserFactory. I've added the >>> Require-Capability and osgi.serviceloader... and osgi.extender... to the >>> Manifest. This class is actually an extention of the abstract class >>> ServiceRegistry from another package so I also added the >>> Require-Capability >>> to this bundles Manifest. >>> >>> The abstract class is available via this url >>> >>> https://bitbucket.org/openrdf/sesame/src/c2c4cfa901461812e15b697994a439efbadaa9e0/core/util/src/main/java/info/aduna/lang/service/ServiceRegistry.java?at=2.7.x >>> >>> At line 46 in this file You'll find: >>> java.util.ServiceLoader.load(serviceClass, >>> serviceClass.getClassLoader()); >>> >>> The bundle that exports the service is org.openrdf.query.parser.sparql. >>> Here >>> I've added the Require-Capability and Provide Capability clauses. >>> >>> When I run the application and enter "inspect capability service 34" I >>> can >>> see the serviceloader.mediator property. >>> >>> However it seems like the consumer can't find the service. Therefore I >>> thought the ServiceLoader.load(class, class.getClassLoader) is causing a >>> problem since the abstract class and implementing class are in a >>> different >>> bundle. >>> >>> >>> Kind regards >>> >>> -- >>> Bram Gadeyne >>> Department of Information Technology >>> Internet Based Communication Networks and Services (IBCN) >>> Ghent University - iMinds >>> Gaston Crommenlaan 8 (Bus 201), B-9050 Gent, Belgium >>> T: +32 (0)9 33 20497 >>> T Secr: +32 (0)9 33 14900 >>> F: +32 (0)9 33 14899 >>> E: [email protected] >>> W : www.ibcn.intec.UGent.be >>> >
