Re: [osgi-dev] Allow registering a (Prototype)ServiceFactory via DS?

2017-04-21 Thread Timothy Ward
I will state again that this seems like a large expansion of DS for quite a 
small use case. It’s limited to existing types which the user can’t change and 
doesn’t want to use the decorator/delegation pattern for, and that also don’t 
have a public constructor (i.e. must use a factory to create them). If there is 
a public constructor then a suitable XML file can be written once and used 
indefinitely. 

Tim


> On 21 Apr 2017, at 09:06, Neil Bartlett <njbartl...@gmail.com> wrote:
> 
> And which bundle would be passed as the requesting bundle parameter of 
> getService? SCR itself?
> 
> 
> 
> On 21 Apr 2017 08:24, "Peter Kriens" <peter.kri...@aqute.biz 
> <mailto:peter.kri...@aqute.biz>> wrote:
> Well, the ServiceFactory is just a way to indirect the creation of the 
> actual instance. I do not see why such a pattern theoretically could not be 
> used for DS as well?
> 
> All the rules could stay the same, however, DS would ask the component 
> instance for the service instance to register instead of assuming this is 
> always the component instance. The difference would be that getService() 
> would only be called once for any given instance since cardinality would be 
> handled by DS.
> 
> Kind regards,
> 
>   Peter Kriens
> 
> 
> 
> 
> 
> 
>> On 20 Apr 2017, at 19:26, BJ Hargrave <hargr...@us.ibm.com 
>> <mailto:hargr...@us.ibm.com>> wrote:
>> 
>> When DS registers your component as a service, it already registers its own 
>> object implementing ServiceFactory. This is necessary to register the 
>> service while still allowing delayed activation of your component. So DS's 
>> ServiceFactory object is called by the framework when someone gets the 
>> service and then DS will instantiate and activate your service component. 
>> How many times this is done is controlled by scope of the component: 
>> singleton, bundle, prototype.
>>  
>> The basic point is that DS must be in charge of constructing and activating 
>> component instances and so your component implemention ServiceFactory does 
>> not work with that. With plans to support constructor injection in DS 1.4, 
>> this is even more important to the DS component model.
>> --
>> 
>> BJ Hargrave
>> Senior Technical Staff Member, IBM // office: +1 386 848 1781 
>> <tel:(386)%20848-1781>
>> OSGi Fellow and CTO of the OSGi Alliance // mobile: +1 386 848 3788 
>> <tel:(386)%20848-3788>
>> hargr...@us.ibm.com <mailto:hargr...@us.ibm.com>
>>  
>>  
>> - Original message -
>> From: Julian Sedding <jsedd...@gmail.com <mailto:jsedd...@gmail.com>>
>> Sent by: osgi-dev-boun...@mail.osgi.org 
>> <mailto:osgi-dev-boun...@mail.osgi.org>
>> To: OSGi Developer Mail List <osgi-dev@mail.osgi.org 
>> <mailto:osgi-dev@mail.osgi.org>>
>> Cc:
>> Subject: Re: [osgi-dev] Allow registering a (Prototype)ServiceFactory via DS?
>> Date: Thu, Apr 20, 2017 9:39 AM
>>  
>> Hi Tim
>> 
>> That's an interesting approach! I hadn't considered using DS but
>> handling the service registration myself.
>> 
>> To me it would have felt consistent if registering a ServiceFactory as
>> a service using DS had just worked. Next to controlling the scope
>> (singleton, bundle, prototype) of a service,  a ServiceFactory seems
>> suitable to creating service objects by means other than their default
>> constructor. Thus, supporting ServiceFactories in DS would make it
>> very easy to provide OSGi-glue for arbitrary Java classes that are
>> themselves unaware of OSGi.
>> 
>> Of course there is a trade-off between the usefulness of a feature and
>> bloating the spec. And I'll leave this decision with you guys.
>> 
>> Regards
>> Julian
>> 
>> 
>> On Thu, Apr 20, 2017 at 12:35 PM, Timothy Ward <tim.w...@paremus.com 
>> <mailto:tim.w...@paremus.com>> wrote:
>> > DS isn’t intended to solve every single use case, rather to make common 
>> > use cases simple to write and understand. In this case what you want is 
>> > more advanced, and unlikely to make it into DS as a natively supported 
>> > pattern. Given that you’re already tied to the core OSGi API 
>> > (ServiceFactory) then registering the service programatically would still 
>> > let DS help you with config and service injection.
>> >
>> >
>> > @Component(
>> >// Do not let DS provide the service
>> >service = {},
>> >configurationPolicy = ConfigurationPolicy.REQUIRE
>> > )
&

Re: [osgi-dev] Allow registering a (Prototype)ServiceFactory via DS?

2017-04-21 Thread Neil Bartlett
And which bundle would be passed as the requesting bundle parameter of
getService? SCR itself?



On 21 Apr 2017 08:24, "Peter Kriens" <peter.kri...@aqute.biz> wrote:

> Well, the ServiceFactory is just a way to indirect the creation of the
> actual instance. I do not see why such a pattern theoretically could not be
> used for DS as well?
>
> All the rules could stay the same, however, DS would ask the component
> instance for the service instance to register instead of assuming this is
> always the component instance. The difference would be that getService()
> would only be called once for any given instance since cardinality would be
> handled by DS.
>
> Kind regards,
>
> Peter Kriens
>
>
>
>
>
>
> On 20 Apr 2017, at 19:26, BJ Hargrave <hargr...@us.ibm.com> wrote:
>
> When DS registers your component as a service, it already registers its
> own object implementing ServiceFactory. This is necessary to register the
> service while still allowing delayed activation of your component. So DS's
> ServiceFactory object is called by the framework when someone gets the
> service and then DS will instantiate and activate your service component.
> How many times this is done is controlled by scope of the component:
> singleton, bundle, prototype.
>
> The basic point is that DS must be in charge of constructing and
> activating component instances and so your component implemention
> ServiceFactory does not work with that. With plans to support constructor
> injection in DS 1.4, this is even more important to the DS component model.
> --
>
> BJ Hargrave
> Senior Technical Staff Member, IBM // office: +1 386 848 1781
> <(386)%20848-1781>
> OSGi Fellow and CTO of the OSGi Alliance // mobile: +1 386 848 3788
> <(386)%20848-3788>
> hargr...@us.ibm.com
>
>
>
> - Original message -
> From: Julian Sedding <jsedd...@gmail.com>
> Sent by: osgi-dev-boun...@mail.osgi.org
> To: OSGi Developer Mail List <osgi-dev@mail.osgi.org>
> Cc:
> Subject: Re: [osgi-dev] Allow registering a (Prototype)ServiceFactory via
> DS?
> Date: Thu, Apr 20, 2017 9:39 AM
>
> Hi Tim
>
> That's an interesting approach! I hadn't considered using DS but
> handling the service registration myself.
>
> To me it would have felt consistent if registering a ServiceFactory as
> a service using DS had just worked. Next to controlling the scope
> (singleton, bundle, prototype) of a service,  a ServiceFactory seems
> suitable to creating service objects by means other than their default
> constructor. Thus, supporting ServiceFactories in DS would make it
> very easy to provide OSGi-glue for arbitrary Java classes that are
> themselves unaware of OSGi.
>
> Of course there is a trade-off between the usefulness of a feature and
> bloating the spec. And I'll leave this decision with you guys.
>
> Regards
> Julian
>
>
> On Thu, Apr 20, 2017 at 12:35 PM, Timothy Ward <tim.w...@paremus.com>
> wrote:
> > DS isn’t intended to solve every single use case, rather to make common
> use cases simple to write and understand. In this case what you want is
> more advanced, and unlikely to make it into DS as a natively supported
> pattern. Given that you’re already tied to the core OSGi API
> (ServiceFactory) then registering the service programatically would still
> let DS help you with config and service injection.
> >
> >
> > @Component(
> >// Do not let DS provide the service
> >service = {},
> >configurationPolicy = ConfigurationPolicy.REQUIRE
> > )
> > public class FooServiceFactory implements ServiceFactory {
> >
> >@Reference // provides FooBuilder instances that are pre-configured
> via OSGi
> >private FooBuilderFactory fooBuilderFactory;
> >
> >private ServiceRegistration reg;
> >
> >   @Activate
> >   void start(BundleContext ctx, Map<String, Object> props, Config
> config) {
> >   reg = ctx.registerService(Foo.class.getName(), this, props);
> >   }
> >
> >   @Deactivate
> >   void stop() {
> >   reg.unregister();
> >   }
> >
> >@Override
> >public Foo getService() {
> >FooBuilder fooBuilder = fooBuilderFactory.builder();
> >applyConfiguration(fooBuilder);
> >return fooBuilder.build();
> >}
> >
> >private void applyConfiguration(FooBuilder fooBuilder) {
> >// apply OSGi configuration to FooBuilder object
> >}
> >
> >... // ungetService omitted for brevity
> >
> > }
> >
> >
> > Regards,
> >
> > Tim
> >
&

Re: [osgi-dev] Allow registering a (Prototype)ServiceFactory via DS?

2017-04-21 Thread Peter Kriens
Well, the ServiceFactory is just a way to indirect the creation of the 
actual instance. I do not see why such a pattern theoretically could not be 
used for DS as well?

All the rules could stay the same, however, DS would ask the component instance 
for the service instance to register instead of assuming this is always the 
component instance. The difference would be that getService() would only be 
called once for any given instance since cardinality would be handled by DS.

Kind regards,

Peter Kriens






> On 20 Apr 2017, at 19:26, BJ Hargrave <hargr...@us.ibm.com> wrote:
> 
> When DS registers your component as a service, it already registers its own 
> object implementing ServiceFactory. This is necessary to register the service 
> while still allowing delayed activation of your component. So DS's 
> ServiceFactory object is called by the framework when someone gets the 
> service and then DS will instantiate and activate your service component. How 
> many times this is done is controlled by scope of the component: singleton, 
> bundle, prototype.
>  
> The basic point is that DS must be in charge of constructing and activating 
> component instances and so your component implemention ServiceFactory does 
> not work with that. With plans to support constructor injection in DS 1.4, 
> this is even more important to the DS component model.
> --
> 
> BJ Hargrave
> Senior Technical Staff Member, IBM // office: +1 386 848 1781
> OSGi Fellow and CTO of the OSGi Alliance // mobile: +1 386 848 3788
> hargr...@us.ibm.com
>  
>  
> - Original message -
> From: Julian Sedding <jsedd...@gmail.com>
> Sent by: osgi-dev-boun...@mail.osgi.org
> To: OSGi Developer Mail List <osgi-dev@mail.osgi.org>
> Cc:
> Subject: Re: [osgi-dev] Allow registering a (Prototype)ServiceFactory via DS?
> Date: Thu, Apr 20, 2017 9:39 AM
>  
> Hi Tim
> 
> That's an interesting approach! I hadn't considered using DS but
> handling the service registration myself.
> 
> To me it would have felt consistent if registering a ServiceFactory as
> a service using DS had just worked. Next to controlling the scope
> (singleton, bundle, prototype) of a service,  a ServiceFactory seems
> suitable to creating service objects by means other than their default
> constructor. Thus, supporting ServiceFactories in DS would make it
> very easy to provide OSGi-glue for arbitrary Java classes that are
> themselves unaware of OSGi.
> 
> Of course there is a trade-off between the usefulness of a feature and
> bloating the spec. And I'll leave this decision with you guys.
> 
> Regards
> Julian
> 
> 
> On Thu, Apr 20, 2017 at 12:35 PM, Timothy Ward <tim.w...@paremus.com> wrote:
> > DS isn’t intended to solve every single use case, rather to make common use 
> > cases simple to write and understand. In this case what you want is more 
> > advanced, and unlikely to make it into DS as a natively supported pattern. 
> > Given that you’re already tied to the core OSGi API (ServiceFactory) then 
> > registering the service programatically would still let DS help you with 
> > config and service injection.
> >
> >
> > @Component(
> >// Do not let DS provide the service
> >service = {},
> >configurationPolicy = ConfigurationPolicy.REQUIRE
> > )
> > public class FooServiceFactory implements ServiceFactory {
> >
> >@Reference // provides FooBuilder instances that are pre-configured via 
> > OSGi
> >private FooBuilderFactory fooBuilderFactory;
> >
> >private ServiceRegistration reg;
> >
> >   @Activate
> >   void start(BundleContext ctx, Map<String, Object> props, Config config) {
> >   reg = ctx.registerService(Foo.class.getName(), this, props);
> >   }
> >
> >   @Deactivate
> >   void stop() {
> >   reg.unregister();
> >   }
> >
> >@Override
> >public Foo getService() {
> >FooBuilder fooBuilder = fooBuilderFactory.builder();
> >applyConfiguration(fooBuilder);
> >return fooBuilder.build();
> >}
> >
> >private void applyConfiguration(FooBuilder fooBuilder) {
> >// apply OSGi configuration to FooBuilder object
> >}
> >
> >... // ungetService omitted for brevity
> >
> > }
> >
> >
> > Regards,
> >
> > Tim
> >
> >
> >> On 20 Apr 2017, at 11:11, Julian Sedding <jsedd...@gmail.com> wrote:
> >>
> >> Hi Timothy
> >>
> >> Thanks for your reply. Using delegation works, I currently use it to
> >> solve my use-case.
> >&g

Re: [osgi-dev] Allow registering a (Prototype)ServiceFactory via DS?

2017-04-20 Thread BJ Hargrave
When DS registers your component as a service, it already registers its own object implementing ServiceFactory. This is necessary to register the service while still allowing delayed activation of your component. So DS's ServiceFactory object is called by the framework when someone gets the service and then DS will instantiate and activate your service component. How many times this is done is controlled by scope of the component: singleton, bundle, prototype.
 
The basic point is that DS must be in charge of constructing and activating component instances and so your component implemention ServiceFactory does not work with that. With plans to support constructor injection in DS 1.4, this is even more important to the DS component model.
--BJ HargraveSenior Technical Staff Member, IBM // office: +1 386 848 1781OSGi Fellow and CTO of the OSGi Alliance // mobile: +1 386 848 3788hargr...@us.ibm.com
 
 
- Original message -From: Julian Sedding <jsedd...@gmail.com>Sent by: osgi-dev-boun...@mail.osgi.orgTo: OSGi Developer Mail List <osgi-dev@mail.osgi.org>Cc:Subject: Re: [osgi-dev] Allow registering a (Prototype)ServiceFactory via DS?Date: Thu, Apr 20, 2017 9:39 AM 
Hi TimThat's an interesting approach! I hadn't considered using DS buthandling the service registration myself.To me it would have felt consistent if registering a ServiceFactory asa service using DS had just worked. Next to controlling the scope(singleton, bundle, prototype) of a service,  a ServiceFactory seemssuitable to creating service objects by means other than their defaultconstructor. Thus, supporting ServiceFactories in DS would make itvery easy to provide OSGi-glue for arbitrary Java classes that arethemselves unaware of OSGi.Of course there is a trade-off between the usefulness of a feature andbloating the spec. And I'll leave this decision with you guys.RegardsJulianOn Thu, Apr 20, 2017 at 12:35 PM, Timothy Ward <tim.w...@paremus.com> wrote:> DS isn’t intended to solve every single use case, rather to make common use cases simple to write and understand. In this case what you want is more advanced, and unlikely to make it into DS as a natively supported pattern. Given that you’re already tied to the core OSGi API (ServiceFactory) then registering the service programatically would still let DS help you with config and service injection.>>> @Component(>    // Do not let DS provide the service>    service = {},>    configurationPolicy = ConfigurationPolicy.REQUIRE> )> public class FooServiceFactory implements ServiceFactory {>>    @Reference // provides FooBuilder instances that are pre-configured via OSGi>    private FooBuilderFactory fooBuilderFactory;>>    private ServiceRegistration reg;>>   @Activate>   void start(BundleContext ctx, Map<String, Object> props, Config config) {>       reg = ctx.registerService(Foo.class.getName(), this, props);>   }>>   @Deactivate>   void stop() {>       reg.unregister();>   }>>    @Override>    public Foo getService() {>        FooBuilder fooBuilder = fooBuilderFactory.builder();>        applyConfiguration(fooBuilder);>        return fooBuilder.build();>    }>>    private void applyConfiguration(FooBuilder fooBuilder) {>        // apply OSGi configuration to FooBuilder object>    }>>    ... // ungetService omitted for brevity>> }>>> Regards,>> Tim>>>> On 20 Apr 2017, at 11:11, Julian Sedding <jsedd...@gmail.com> wrote:>>>> Hi Timothy>>>> Thanks for your reply. Using delegation works, I currently use it to>> solve my use-case.>>>> However, compared to implementing a ServiceFactory, delegation adds>> some overhead:>>>> - delegation needs to be implemented, which is trivial, but noisy if>> there are lots of methods that need delegating>> - by delegating, my implementation becomes a "provider" of Foo, rather>> than a "consumer", making my bundle more susceptible to changes in>> Foo's API>> - also: delegation is not possible if Foo is a final class>>>> I brought up this topic in order to (a) confirm that my desired>> approach is indeed not possible at the moment and (b) to see if adding>> support for registering custom ServiceFactory implementations via DS>> could be a desirable enhancement for the spec.>>>> Regards>> Julian>>>>>> On Thu, Apr 20, 2017 at 11:22 AM, Timothy Ward <tim.w...@paremus.com> wrote:>>> Have you not considered the following:>>>>>>>>> @Component(configurationPolicy = ConfigurationPolicy.REQUIRE,>>>    scope = ServiceScope.BUNDLE)>>> public class FooImpl implements Foo {>>>>>>   public @interface Config {>>>      // Config definition in here>&g

Re: [osgi-dev] Allow registering a (Prototype)ServiceFactory via DS?

2017-04-20 Thread Julian Sedding
Hi Tim

That's an interesting approach! I hadn't considered using DS but
handling the service registration myself.

To me it would have felt consistent if registering a ServiceFactory as
a service using DS had just worked. Next to controlling the scope
(singleton, bundle, prototype) of a service,  a ServiceFactory seems
suitable to creating service objects by means other than their default
constructor. Thus, supporting ServiceFactories in DS would make it
very easy to provide OSGi-glue for arbitrary Java classes that are
themselves unaware of OSGi.

Of course there is a trade-off between the usefulness of a feature and
bloating the spec. And I'll leave this decision with you guys.

Regards
Julian


On Thu, Apr 20, 2017 at 12:35 PM, Timothy Ward  wrote:
> DS isn’t intended to solve every single use case, rather to make common use 
> cases simple to write and understand. In this case what you want is more 
> advanced, and unlikely to make it into DS as a natively supported pattern. 
> Given that you’re already tied to the core OSGi API (ServiceFactory) then 
> registering the service programatically would still let DS help you with 
> config and service injection.
>
>
> @Component(
>// Do not let DS provide the service
>service = {},
>configurationPolicy = ConfigurationPolicy.REQUIRE
> )
> public class FooServiceFactory implements ServiceFactory {
>
>@Reference // provides FooBuilder instances that are pre-configured via 
> OSGi
>private FooBuilderFactory fooBuilderFactory;
>
>private ServiceRegistration reg;
>
>   @Activate
>   void start(BundleContext ctx, Map props, Config config) {
>   reg = ctx.registerService(Foo.class.getName(), this, props);
>   }
>
>   @Deactivate
>   void stop() {
>   reg.unregister();
>   }
>
>@Override
>public Foo getService() {
>FooBuilder fooBuilder = fooBuilderFactory.builder();
>applyConfiguration(fooBuilder);
>return fooBuilder.build();
>}
>
>private void applyConfiguration(FooBuilder fooBuilder) {
>// apply OSGi configuration to FooBuilder object
>}
>
>... // ungetService omitted for brevity
>
> }
>
>
> Regards,
>
> Tim
>
>
>> On 20 Apr 2017, at 11:11, Julian Sedding  wrote:
>>
>> Hi Timothy
>>
>> Thanks for your reply. Using delegation works, I currently use it to
>> solve my use-case.
>>
>> However, compared to implementing a ServiceFactory, delegation adds
>> some overhead:
>>
>> - delegation needs to be implemented, which is trivial, but noisy if
>> there are lots of methods that need delegating
>> - by delegating, my implementation becomes a "provider" of Foo, rather
>> than a "consumer", making my bundle more susceptible to changes in
>> Foo's API
>> - also: delegation is not possible if Foo is a final class
>>
>> I brought up this topic in order to (a) confirm that my desired
>> approach is indeed not possible at the moment and (b) to see if adding
>> support for registering custom ServiceFactory implementations via DS
>> could be a desirable enhancement for the spec.
>>
>> Regards
>> Julian
>>
>>
>> On Thu, Apr 20, 2017 at 11:22 AM, Timothy Ward  wrote:
>>> Have you not considered the following:
>>>
>>>
>>> @Component(configurationPolicy = ConfigurationPolicy.REQUIRE,
>>>scope = ServiceScope.BUNDLE)
>>> public class FooImpl implements Foo {
>>>
>>>   public @interface Config {
>>>  // Config definition in here
>>>   }
>>>
>>>   @Reference
>>>   private FooBuilderFactory fooBuilderFactory;
>>>
>>>   private Foo delegate;
>>>
>>>   @Activate
>>>   void start(Config config) {
>>>   FooBuilder fooBuilder = fooBuilderFactory.builder();
>>>   applyConfiguration(fooBuilder, config);
>>>   delegate = fooBuilder.build();
>>>   }
>>>
>>>   // Deactivation and Foo delegation methods go here
>>>   …
>>> }
>>>
>>> Regards,
>>>
>>> Tim
>>>
 On 20 Apr 2017, at 09:30, Julian Sedding  wrote:

 Hi there

 I have been trying to implement a use-case, but I seem to be running
 into walls ;) (Disclaimer: I can see multiple ways to implement this,
 but would like to re-use the dependency injection and lazy
 instantiation of DS).

 My aim is to create configured service objects in the way that is
 normally achieved by using a DS factory component with
 configuration-policy require.

 The catch is that the implementation of the objects I want to
 configure and register as a service is not under my control and is
 instanciated via a builder obtained from a factory that is registered
 as an OSGi-service. Sounds a bit complicated, maybe it's clearer in
 code.

 @Component(
   service = Foo.class,
   configurationPolicy = ConfigurationPolicy.REQUIRE
 )
 public class FooServiceFactory implements ServiceFactory {

   @Reference // provides FooBuilder instances that are pre-configured via 

Re: [osgi-dev] Allow registering a (Prototype)ServiceFactory via DS?

2017-04-20 Thread Peter Kriens
Yes, that would solve this issue.

Kind regards,

Peter Kriens


> On 20 Apr 2017, at 14:02, Tim Ward  wrote:
> 
> Peter - I assume that you mean that there will be no auto-generated 
> osgi.service capability. Couldn't that be fixed with an additional annotation 
> on the component type to add the Provide-Capability to the manifest?
> 
> Tim Ward
> 
> Sent from my iPhone
> 
>> On 20 Apr 2017, at 12:38, Peter Kriens  wrote:
>> 
>> But then you loose the DS dependency management on Foo … Since your 
>> FooServiceFactory no longer promises to provide a Foo service :-(
>> 
>> Kind regards,
>> 
>>   Peter Kriens
>> 
>> 
>>> On 20 Apr 2017, at 12:35, Timothy Ward  wrote:
>>> 
>>> DS isn’t intended to solve every single use case, rather to make common use 
>>> cases simple to write and understand. In this case what you want is more 
>>> advanced, and unlikely to make it into DS as a natively supported pattern. 
>>> Given that you’re already tied to the core OSGi API (ServiceFactory) then 
>>> registering the service programatically would still let DS help you with 
>>> config and service injection.
>>> 
>>> 
>>> @Component(
>>> // Do not let DS provide the service
>>> service = {},
>>> configurationPolicy = ConfigurationPolicy.REQUIRE
>>> )
>>> public class FooServiceFactory implements ServiceFactory {
>>> 
>>> @Reference // provides FooBuilder instances that are pre-configured via OSGi
>>> private FooBuilderFactory fooBuilderFactory;
>>> 
>>> private ServiceRegistration reg;
>>> 
>>> @Activate
>>> void start(BundleContext ctx, Map props, Config config) {
>>>reg = ctx.registerService(Foo.class.getName(), this, props);
>>> }
>>> 
>>> @Deactivate
>>> void stop() {
>>>reg.unregister();
>>> }
>>> 
>>> @Override
>>> public Foo getService() {
>>> FooBuilder fooBuilder = fooBuilderFactory.builder();
>>> applyConfiguration(fooBuilder);
>>> return fooBuilder.build();
>>> }
>>> 
>>> private void applyConfiguration(FooBuilder fooBuilder) {
>>> // apply OSGi configuration to FooBuilder object
>>> }
>>> 
>>> ... // ungetService omitted for brevity
>>> 
>>> }
>>> 
>>> 
>>> Regards,
>>> 
>>> Tim
>>> 
>>> 
 On 20 Apr 2017, at 11:11, Julian Sedding  wrote:
 
 Hi Timothy
 
 Thanks for your reply. Using delegation works, I currently use it to
 solve my use-case.
 
 However, compared to implementing a ServiceFactory, delegation adds
 some overhead:
 
 - delegation needs to be implemented, which is trivial, but noisy if
 there are lots of methods that need delegating
 - by delegating, my implementation becomes a "provider" of Foo, rather
 than a "consumer", making my bundle more susceptible to changes in
 Foo's API
 - also: delegation is not possible if Foo is a final class
 
 I brought up this topic in order to (a) confirm that my desired
 approach is indeed not possible at the moment and (b) to see if adding
 support for registering custom ServiceFactory implementations via DS
 could be a desirable enhancement for the spec.
 
 Regards
 Julian
 
 
> On Thu, Apr 20, 2017 at 11:22 AM, Timothy Ward  
> wrote:
> Have you not considered the following:
> 
> 
> @Component(configurationPolicy = ConfigurationPolicy.REQUIRE,
> scope = ServiceScope.BUNDLE)
> public class FooImpl implements Foo {
> 
> public @interface Config {
>   // Config definition in here
> }
> 
> @Reference
> private FooBuilderFactory fooBuilderFactory;
> 
> private Foo delegate;
> 
> @Activate
> void start(Config config) {
>FooBuilder fooBuilder = fooBuilderFactory.builder();
>applyConfiguration(fooBuilder, config);
>delegate = fooBuilder.build();
> }
> 
> // Deactivation and Foo delegation methods go here
> …
> }
> 
> Regards,
> 
> Tim
> 
>> On 20 Apr 2017, at 09:30, Julian Sedding  wrote:
>> 
>> Hi there
>> 
>> I have been trying to implement a use-case, but I seem to be running
>> into walls ;) (Disclaimer: I can see multiple ways to implement this,
>> but would like to re-use the dependency injection and lazy
>> instantiation of DS).
>> 
>> My aim is to create configured service objects in the way that is
>> normally achieved by using a DS factory component with
>> configuration-policy require.
>> 
>> The catch is that the implementation of the objects I want to
>> configure and register as a service is not under my control and is
>> instanciated via a builder obtained from a factory that is registered
>> as an OSGi-service. Sounds a bit complicated, maybe it's clearer in
>> code.
>> 
>> @Component(
>> service = Foo.class,
>> configurationPolicy = 

Re: [osgi-dev] Allow registering a (Prototype)ServiceFactory via DS?

2017-04-20 Thread Tim Ward
Peter - I assume that you mean that there will be no auto-generated 
osgi.service capability. Couldn't that be fixed with an additional annotation 
on the component type to add the Provide-Capability to the manifest?

Tim Ward

Sent from my iPhone

> On 20 Apr 2017, at 12:38, Peter Kriens  wrote:
> 
> But then you loose the DS dependency management on Foo … Since your 
> FooServiceFactory no longer promises to provide a Foo service :-(
> 
> Kind regards,
> 
>Peter Kriens
> 
> 
>> On 20 Apr 2017, at 12:35, Timothy Ward  wrote:
>> 
>> DS isn’t intended to solve every single use case, rather to make common use 
>> cases simple to write and understand. In this case what you want is more 
>> advanced, and unlikely to make it into DS as a natively supported pattern. 
>> Given that you’re already tied to the core OSGi API (ServiceFactory) then 
>> registering the service programatically would still let DS help you with 
>> config and service injection.
>> 
>> 
>> @Component(
>>  // Do not let DS provide the service
>>  service = {},
>>  configurationPolicy = ConfigurationPolicy.REQUIRE
>> )
>> public class FooServiceFactory implements ServiceFactory {
>> 
>>  @Reference // provides FooBuilder instances that are pre-configured via OSGi
>>  private FooBuilderFactory fooBuilderFactory;
>> 
>>  private ServiceRegistration reg;
>> 
>> @Activate
>> void start(BundleContext ctx, Map props, Config config) {
>> reg = ctx.registerService(Foo.class.getName(), this, props);
>> }
>> 
>> @Deactivate
>> void stop() {
>> reg.unregister();
>> }
>> 
>>  @Override
>>  public Foo getService() {
>>  FooBuilder fooBuilder = fooBuilderFactory.builder();
>>  applyConfiguration(fooBuilder);
>>  return fooBuilder.build();
>>  }
>> 
>>  private void applyConfiguration(FooBuilder fooBuilder) {
>>  // apply OSGi configuration to FooBuilder object
>>  }
>> 
>>  ... // ungetService omitted for brevity
>> 
>> }
>> 
>> 
>> Regards,
>> 
>> Tim
>> 
>> 
>>> On 20 Apr 2017, at 11:11, Julian Sedding  wrote:
>>> 
>>> Hi Timothy
>>> 
>>> Thanks for your reply. Using delegation works, I currently use it to
>>> solve my use-case.
>>> 
>>> However, compared to implementing a ServiceFactory, delegation adds
>>> some overhead:
>>> 
>>> - delegation needs to be implemented, which is trivial, but noisy if
>>> there are lots of methods that need delegating
>>> - by delegating, my implementation becomes a "provider" of Foo, rather
>>> than a "consumer", making my bundle more susceptible to changes in
>>> Foo's API
>>> - also: delegation is not possible if Foo is a final class
>>> 
>>> I brought up this topic in order to (a) confirm that my desired
>>> approach is indeed not possible at the moment and (b) to see if adding
>>> support for registering custom ServiceFactory implementations via DS
>>> could be a desirable enhancement for the spec.
>>> 
>>> Regards
>>> Julian
>>> 
>>> 
 On Thu, Apr 20, 2017 at 11:22 AM, Timothy Ward  
 wrote:
 Have you not considered the following:
 
 
 @Component(configurationPolicy = ConfigurationPolicy.REQUIRE,
  scope = ServiceScope.BUNDLE)
 public class FooImpl implements Foo {
 
 public @interface Config {
// Config definition in here
 }
 
 @Reference
 private FooBuilderFactory fooBuilderFactory;
 
 private Foo delegate;
 
 @Activate
 void start(Config config) {
 FooBuilder fooBuilder = fooBuilderFactory.builder();
 applyConfiguration(fooBuilder, config);
 delegate = fooBuilder.build();
 }
 
 // Deactivation and Foo delegation methods go here
 …
 }
 
 Regards,
 
 Tim
 
> On 20 Apr 2017, at 09:30, Julian Sedding  wrote:
> 
> Hi there
> 
> I have been trying to implement a use-case, but I seem to be running
> into walls ;) (Disclaimer: I can see multiple ways to implement this,
> but would like to re-use the dependency injection and lazy
> instantiation of DS).
> 
> My aim is to create configured service objects in the way that is
> normally achieved by using a DS factory component with
> configuration-policy require.
> 
> The catch is that the implementation of the objects I want to
> configure and register as a service is not under my control and is
> instanciated via a builder obtained from a factory that is registered
> as an OSGi-service. Sounds a bit complicated, maybe it's clearer in
> code.
> 
> @Component(
> service = Foo.class,
> configurationPolicy = ConfigurationPolicy.REQUIRE
> )
> public class FooServiceFactory implements ServiceFactory {
> 
> @Reference // provides FooBuilder instances that are pre-configured via 
> OSGi
> private FooBuilderFactory fooBuilderFactory;
> 
> @Override
> public Foo 

Re: [osgi-dev] Allow registering a (Prototype)ServiceFactory via DS?

2017-04-20 Thread Peter Kriens
But then you loose the DS dependency management on Foo … Since your 
FooServiceFactory no longer promises to provide a Foo service :-(

Kind regards,

Peter Kriens


> On 20 Apr 2017, at 12:35, Timothy Ward  wrote:
> 
> DS isn’t intended to solve every single use case, rather to make common use 
> cases simple to write and understand. In this case what you want is more 
> advanced, and unlikely to make it into DS as a natively supported pattern. 
> Given that you’re already tied to the core OSGi API (ServiceFactory) then 
> registering the service programatically would still let DS help you with 
> config and service injection.
> 
> 
> @Component(
>   // Do not let DS provide the service
>   service = {},
>   configurationPolicy = ConfigurationPolicy.REQUIRE
> )
> public class FooServiceFactory implements ServiceFactory {
> 
>   @Reference // provides FooBuilder instances that are pre-configured via OSGi
>   private FooBuilderFactory fooBuilderFactory;
> 
>   private ServiceRegistration reg;
> 
>  @Activate
>  void start(BundleContext ctx, Map props, Config config) {
>  reg = ctx.registerService(Foo.class.getName(), this, props);
>  }
> 
>  @Deactivate
>  void stop() {
>  reg.unregister();
>  }
> 
>   @Override
>   public Foo getService() {
>   FooBuilder fooBuilder = fooBuilderFactory.builder();
>   applyConfiguration(fooBuilder);
>   return fooBuilder.build();
>   }
> 
>   private void applyConfiguration(FooBuilder fooBuilder) {
>   // apply OSGi configuration to FooBuilder object
>   }
> 
>   ... // ungetService omitted for brevity
> 
> }
> 
> 
> Regards,
> 
> Tim
> 
> 
>> On 20 Apr 2017, at 11:11, Julian Sedding  wrote:
>> 
>> Hi Timothy
>> 
>> Thanks for your reply. Using delegation works, I currently use it to
>> solve my use-case.
>> 
>> However, compared to implementing a ServiceFactory, delegation adds
>> some overhead:
>> 
>> - delegation needs to be implemented, which is trivial, but noisy if
>> there are lots of methods that need delegating
>> - by delegating, my implementation becomes a "provider" of Foo, rather
>> than a "consumer", making my bundle more susceptible to changes in
>> Foo's API
>> - also: delegation is not possible if Foo is a final class
>> 
>> I brought up this topic in order to (a) confirm that my desired
>> approach is indeed not possible at the moment and (b) to see if adding
>> support for registering custom ServiceFactory implementations via DS
>> could be a desirable enhancement for the spec.
>> 
>> Regards
>> Julian
>> 
>> 
>> On Thu, Apr 20, 2017 at 11:22 AM, Timothy Ward  wrote:
>>> Have you not considered the following:
>>> 
>>> 
>>> @Component(configurationPolicy = ConfigurationPolicy.REQUIRE,
>>>   scope = ServiceScope.BUNDLE)
>>> public class FooImpl implements Foo {
>>> 
>>>  public @interface Config {
>>> // Config definition in here
>>>  }
>>> 
>>>  @Reference
>>>  private FooBuilderFactory fooBuilderFactory;
>>> 
>>>  private Foo delegate;
>>> 
>>>  @Activate
>>>  void start(Config config) {
>>>  FooBuilder fooBuilder = fooBuilderFactory.builder();
>>>  applyConfiguration(fooBuilder, config);
>>>  delegate = fooBuilder.build();
>>>  }
>>> 
>>>  // Deactivation and Foo delegation methods go here
>>>  …
>>> }
>>> 
>>> Regards,
>>> 
>>> Tim
>>> 
 On 20 Apr 2017, at 09:30, Julian Sedding  wrote:
 
 Hi there
 
 I have been trying to implement a use-case, but I seem to be running
 into walls ;) (Disclaimer: I can see multiple ways to implement this,
 but would like to re-use the dependency injection and lazy
 instantiation of DS).
 
 My aim is to create configured service objects in the way that is
 normally achieved by using a DS factory component with
 configuration-policy require.
 
 The catch is that the implementation of the objects I want to
 configure and register as a service is not under my control and is
 instanciated via a builder obtained from a factory that is registered
 as an OSGi-service. Sounds a bit complicated, maybe it's clearer in
 code.
 
 @Component(
  service = Foo.class,
  configurationPolicy = ConfigurationPolicy.REQUIRE
 )
 public class FooServiceFactory implements ServiceFactory {
 
  @Reference // provides FooBuilder instances that are pre-configured via 
 OSGi
  private FooBuilderFactory fooBuilderFactory;
 
  @Override
  public Foo getService() {
  FooBuilder fooBuilder = fooBuilderFactory.builder();
  applyConfiguration(fooBuilder);
  return fooBuilder.build();
  }
 
  private void applyConfiguration(FooBuilder fooBuilder) {
  // apply OSGi configuration to FooBuilder object
  }
 
  ... // ungetService omitted for brevity
 
 }
 
 As far as I understand, this is not currently possible. The bnd 

Re: [osgi-dev] Allow registering a (Prototype)ServiceFactory via DS?

2017-04-20 Thread Timothy Ward
DS isn’t intended to solve every single use case, rather to make common use 
cases simple to write and understand. In this case what you want is more 
advanced, and unlikely to make it into DS as a natively supported pattern. 
Given that you’re already tied to the core OSGi API (ServiceFactory) then 
registering the service programatically would still let DS help you with config 
and service injection.


@Component(
   // Do not let DS provide the service
   service = {},
   configurationPolicy = ConfigurationPolicy.REQUIRE
)
public class FooServiceFactory implements ServiceFactory {

   @Reference // provides FooBuilder instances that are pre-configured via OSGi
   private FooBuilderFactory fooBuilderFactory;

   private ServiceRegistration reg;

  @Activate
  void start(BundleContext ctx, Map props, Config config) {
  reg = ctx.registerService(Foo.class.getName(), this, props);
  }

  @Deactivate
  void stop() {
  reg.unregister();
  }

   @Override
   public Foo getService() {
   FooBuilder fooBuilder = fooBuilderFactory.builder();
   applyConfiguration(fooBuilder);
   return fooBuilder.build();
   }

   private void applyConfiguration(FooBuilder fooBuilder) {
   // apply OSGi configuration to FooBuilder object
   }

   ... // ungetService omitted for brevity

}


Regards,

Tim


> On 20 Apr 2017, at 11:11, Julian Sedding  wrote:
> 
> Hi Timothy
> 
> Thanks for your reply. Using delegation works, I currently use it to
> solve my use-case.
> 
> However, compared to implementing a ServiceFactory, delegation adds
> some overhead:
> 
> - delegation needs to be implemented, which is trivial, but noisy if
> there are lots of methods that need delegating
> - by delegating, my implementation becomes a "provider" of Foo, rather
> than a "consumer", making my bundle more susceptible to changes in
> Foo's API
> - also: delegation is not possible if Foo is a final class
> 
> I brought up this topic in order to (a) confirm that my desired
> approach is indeed not possible at the moment and (b) to see if adding
> support for registering custom ServiceFactory implementations via DS
> could be a desirable enhancement for the spec.
> 
> Regards
> Julian
> 
> 
> On Thu, Apr 20, 2017 at 11:22 AM, Timothy Ward  wrote:
>> Have you not considered the following:
>> 
>> 
>> @Component(configurationPolicy = ConfigurationPolicy.REQUIRE,
>>scope = ServiceScope.BUNDLE)
>> public class FooImpl implements Foo {
>> 
>>   public @interface Config {
>>  // Config definition in here
>>   }
>> 
>>   @Reference
>>   private FooBuilderFactory fooBuilderFactory;
>> 
>>   private Foo delegate;
>> 
>>   @Activate
>>   void start(Config config) {
>>   FooBuilder fooBuilder = fooBuilderFactory.builder();
>>   applyConfiguration(fooBuilder, config);
>>   delegate = fooBuilder.build();
>>   }
>> 
>>   // Deactivation and Foo delegation methods go here
>>   …
>> }
>> 
>> Regards,
>> 
>> Tim
>> 
>>> On 20 Apr 2017, at 09:30, Julian Sedding  wrote:
>>> 
>>> Hi there
>>> 
>>> I have been trying to implement a use-case, but I seem to be running
>>> into walls ;) (Disclaimer: I can see multiple ways to implement this,
>>> but would like to re-use the dependency injection and lazy
>>> instantiation of DS).
>>> 
>>> My aim is to create configured service objects in the way that is
>>> normally achieved by using a DS factory component with
>>> configuration-policy require.
>>> 
>>> The catch is that the implementation of the objects I want to
>>> configure and register as a service is not under my control and is
>>> instanciated via a builder obtained from a factory that is registered
>>> as an OSGi-service. Sounds a bit complicated, maybe it's clearer in
>>> code.
>>> 
>>> @Component(
>>>   service = Foo.class,
>>>   configurationPolicy = ConfigurationPolicy.REQUIRE
>>> )
>>> public class FooServiceFactory implements ServiceFactory {
>>> 
>>>   @Reference // provides FooBuilder instances that are pre-configured via 
>>> OSGi
>>>   private FooBuilderFactory fooBuilderFactory;
>>> 
>>>   @Override
>>>   public Foo getService() {
>>>   FooBuilder fooBuilder = fooBuilderFactory.builder();
>>>   applyConfiguration(fooBuilder);
>>>   return fooBuilder.build();
>>>   }
>>> 
>>>   private void applyConfiguration(FooBuilder fooBuilder) {
>>>   // apply OSGi configuration to FooBuilder object
>>>   }
>>> 
>>>   ... // ungetService omitted for brevity
>>> 
>>> }
>>> 
>>> As far as I understand, this is not currently possible. The bnd tool
>>> shouts at the mismatch between the "service" attribute (Foo.class) and
>>> the ServiceFactory interface and refuses to generate the SCR XML. With
>>> a manually crafted XML, Apache Felix SCR ends up throwing exceptions.
>>> And most likely both implementations are correct, as I could not find
>>> anything supporting my use-case in the spec.
>>> 
>>> Can anyone on this list please confirm 

Re: [osgi-dev] Allow registering a (Prototype)ServiceFactory via DS?

2017-04-20 Thread Julian Sedding
Hi Timothy

Thanks for your reply. Using delegation works, I currently use it to
solve my use-case.

However, compared to implementing a ServiceFactory, delegation adds
some overhead:

- delegation needs to be implemented, which is trivial, but noisy if
there are lots of methods that need delegating
- by delegating, my implementation becomes a "provider" of Foo, rather
than a "consumer", making my bundle more susceptible to changes in
Foo's API
- also: delegation is not possible if Foo is a final class

I brought up this topic in order to (a) confirm that my desired
approach is indeed not possible at the moment and (b) to see if adding
support for registering custom ServiceFactory implementations via DS
could be a desirable enhancement for the spec.

Regards
Julian


On Thu, Apr 20, 2017 at 11:22 AM, Timothy Ward  wrote:
> Have you not considered the following:
>
>
> @Component(configurationPolicy = ConfigurationPolicy.REQUIRE,
> scope = ServiceScope.BUNDLE)
> public class FooImpl implements Foo {
>
>public @interface Config {
>   // Config definition in here
>}
>
>@Reference
>private FooBuilderFactory fooBuilderFactory;
>
>private Foo delegate;
>
>@Activate
>void start(Config config) {
>FooBuilder fooBuilder = fooBuilderFactory.builder();
>applyConfiguration(fooBuilder, config);
>delegate = fooBuilder.build();
>}
>
>// Deactivation and Foo delegation methods go here
>…
> }
>
> Regards,
>
> Tim
>
>> On 20 Apr 2017, at 09:30, Julian Sedding  wrote:
>>
>> Hi there
>>
>> I have been trying to implement a use-case, but I seem to be running
>> into walls ;) (Disclaimer: I can see multiple ways to implement this,
>> but would like to re-use the dependency injection and lazy
>> instantiation of DS).
>>
>> My aim is to create configured service objects in the way that is
>> normally achieved by using a DS factory component with
>> configuration-policy require.
>>
>> The catch is that the implementation of the objects I want to
>> configure and register as a service is not under my control and is
>> instanciated via a builder obtained from a factory that is registered
>> as an OSGi-service. Sounds a bit complicated, maybe it's clearer in
>> code.
>>
>> @Component(
>>service = Foo.class,
>>configurationPolicy = ConfigurationPolicy.REQUIRE
>> )
>> public class FooServiceFactory implements ServiceFactory {
>>
>>@Reference // provides FooBuilder instances that are pre-configured via 
>> OSGi
>>private FooBuilderFactory fooBuilderFactory;
>>
>>@Override
>>public Foo getService() {
>>FooBuilder fooBuilder = fooBuilderFactory.builder();
>>applyConfiguration(fooBuilder);
>>return fooBuilder.build();
>>}
>>
>>private void applyConfiguration(FooBuilder fooBuilder) {
>>// apply OSGi configuration to FooBuilder object
>>}
>>
>>... // ungetService omitted for brevity
>>
>> }
>>
>> As far as I understand, this is not currently possible. The bnd tool
>> shouts at the mismatch between the "service" attribute (Foo.class) and
>> the ServiceFactory interface and refuses to generate the SCR XML. With
>> a manually crafted XML, Apache Felix SCR ends up throwing exceptions.
>> And most likely both implementations are correct, as I could not find
>> anything supporting my use-case in the spec.
>>
>> Can anyone on this list please confirm that this is not (currently) possible?
>>
>> I think this use-case is relatively generic. It has two preconditions:
>>
>> - the implementation of the service object (e.g. Foo) is out of my
>> control and can therefore not be enhanced with OSGi-specifics
>> - in order to be able to create the service object, dependencies on
>> other services are required
>>
>> Does this sound like a possible addition to the Declarative Services
>> specification?
>>
>> Regards
>> Julian
>>
>> PS: For those curious on how this could be implemented today. One way
>> to implement this is to register the ServiceFactory (lazily) by hand.
>> Provided Foo is not a final class, another way is to create a wrapper
>> for Foo that delegates all calls to a "real" Foo instance. The
>> FooWrapper implementation is then under my control and can be enhanced
>> with DS annotations etc.
>> ___
>> OSGi Developer Mail List
>> osgi-dev@mail.osgi.org
>> https://mail.osgi.org/mailman/listinfo/osgi-dev
>
> ___
> OSGi Developer Mail List
> osgi-dev@mail.osgi.org
> https://mail.osgi.org/mailman/listinfo/osgi-dev
___
OSGi Developer Mail List
osgi-dev@mail.osgi.org
https://mail.osgi.org/mailman/listinfo/osgi-dev

Re: [osgi-dev] Allow registering a (Prototype)ServiceFactory via DS?

2017-04-20 Thread Timothy Ward
Have you not considered the following:


@Component(configurationPolicy = ConfigurationPolicy.REQUIRE,
scope = ServiceScope.BUNDLE)
public class FooImpl implements Foo {

   public @interface Config {
  // Config definition in here
   }

   @Reference
   private FooBuilderFactory fooBuilderFactory;

   private Foo delegate;

   @Activate
   void start(Config config) {
   FooBuilder fooBuilder = fooBuilderFactory.builder();
   applyConfiguration(fooBuilder, config);
   delegate = fooBuilder.build();
   }

   // Deactivation and Foo delegation methods go here
   …
}

Regards,

Tim

> On 20 Apr 2017, at 09:30, Julian Sedding  wrote:
> 
> Hi there
> 
> I have been trying to implement a use-case, but I seem to be running
> into walls ;) (Disclaimer: I can see multiple ways to implement this,
> but would like to re-use the dependency injection and lazy
> instantiation of DS).
> 
> My aim is to create configured service objects in the way that is
> normally achieved by using a DS factory component with
> configuration-policy require.
> 
> The catch is that the implementation of the objects I want to
> configure and register as a service is not under my control and is
> instanciated via a builder obtained from a factory that is registered
> as an OSGi-service. Sounds a bit complicated, maybe it's clearer in
> code.
> 
> @Component(
>service = Foo.class,
>configurationPolicy = ConfigurationPolicy.REQUIRE
> )
> public class FooServiceFactory implements ServiceFactory {
> 
>@Reference // provides FooBuilder instances that are pre-configured via 
> OSGi
>private FooBuilderFactory fooBuilderFactory;
> 
>@Override
>public Foo getService() {
>FooBuilder fooBuilder = fooBuilderFactory.builder();
>applyConfiguration(fooBuilder);
>return fooBuilder.build();
>}
> 
>private void applyConfiguration(FooBuilder fooBuilder) {
>// apply OSGi configuration to FooBuilder object
>}
> 
>... // ungetService omitted for brevity
> 
> }
> 
> As far as I understand, this is not currently possible. The bnd tool
> shouts at the mismatch between the "service" attribute (Foo.class) and
> the ServiceFactory interface and refuses to generate the SCR XML. With
> a manually crafted XML, Apache Felix SCR ends up throwing exceptions.
> And most likely both implementations are correct, as I could not find
> anything supporting my use-case in the spec.
> 
> Can anyone on this list please confirm that this is not (currently) possible?
> 
> I think this use-case is relatively generic. It has two preconditions:
> 
> - the implementation of the service object (e.g. Foo) is out of my
> control and can therefore not be enhanced with OSGi-specifics
> - in order to be able to create the service object, dependencies on
> other services are required
> 
> Does this sound like a possible addition to the Declarative Services
> specification?
> 
> Regards
> Julian
> 
> PS: For those curious on how this could be implemented today. One way
> to implement this is to register the ServiceFactory (lazily) by hand.
> Provided Foo is not a final class, another way is to create a wrapper
> for Foo that delegates all calls to a "real" Foo instance. The
> FooWrapper implementation is then under my control and can be enhanced
> with DS annotations etc.
> ___
> OSGi Developer Mail List
> osgi-dev@mail.osgi.org
> https://mail.osgi.org/mailman/listinfo/osgi-dev

___
OSGi Developer Mail List
osgi-dev@mail.osgi.org
https://mail.osgi.org/mailman/listinfo/osgi-dev

[osgi-dev] Allow registering a (Prototype)ServiceFactory via DS?

2017-04-20 Thread Julian Sedding
Hi there

I have been trying to implement a use-case, but I seem to be running
into walls ;) (Disclaimer: I can see multiple ways to implement this,
but would like to re-use the dependency injection and lazy
instantiation of DS).

My aim is to create configured service objects in the way that is
normally achieved by using a DS factory component with
configuration-policy require.

The catch is that the implementation of the objects I want to
configure and register as a service is not under my control and is
instanciated via a builder obtained from a factory that is registered
as an OSGi-service. Sounds a bit complicated, maybe it's clearer in
code.

@Component(
service = Foo.class,
configurationPolicy = ConfigurationPolicy.REQUIRE
)
public class FooServiceFactory implements ServiceFactory {

@Reference // provides FooBuilder instances that are pre-configured via OSGi
private FooBuilderFactory fooBuilderFactory;

@Override
public Foo getService() {
FooBuilder fooBuilder = fooBuilderFactory.builder();
applyConfiguration(fooBuilder);
return fooBuilder.build();
}

private void applyConfiguration(FooBuilder fooBuilder) {
// apply OSGi configuration to FooBuilder object
}

... // ungetService omitted for brevity

}

As far as I understand, this is not currently possible. The bnd tool
shouts at the mismatch between the "service" attribute (Foo.class) and
the ServiceFactory interface and refuses to generate the SCR XML. With
a manually crafted XML, Apache Felix SCR ends up throwing exceptions.
And most likely both implementations are correct, as I could not find
anything supporting my use-case in the spec.

Can anyone on this list please confirm that this is not (currently) possible?

I think this use-case is relatively generic. It has two preconditions:

- the implementation of the service object (e.g. Foo) is out of my
control and can therefore not be enhanced with OSGi-specifics
- in order to be able to create the service object, dependencies on
other services are required

Does this sound like a possible addition to the Declarative Services
specification?

Regards
Julian

PS: For those curious on how this could be implemented today. One way
to implement this is to register the ServiceFactory (lazily) by hand.
Provided Foo is not a final class, another way is to create a wrapper
for Foo that delegates all calls to a "real" Foo instance. The
FooWrapper implementation is then under my control and can be enhanced
with DS annotations etc.
___
OSGi Developer Mail List
osgi-dev@mail.osgi.org
https://mail.osgi.org/mailman/listinfo/osgi-dev