You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@aries.apache.org by Bram Gadeyne <br...@intec.ugent.be> on 2013/10/09 10:40:55 UTC

ServiceLoader.load(class, class.ClassLoader)

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: bram.gadeyne@intec.UGent.be
W : www.ibcn.intec.UGent.be


Re: ServiceLoader.load(class, class.ClassLoader)

Posted by David Bosschaert <da...@gmail.com>.
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 <br...@intec.ugent.be> 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: bram.gadeyne@intec.UGent.be
> 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 <br...@intec.ugent.be> 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: bram.gadeyne@intec.UGent.be
>>> W : www.ibcn.intec.UGent.be
>>>
>

Re: ServiceLoader.load(class, class.ClassLoader)

Posted by Bram Gadeyne <br...@intec.ugent.be>.
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: bram.gadeyne@intec.UGent.be
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 <br...@intec.ugent.be> 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: bram.gadeyne@intec.UGent.be
>> W : www.ibcn.intec.UGent.be
>>


Re: ServiceLoader.load(class, class.ClassLoader)

Posted by David Bosschaert <da...@gmail.com>.
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 <br...@intec.ugent.be> 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: bram.gadeyne@intec.UGent.be
> W : www.ibcn.intec.UGent.be
>