Alex,
I have created the following Jira.  Please note the Jira describes the behavior 
and references this thread.  You may add information regarding the suspected 
root cause.

  https://issues.apache.org/jira/browse/KARAF-6790

Paul Spencer

> On Jul 16, 2020, at 8:50 AM, Alex Soto <alex.s...@envieta.com> wrote:
> 
> I also believe there is a bug here; I had pasted in a previous post the part 
> of the code I suspect is at fault.
> 
> Best regards,
> Alex soto
> 
> 
> 
> 
>> On Jul 16, 2020, at 6:26 AM, João Assunção <joao.assun...@exploitsys.com> 
>> wrote:
>> 
>> Paul,
>> you are right. I think there is a bug in the implementation of 
>> SingleServiceTracker used to bind service references in commands.
>> The filter is used for the listener but is ignored when retrieving the 
>> serviceReference.
>> 
>> For example:
>> If the command starts and the services are available, it will use the first 
>> service matching the class and ignore the filter.
>> If the command starts and no service is available, the listener will be 
>> called when one service matches the filter. When one matches, 
>> SingleServiceTracker.findMatchingReference will be called and the filter is 
>> ignored.
>> 
>> 
>> 
>> João Assunção
>> 
>> Email: joao.assun...@exploitsys.com
>> Mobile: +351 916968984
>> Phone: +351 211933149
>> Web: www.exploitsys.com
>> 
>> 
>> 
>> 
>> On Thu, Jul 16, 2020 at 1:42 AM Paul Spencer <paulspen...@mindspring.com> 
>> wrote:
>> 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 <lich...@yahoo.com> 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: joao.assun...@exploitsys.com <mailto:joao.assun...@exploitsys.com>
>> >> 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 <p...@intekon.com 
>> >> <mailto:p...@intekon.com>> 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 <alex.s...@envieta.com 
>> >> <mailto:alex.s...@envieta.com>> 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 
>> >> <j...@nanthrax.net <mailto:j...@nanthrax.net>> 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 <alex.s...@envieta.com 
>> >> <mailto:alex.s...@envieta.com>> 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 
>> >> <j...@nanthrax.net <mailto:j...@nanthrax.net>> 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 <alex.s...@envieta.com 
>> >> <mailto:alex.s...@envieta.com>> 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 
>> >> <j...@nanthrax.net <mailto:j...@nanthrax.net>> 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 <alex.s...@envieta.com 
>> >> <mailto:alex.s...@envieta.com>> 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