Martin,
Parenthesis in the @Reference, 
org.apache.karaf.shell.api.action.lifecycle.Reference, for the Command did not 
change the results, this the wrong service was returned.  Parenthesis are 
required for the @Reference,org.osgi.service.component.annotations.Reference, 
in the @Component.

Details below.

***
* From command that uses the RedColor service
*  Parenthesis did not return the correct ColorService.
***
import org.apache.karaf.shell.api.action.Action;
import org.apache.karaf.shell.api.action.Command;
import org.apache.karaf.shell.api.action.lifecycle.Reference;
import org.apache.karaf.shell.api.action.lifecycle.Service;

import com.example.service.ColorService;

@Service
@Command(scope = "color", name = "get-red", description = "Get Red Service")
public class DisplayRedServiceCommand implements Action {

        @Reference(filter = "(color=red)")
        private ColorService colorService;

***
* Output from Command that get a RedColor service
***
karaf@root()> color:get-red
Color = BLUE

***
* Component the defines the RedColor service
***
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Modified;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.example.service.ColorService;

@Component(immediate = true, property = "color=red")
public class RedColorService implements ColorService {
        private final Logger log = LoggerFactory.getLogger(getClass());

***
* Component that uses the RedColor Service
***
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Modified;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.example.service.ColorService;
import com.example.service.GenericColorService;

@Component(immediate = true, property = "color=all")
public class AllColorService implements GenericColorService {
        private final Logger log = LoggerFactory.getLogger(getClass());

        @Reference(target = "(color=red)")
        private ColorService redColorService;

        @Reference(target = "(color=green)")
        private ColorService greenColorService;
        @Reference(target = "(color=blue)")
        private ColorService blueColorService;

        @Override
        public String getColor() {
                StringBuffer colors = new StringBuffer();
                colors.append(redColorService.getColor());
                colors.append(", ");
                colors.append(greenColorService.getColor());
                colors.append(", ");
                colors.append(blueColorService.getColor());
                return colors.toString();
        }

***
* Command that get a two color service
***
import org.apache.karaf.shell.api.action.Action;
import org.apache.karaf.shell.api.action.Command;
import org.apache.karaf.shell.api.action.lifecycle.Reference;
import org.apache.karaf.shell.api.action.lifecycle.Service;

import com.example.secondService.TwoColorService;

@Service
@Command(scope = "yellow", name = "yellow", description = "Get Yellow Service")
public class DisplayYellowServiceCommand implements Action {

        @Reference
        private TwoColorService colorService;

        @Override
        public Object execute() throws Exception {
                System.out.println("Color = " + colorService.getColor());
                return null;
        }

***
* Output from Command that get a two color service
***
karaf@root()> yellow:yellow
Color = RED, GREEN


***
* Component that produces a two color service
***
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Modified;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.example.secondService.TwoColorService;
import com.example.service.ColorService;

@Component(immediate = true, property = "2color=yellow")
public class YellowColorService implements TwoColorService {
        private final Logger log = LoggerFactory.getLogger(getClass());

        @Reference(target = "(color=red)")
        private ColorService redColorService;
        @Reference(target = "(color=green)")
        private ColorService greenColorService;

        @Override
        public String getColor() {
                StringBuffer colors = new StringBuffer();
                colors.append(redColorService.getColor());
                colors.append(", ");
                colors.append(greenColorService.getColor());
                return colors.toString();
        }

Paul Spencer
 

> On Jul 15, 2020, at 3:12 PM, Martin Lichtin <[email protected]> wrote:
> 
> Yes that should work. You need the parenthesis.
> The code is doing something like
> 
>                 String filterString = '(' + Constants.OBJECTCLASS + '=' + 
> clazz.getName() + ')';
>                 if (filter != null && !filter.isEmpty()) {
>                     filterString = "(&" + filterString + filter + ')';
>                 }
> 
> On 15.07.2020 18:06, João Assunção wrote:
>> Hello all,
>> 
>> Have you tried to use an LDAP filter expression?  Instead of *color=red* try 
>> *(color=red). *(I haven't tried this myself)
>> 
>> João Assunção
>> 
>> Email: [email protected] <mailto:[email protected]>
>> Mobile: +351 916968984
>> Phone: +351 211933149
>> Web: www.exploitsys.com <http://www.exploitsys.com>
>> 
>> 
>> 
>> 
>> On Mon, Jul 13, 2020 at 6:33 PM Paul Spencerx <[email protected] 
>> <mailto:[email protected]>> wrote:
>> 
>>    JB,
>>    What is the status of your checking?
>> 
>>    @Reference for commands is not working for me either.  I have included 
>> related code and output from Karaf below.
>> 
>>    ***
>>    * Testing commands
>>    ***
>>    karaf@root()> color --help
>>    SUBSHELL
>>            color
>> 
>>    COMMANDS
>>        color:get-any   Get any Service
>>        color:get-blue  Get Blue Service
>>        color:get-green Get Green Service
>>        color:get-red   Get Red Service
>>    karaf@root()> color:get-red
>>    Color = BLUE
>>    karaf@root()> color:get-red
>>    Color = BLUE
>>    karaf@root()> color:get-red
>>    Color = BLUE
>>    karaf@root()> color:get-any
>>    Color = BLUE
>>    karaf@root()> color:get-green
>>    Color = BLUE
>>    karaf@root()>
>> 
>>    ***
>>    * Available Color Services
>>    ***
>>    karaf@root()> services -p  165
>> 
>>    Karaf Service sandbox (165) provides:
>>    -------------------------------------
>>    color = blue
>>    component.id <http://component.id> = 9
>>    component.name <http://component.name> = 
>> com.example.service.internal.BlueColorService
>>    objectClass = [com.example.service.ColorService]
>>    service.bundleid = 165
>>    service.id <http://service.id> = 193
>>    service.scope = bundle
>>    ----
>>    color = green
>>    component.id <http://component.id> = 10
>>    component.name <http://component.name> = 
>> com.example.service.internal.GreenColorService
>>    objectClass = [com.example.service.ColorService]
>>    service.bundleid = 165
>>    service.id <http://service.id> = 194
>>    service.scope = bundle
>>    ----
>>    color = red
>>    component.id <http://component.id> = 11
>>    component.name <http://component.name> = 
>> com.example.service.internal.RedColorService
>>    objectClass = [com.example.service.ColorService]
>>    service.bundleid = 165
>>    service.id <http://service.id> = 195
>>    service.scope = bundle
>>    karaf@root()>
>> 
>>    ***
>>    * Example command source code
>>    ***
>>    package com.example.command.internal;
>> 
>>    import org.apache.karaf.shell.api.action.Action;
>>    import org.apache.karaf.shell.api.action.Command;
>>    import org.apache.karaf.shell.api.action.lifecycle.Reference;
>>    import org.apache.karaf.shell.api.action.lifecycle.Service;
>> 
>>    import com.example.service.ColorService;
>> 
>>    @Service
>>    @Command(scope = "color", name = "get-red", description = "Get Red 
>> Service")
>>    public class DisplayRedServiceCommand implements Action {
>> 
>>            @Reference(filter = "color=red")
>>            private ColorService colorService;
>> 
>>            @Override
>>            public Object execute() throws Exception {
>>                    System.out.println("Color = " + colorService.getColor());
>>                    return null;
>>            }
>> 
>>    }
>> 
>>    ***
>>    * Example Service source code
>>    ***
>>    package com.example.service.internal;
>> 
>>    import org.osgi.service.component.annotations.Component;
>> 
>>    import com.example.service.ColorService;
>> 
>>    @Component(immediate = true, property = "color=red")
>>    public class RedColorService implements ColorService {
>> 
>>            @Override
>>            public String getColor() {
>>                    return "RED";
>>            }
>> 
>>    }
>> 
>> 
>>    Paul Spencer
>> 
>> 
>>    > On Mar 12, 2020, at 9:41 AM, Alex Soto <[email protected] 
>> <mailto:[email protected]>> wrote:
>>    >
>>    > Just to clarify, when I say it does not work, I mean that the injected 
>> service is not the correct one matching the filter expression.
>>    >
>>    > Best regards,
>>    > Alex soto
>>    >
>>    >
>>    >
>>    >
>>    >> On Mar 12, 2020, at 9:24 AM, Jean-Baptiste Onofre <[email protected] 
>> <mailto:[email protected]>> wrote:
>>    >>
>>    >> Hi,
>>    >>
>>    >> Let me check, but AFAIR, I have a test about that and it seems to work.
>>    >>
>>    >> I will create a Jira to double check.
>>    >>
>>    >> Regards
>>    >> JB
>>    >>
>>    >>> Le 12 mars 2020 à 14:23, Alex Soto <[email protected] 
>> <mailto:[email protected]>> a écrit :
>>    >>>
>>    >>> I see, but it is not working for me…
>>    >>>
>>    >>> The PR  does not update 
>> org.apache.karaf.shell.impl.action.command.ManagerImpl#instantiate, 
>> shouldn’t this method be updated also to inject the appropriate service when 
>> the command is instantiated? (See code fragment I pasted earlier)
>>    >>>
>>    >>>
>>    >>> Best regards,
>>    >>> Alex soto
>>    >>>
>>    >>>
>>    >>>
>>    >>>
>>    >>>> On Mar 12, 2020, at 9:07 AM, Jean-Baptiste Onofre <[email protected] 
>> <mailto:[email protected]>> wrote:
>>    >>>>
>>    >>>> Hi Alex,
>>    >>>>
>>    >>>> You can find the change I did about that here:
>>    >>>>
>>    >>>> https://github.com/apache/karaf/pull/992
>>    >>>>
>>    >>>> Regards
>>    >>>> JB
>>    >>>>
>>    >>>>> Le 12 mars 2020 à 14:02, Alex Soto <[email protected] 
>> <mailto:[email protected]>> a écrit :
>>    >>>>>
>>    >>>>> Thanks, JB
>>    >>>>>
>>    >>>>> But it doesn’t seem to work for Karaf 4.2.8.
>>    >>>>> I am not  familiar with the internals of Karaf code, but I spotted 
>> the following in 
>> org.apache.karaf.shell.impl.action.command.ManagerImpl.instantiate of  
>> org.apache.karaf.shell.core-4.2.8.jar:
>>    >>>>>
>>    >>>>>           Reference ref = field.getAnnotation(Reference.class);
>>    >>>>>                 if (ref != null) {
>>    >>>>>                     GenericType type = new 
>> GenericType(field.getGenericType());
>>    >>>>>                     Object value;
>>    >>>>>                     if (type.getRawClass() == List.class) {
>>    >>>>>                         Set<Object> set = new HashSet<>();
>>    >>>>>  
>> set.addAll(registry.getServices(type.getActualTypeArgument(0).getRawClass()));
>>    >>>>>                         if (registry != this.dependencies) {
>>    >>>>>  
>> set.addAll(this.dependencies.getServices(type.getActualTypeArgument(0).getRawClass()));
>>    >>>>>                         }
>>    >>>>>                         value = new ArrayList<>(set);
>>    >>>>>                     } else {
>>    >>>>>                         value = 
>> registry.getService(type.getRawClass());
>>    >>>>>                         if (value == null && registry != 
>> this.dependencies) {
>>    >>>>>                             value = 
>> this.dependencies.getService(type.getRawClass());
>>    >>>>>                         }
>>    >>>>>                     }
>>    >>>>>                     if (!allowCustomServices && value == null && 
>> !ref.optional()) {
>>    >>>>>                         throw new IllegalStateException("No service 
>> matching " + field.getType().getName());
>>    >>>>>                     }
>>    >>>>>  field.setAccessible(true);
>>    >>>>>                     field.set(instance, value);
>>    >>>>>                 }
>>    >>>>>
>>    >>>>> Maybe this is not the relevant piece of code, but I do not see that 
>> the filter attribute is being used to look up the service.
>>    >>>>>
>>    >>>>>
>>    >>>>> Best regards,
>>    >>>>> Alex soto
>>    >>>>>
>>    >>>>>
>>    >>>>>
>>    >>>>>
>>    >>>>>> On Mar 12, 2020, at 12:50 AM, Jean-Baptiste Onofre 
>> <[email protected] <mailto:[email protected]>> wrote:
>>    >>>>>>
>>    >>>>>> Hi,
>>    >>>>>>
>>    >>>>>> Yes, it’s to "select" the service you want to use.
>>    >>>>>>
>>    >>>>>> I did the change because previously it wasn’t possible to select, 
>> meaning that if you had several services (with the same interface) 
>> available, it took the first one.
>>    >>>>>>
>>    >>>>>> Now, you can specify the LDIF filter to select the exact service 
>> you want to inject.
>>    >>>>>>
>>    >>>>>> Regards
>>    >>>>>> JB
>>    >>>>>>
>>    >>>>>>> Le 11 mars 2020 à 20:03, Alex Soto <[email protected] 
>> <mailto:[email protected]>> a écrit :
>>    >>>>>>>
>>    >>>>>>> Is the filter attribute in annotation 
>> org.apache.karaf.shell.api.action.lifecycle.Reference used to filter the 
>> injected service on Service attributes?
>>    >>>>>>>
>>    >>>>>>> Best regards,
>>    >>>>>>> Alex soto
>>    >>>>>>>
>>    >>>>>>>
>>    >>>>>>>
>>    >>>>>>>
>>    >>>>>>
>>    >>>>>
>>    >>>>
>>    >>>
>>    >>
>>    >
>> 

Reply via email to