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 <peter.kri...@aqute.biz> 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 <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