Hi guys,

Thanks for the Jira. I did some cleanup (we had two Jira for the same thing) 
and I already started to work on a fix.

Regards
JB

> Le 16 juil. 2020 à 15:52, Paul Spencerx <p...@intekon.com> a écrit :
> 
> 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