Search code examples
osgideclarative-services

OSGi: Can a declarative service reference use a target filter of a prototype component?


I have a service interface Logger and a service factory

interface LoggerFactory {
    Logger createLogger(String name)
}

My components use it like this:

@Component
public class User {
    
    private Logger logger;

    @Activate
    public User(@Reference LoggerFactory loggerFactory) {
        logger = loggerFactory.create("user")
    }
}

I'd like to get rid of the LoggerFactory and instead be able to retrieve my logger like this:

@Component
public class User {
    
    @Reference(target = "(name=user)")
    private Logger logger;

}

I tried to make the Logger implementations prototypes, but SCR didn't create the loggers as expected. Is it because factory components always require a configurationPID from the ConfigAdmin?

I also tried to register a PrototypeServiceFactory for the Logger interface explicitly via the bundle context, but no luck.

I'm under the impression that this must work somehow with declarative services, since another use case fits this pattern, so it seems to be a common problem: Many components use a http service but with a different port. I'd like to use a target filter for the reference, instead of my custom factory.

1.) How can I achieve that?

2.) If this is not possible, are there alternatives? Like having some other kind of service factory, which uses the component name as logger name?

3.) If this can work somehow, can I make the target filter optional, which then doesn't select a random logger, but instead one that uses the component name?


Solution

  • The target property is an LDAP filter expression used to select a service from the OSGi Service Registry. target = "(name=user)" means that a service must have a service property "name" with the value "user". The target property cannot be used to invoke a service with some argument.

    DS has special support for the OSGi Log Service but that support is special and does not apply generally to any arbitrary service.