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

Reply via email to