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 <[email protected]> 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 <[email protected]> >> 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: [email protected] >> Mobile: +351 916968984 >> Phone: +351 211933149 >> Web: www.exploitsys.com >> >> >> >> >> On Thu, Jul 16, 2020 at 1:42 AM Paul Spencer <[email protected]> >> 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 <[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 >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>> >>>>>> >>>>> >>>> >> >
