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<T> 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
>> > )
>> > public class FooServiceFactory implements ServiceFactory<Foo> {
>> >
>> >    @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 
>> >> <mailto: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 
>> >> <mailto: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
>> >>>   }
>> >>>
>> >>>   @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 <jsedd...@gmail.com 
>> >>>> <mailto:jsedd...@gmail.com>> 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<Foo> {
>> >>>>
>> >>>>   @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 <mailto:osgi-dev@mail.osgi.org>
>> >>>> https://mail.osgi.org/mailman/listinfo/osgi-dev 
>> >>>> <https://mail.osgi.org/mailman/listinfo/osgi-dev>
>> >>>
>> >>> _______________________________________________
>> >>> OSGi Developer Mail List
>> >>> osgi-dev@mail.osgi.org <mailto:osgi-dev@mail.osgi.org>
>> >>> https://mail.osgi.org/mailman/listinfo/osgi-dev 
>> >>> <https://mail.osgi.org/mailman/listinfo/osgi-dev>
>> >> _______________________________________________
>> >> OSGi Developer Mail List
>> >> osgi-dev@mail.osgi.org <mailto:osgi-dev@mail.osgi.org>
>> >> https://mail.osgi.org/mailman/listinfo/osgi-dev 
>> >> <https://mail.osgi.org/mailman/listinfo/osgi-dev>
>> >
>> > _______________________________________________
>> > OSGi Developer Mail List
>> > osgi-dev@mail.osgi.org <mailto:osgi-dev@mail.osgi.org>
>> > https://mail.osgi.org/mailman/listinfo/osgi-dev 
>> > <https://mail.osgi.org/mailman/listinfo/osgi-dev>
>> _______________________________________________
>> OSGi Developer Mail List
>> osgi-dev@mail.osgi.org <mailto:osgi-dev@mail.osgi.org>
>> https://mail.osgi.org/mailman/listinfo/osgi-dev 
>> <https://mail.osgi.org/mailman/listinfo/osgi-dev>
>>  
>> 
>> _______________________________________________
>> OSGi Developer Mail List
>> osgi-dev@mail.osgi.org <mailto:osgi-dev@mail.osgi.org>
>> https://mail.osgi.org/mailman/listinfo/osgi-dev 
>> <https://mail.osgi.org/mailman/listinfo/osgi-dev>
> 
> _______________________________________________
> OSGi Developer Mail List
> osgi-dev@mail.osgi.org <mailto:osgi-dev@mail.osgi.org>
> https://mail.osgi.org/mailman/listinfo/osgi-dev 
> <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

Reply via email to