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 >> >> >>>>>>> >> >> >>>>>>> >> >> >>>>>>> >> >> >>>>>>> >> >> >>>>>> >> >> >>>>> >> >> >>>> >> >> >>> >> >> >> >> >> > >> >> >> >