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