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