From user-return-22541-apmail-karaf-user-archive=karaf.apache.org@karaf.apache.org Fri Jul 17 05:33:47 2020 Return-Path: X-Original-To: apmail-karaf-user-archive@minotaur.apache.org Delivered-To: apmail-karaf-user-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [207.244.88.153]) by minotaur.apache.org (Postfix) with SMTP id 74B7019350 for ; Fri, 17 Jul 2020 05:33:47 +0000 (UTC) Received: (qmail 35956 invoked by uid 500); 17 Jul 2020 05:33:46 -0000 Delivered-To: apmail-karaf-user-archive@karaf.apache.org Received: (qmail 35923 invoked by uid 500); 17 Jul 2020 05:33:46 -0000 Mailing-List: contact user-help@karaf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: user@karaf.apache.org Delivered-To: mailing list user@karaf.apache.org Received: (qmail 35913 invoked by uid 99); 17 Jul 2020 05:33:45 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd2-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 17 Jul 2020 05:33:45 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd2-us-west.apache.org (ASF Mail Server at spamd2-us-west.apache.org) with ESMTP id 38D131A4129 for ; Fri, 17 Jul 2020 05:33:45 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd2-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: 0.315 X-Spam-Level: X-Spam-Status: No, score=0.315 tagged_above=-999 required=6.31 tests=[KAM_DMARC_STATUS=0.01, KAM_LAZY_DOMAIN_SECURITY=1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_NONE=0.001, URIBL_BLOCKED=0.001] autolearn=disabled Received: from mx1-ec2-va.apache.org ([10.40.0.8]) by localhost (spamd2-us-west.apache.org [10.40.0.9]) (amavisd-new, port 10024) with ESMTP id Q2cevO-UkMUk for ; Fri, 17 Jul 2020 05:33:43 +0000 (UTC) Received-SPF: None (mailfrom) identity=mailfrom; client-ip=217.70.183.195; helo=relay3-d.mail.gandi.net; envelope-from=jb@nanthrax.net; receiver= Received: from relay3-d.mail.gandi.net (relay3-d.mail.gandi.net [217.70.183.195]) by mx1-ec2-va.apache.org (ASF Mail Server at mx1-ec2-va.apache.org) with ESMTPS id B8055BE2E9 for ; Fri, 17 Jul 2020 05:33:42 +0000 (UTC) X-Originating-IP: 78.218.26.15 Received: from [192.168.1.100] (hvc29-1-78-218-26-15.fbx.proxad.net [78.218.26.15]) (Authenticated sender: jb@nanthrax.net) by relay3-d.mail.gandi.net (Postfix) with ESMTPSA id 2717360008 for ; Fri, 17 Jul 2020 05:33:34 +0000 (UTC) From: Jean-Baptiste Onofre Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Mime-Version: 1.0 (Mac OS X Mail 13.4 \(3608.80.23.2.2\)) Subject: Re: Question about @Reference Karaf Command annotation Date: Fri, 17 Jul 2020 07:33:34 +0200 References: <4f6415b1-d7e8-3772-015f-3c5f731c641a@yahoo.com> <2076B0CF-8891-4E90-BF47-30A22B5748F6@intekon.com> To: user@karaf.apache.org In-Reply-To: <2076B0CF-8891-4E90-BF47-30A22B5748F6@intekon.com> Message-Id: <3337BE71-3A3C-406A-B6CD-9881724EC6DC@nanthrax.net> X-Mailer: Apple Mail (2.3608.80.23.2.2) 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 =C3=A0 15:52, Paul Spencerx a = =C3=A9crit : >=20 > 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. >=20 > https://issues.apache.org/jira/browse/KARAF-6790 >=20 > Paul Spencer >=20 >> On Jul 16, 2020, at 8:50 AM, Alex Soto wrote: >>=20 >> 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. >>=20 >> Best regards, >> Alex soto >>=20 >>=20 >>=20 >>=20 >>> On Jul 16, 2020, at 6:26 AM, Jo=C3=A3o Assun=C3=A7=C3=A3o = wrote: >>>=20 >>> 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. >>>=20 >>> 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. >>>=20 >>>=20 >>>=20 >>> Jo=C3=A3o Assun=C3=A7=C3=A3o >>>=20 >>> Email: joao.assuncao@exploitsys.com >>> Mobile: +351 916968984 >>> Phone: +351 211933149 >>> Web: www.exploitsys.com >>>=20 >>>=20 >>>=20 >>>=20 >>> On Thu, Jul 16, 2020 at 1:42 AM Paul Spencer = 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. >>>=20 >>> Details below. >>>=20 >>> *** >>> * =46rom 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; >>>=20 >>> import com.example.service.ColorService; >>>=20 >>> @Service >>> @Command(scope =3D "color", name =3D "get-red", description =3D "Get = Red Service") >>> public class DisplayRedServiceCommand implements Action { >>>=20 >>> @Reference(filter =3D "(color=3Dred)") >>> private ColorService colorService; >>>=20 >>> *** >>> * Output from Command that get a RedColor service >>> *** >>> karaf@root()> color:get-red >>> Color =3D BLUE >>>=20 >>> *** >>> * 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; >>>=20 >>> import com.example.service.ColorService; >>>=20 >>> @Component(immediate =3D true, property =3D "color=3Dred") >>> public class RedColorService implements ColorService { >>> private final Logger log =3D = LoggerFactory.getLogger(getClass()); >>>=20 >>> *** >>> * 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; >>>=20 >>> import com.example.service.ColorService; >>> import com.example.service.GenericColorService; >>>=20 >>> @Component(immediate =3D true, property =3D "color=3Dall") >>> public class AllColorService implements GenericColorService { >>> private final Logger log =3D = LoggerFactory.getLogger(getClass()); >>>=20 >>> @Reference(target =3D "(color=3Dred)") >>> private ColorService redColorService; >>>=20 >>> @Reference(target =3D "(color=3Dgreen)") >>> private ColorService greenColorService; >>> @Reference(target =3D "(color=3Dblue)") >>> private ColorService blueColorService; >>>=20 >>> @Override >>> public String getColor() { >>> StringBuffer colors =3D new StringBuffer(); >>> colors.append(redColorService.getColor()); >>> colors.append(", "); >>> colors.append(greenColorService.getColor()); >>> colors.append(", "); >>> colors.append(blueColorService.getColor()); >>> return colors.toString(); >>> } >>>=20 >>> *** >>> * 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; >>>=20 >>> import com.example.secondService.TwoColorService; >>>=20 >>> @Service >>> @Command(scope =3D "yellow", name =3D "yellow", description =3D "Get = Yellow Service") >>> public class DisplayYellowServiceCommand implements Action { >>>=20 >>> @Reference >>> private TwoColorService colorService; >>>=20 >>> @Override >>> public Object execute() throws Exception { >>> System.out.println("Color =3D " + = colorService.getColor()); >>> return null; >>> } >>>=20 >>> *** >>> * Output from Command that get a two color service >>> *** >>> karaf@root()> yellow:yellow >>> Color =3D RED, GREEN >>>=20 >>>=20 >>> *** >>> * 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; >>>=20 >>> import com.example.secondService.TwoColorService; >>> import com.example.service.ColorService; >>>=20 >>> @Component(immediate =3D true, property =3D "2color=3Dyellow") >>> public class YellowColorService implements TwoColorService { >>> private final Logger log =3D = LoggerFactory.getLogger(getClass()); >>>=20 >>> @Reference(target =3D "(color=3Dred)") >>> private ColorService redColorService; >>> @Reference(target =3D "(color=3Dgreen)") >>> private ColorService greenColorService; >>>=20 >>> @Override >>> public String getColor() { >>> StringBuffer colors =3D new StringBuffer(); >>> colors.append(redColorService.getColor()); >>> colors.append(", "); >>> colors.append(greenColorService.getColor()); >>> return colors.toString(); >>> } >>>=20 >>> Paul Spencer >>>=20 >>>=20 >>>> On Jul 15, 2020, at 3:12 PM, Martin Lichtin = wrote: >>>>=20 >>>> Yes that should work. You need the parenthesis. >>>> The code is doing something like >>>>=20 >>>> String filterString =3D '(' + Constants.OBJECTCLASS = + '=3D' + clazz.getName() + ')'; >>>> if (filter !=3D null && !filter.isEmpty()) { >>>> filterString =3D "(&" + filterString + filter + = ')'; >>>> } >>>>=20 >>>> On 15.07.2020 18:06, Jo=C3=A3o Assun=C3=A7=C3=A3o wrote: >>>>> Hello all, >>>>>=20 >>>>> Have you tried to use an LDAP filter expression? Instead of = *color=3Dred* try *(color=3Dred). *(I haven't tried this myself) >>>>>=20 >>>>> Jo=C3=A3o Assun=C3=A7=C3=A3o >>>>>=20 >>>>> Email: joao.assuncao@exploitsys.com = >>>>> Mobile: +351 916968984 >>>>> Phone: +351 211933149 >>>>> Web: www.exploitsys.com >>>>>=20 >>>>>=20 >>>>>=20 >>>>>=20 >>>>> On Mon, Jul 13, 2020 at 6:33 PM Paul Spencerx > wrote: >>>>>=20 >>>>> JB, >>>>> What is the status of your checking? >>>>>=20 >>>>> @Reference for commands is not working for me either. I have = included related code and output from Karaf below. >>>>>=20 >>>>> *** >>>>> * Testing commands >>>>> *** >>>>> karaf@root()> color --help >>>>> SUBSHELL >>>>> color >>>>>=20 >>>>> 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 =3D BLUE >>>>> karaf@root()> color:get-red >>>>> Color =3D BLUE >>>>> karaf@root()> color:get-red >>>>> Color =3D BLUE >>>>> karaf@root()> color:get-any >>>>> Color =3D BLUE >>>>> karaf@root()> color:get-green >>>>> Color =3D BLUE >>>>> karaf@root()> >>>>>=20 >>>>> *** >>>>> * Available Color Services >>>>> *** >>>>> karaf@root()> services -p 165 >>>>>=20 >>>>> Karaf Service sandbox (165) provides: >>>>> ------------------------------------- >>>>> color =3D blue >>>>> component.id =3D 9 >>>>> component.name =3D = com.example.service.internal.BlueColorService >>>>> objectClass =3D [com.example.service.ColorService] >>>>> service.bundleid =3D 165 >>>>> service.id =3D 193 >>>>> service.scope =3D bundle >>>>> ---- >>>>> color =3D green >>>>> component.id =3D 10 >>>>> component.name =3D = com.example.service.internal.GreenColorService >>>>> objectClass =3D [com.example.service.ColorService] >>>>> service.bundleid =3D 165 >>>>> service.id =3D 194 >>>>> service.scope =3D bundle >>>>> ---- >>>>> color =3D red >>>>> component.id =3D 11 >>>>> component.name =3D = com.example.service.internal.RedColorService >>>>> objectClass =3D [com.example.service.ColorService] >>>>> service.bundleid =3D 165 >>>>> service.id =3D 195 >>>>> service.scope =3D bundle >>>>> karaf@root()> >>>>>=20 >>>>> *** >>>>> * Example command source code >>>>> *** >>>>> package com.example.command.internal; >>>>>=20 >>>>> 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; >>>>>=20 >>>>> import com.example.service.ColorService; >>>>>=20 >>>>> @Service >>>>> @Command(scope =3D "color", name =3D "get-red", description =3D = "Get Red Service") >>>>> public class DisplayRedServiceCommand implements Action { >>>>>=20 >>>>> @Reference(filter =3D "color=3Dred") >>>>> private ColorService colorService; >>>>>=20 >>>>> @Override >>>>> public Object execute() throws Exception { >>>>> System.out.println("Color =3D " + = colorService.getColor()); >>>>> return null; >>>>> } >>>>>=20 >>>>> } >>>>>=20 >>>>> *** >>>>> * Example Service source code >>>>> *** >>>>> package com.example.service.internal; >>>>>=20 >>>>> import org.osgi.service.component.annotations.Component; >>>>>=20 >>>>> import com.example.service.ColorService; >>>>>=20 >>>>> @Component(immediate =3D true, property =3D "color=3Dred") >>>>> public class RedColorService implements ColorService { >>>>>=20 >>>>> @Override >>>>> public String getColor() { >>>>> return "RED"; >>>>> } >>>>>=20 >>>>> } >>>>>=20 >>>>>=20 >>>>> Paul Spencer >>>>>=20 >>>>>=20 >>>>>> On Mar 12, 2020, at 9:41 AM, Alex Soto > wrote: >>>>>>=20 >>>>>> 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. >>>>>>=20 >>>>>> Best regards, >>>>>> Alex soto >>>>>>=20 >>>>>>=20 >>>>>>=20 >>>>>>=20 >>>>>>> On Mar 12, 2020, at 9:24 AM, Jean-Baptiste Onofre = > wrote: >>>>>>>=20 >>>>>>> Hi, >>>>>>>=20 >>>>>>> Let me check, but AFAIR, I have a test about that and it seems = to work. >>>>>>>=20 >>>>>>> I will create a Jira to double check. >>>>>>>=20 >>>>>>> Regards >>>>>>> JB >>>>>>>=20 >>>>>>>> Le 12 mars 2020 =C3=A0 14:23, Alex Soto > a =C3=A9crit : >>>>>>>>=20 >>>>>>>> I see, but it is not working for me=E2=80=A6 >>>>>>>>=20 >>>>>>>> The PR does not update = org.apache.karaf.shell.impl.action.command.ManagerImpl#instantiate, = shouldn=E2=80=99t this method be updated also to inject the appropriate = service when the command is instantiated? (See code fragment I pasted = earlier) >>>>>>>>=20 >>>>>>>>=20 >>>>>>>> Best regards, >>>>>>>> Alex soto >>>>>>>>=20 >>>>>>>>=20 >>>>>>>>=20 >>>>>>>>=20 >>>>>>>>> On Mar 12, 2020, at 9:07 AM, Jean-Baptiste Onofre = > wrote: >>>>>>>>>=20 >>>>>>>>> Hi Alex, >>>>>>>>>=20 >>>>>>>>> You can find the change I did about that here: >>>>>>>>>=20 >>>>>>>>> https://github.com/apache/karaf/pull/992 >>>>>>>>>=20 >>>>>>>>> Regards >>>>>>>>> JB >>>>>>>>>=20 >>>>>>>>>> Le 12 mars 2020 =C3=A0 14:02, Alex Soto = > a =C3=A9crit : >>>>>>>>>>=20 >>>>>>>>>> Thanks, JB >>>>>>>>>>=20 >>>>>>>>>> But it doesn=E2=80=99t 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: >>>>>>>>>>=20 >>>>>>>>>> Reference ref =3D = field.getAnnotation(Reference.class); >>>>>>>>>> if (ref !=3D null) { >>>>>>>>>> GenericType type =3D new = GenericType(field.getGenericType()); >>>>>>>>>> Object value; >>>>>>>>>> if (type.getRawClass() =3D=3D List.class) = { >>>>>>>>>> Set set =3D new HashSet<>(); >>>>>>>>>> = set.addAll(registry.getServices(type.getActualTypeArgument(0).getRawClass(= ))); >>>>>>>>>> if (registry !=3D this.dependencies) { >>>>>>>>>> = set.addAll(this.dependencies.getServices(type.getActualTypeArgument(0).get= RawClass())); >>>>>>>>>> } >>>>>>>>>> value =3D new ArrayList<>(set); >>>>>>>>>> } else { >>>>>>>>>> value =3D = registry.getService(type.getRawClass()); >>>>>>>>>> if (value =3D=3D null && registry !=3D = this.dependencies) { >>>>>>>>>> value =3D = this.dependencies.getService(type.getRawClass()); >>>>>>>>>> } >>>>>>>>>> } >>>>>>>>>> if (!allowCustomServices && value =3D=3D = null && !ref.optional()) { >>>>>>>>>> throw new IllegalStateException("No = service matching " + field.getType().getName()); >>>>>>>>>> } >>>>>>>>>> field.setAccessible(true); >>>>>>>>>> field.set(instance, value); >>>>>>>>>> } >>>>>>>>>>=20 >>>>>>>>>> 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. >>>>>>>>>>=20 >>>>>>>>>>=20 >>>>>>>>>> Best regards, >>>>>>>>>> Alex soto >>>>>>>>>>=20 >>>>>>>>>>=20 >>>>>>>>>>=20 >>>>>>>>>>=20 >>>>>>>>>>> On Mar 12, 2020, at 12:50 AM, Jean-Baptiste Onofre = > wrote: >>>>>>>>>>>=20 >>>>>>>>>>> Hi, >>>>>>>>>>>=20 >>>>>>>>>>> Yes, it=E2=80=99s to "select" the service you want to use. >>>>>>>>>>>=20 >>>>>>>>>>> I did the change because previously it wasn=E2=80=99t = possible to select, meaning that if you had several services (with the = same interface) available, it took the first one. >>>>>>>>>>>=20 >>>>>>>>>>> Now, you can specify the LDIF filter to select the exact = service you want to inject. >>>>>>>>>>>=20 >>>>>>>>>>> Regards >>>>>>>>>>> JB >>>>>>>>>>>=20 >>>>>>>>>>>> Le 11 mars 2020 =C3=A0 20:03, Alex Soto = > a =C3=A9crit : >>>>>>>>>>>>=20 >>>>>>>>>>>> Is the filter attribute in annotation = org.apache.karaf.shell.api.action.lifecycle.Reference used to filter the = injected service on Service attributes? >>>>>>>>>>>>=20 >>>>>>>>>>>> Best regards, >>>>>>>>>>>> Alex soto >>>>>>>>>>>>=20 >>>>>>>>>>>>=20 >>>>>>>>>>>>=20 >>>>>>>>>>>>=20 >>>>>>>>>>>=20 >>>>>>>>>>=20 >>>>>>>>>=20 >>>>>>>>=20 >>>>>>>=20 >>>>>>=20 >>>>>=20 >>>=20 >>=20 >=20