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<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> 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<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> 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 > >>> } > >>> > >>> @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> 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 > >>>> 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 > > > > _______________________________________________ > > 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 > > > > _______________________________________________ > 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