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