2

Karaf reference is not injecting the reference objects. Please see my setup and code.

Version: apache-karaf-3.0.5

Part 1: Service class

Service:

package org.jrb.test;

public interface MyService
{
    String echo(String message);
}

package org.jrb.test;

public class MyServiceImpl implements MyService
{
    public String echo(String message)
    {
        return "Echo processed: " + message;
    }
}

Blueprint:

<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" default-activation="lazy">

    <bean id="serviceBean" class="org.jrb.test.MyServiceImpl"/>

    <service id="MyService" ref="serviceBean" interface="org.jrb.test.MyService"/>

</blueprint>

i can see my service in list:

onos> service:list | grep serviceBean

osgi.service.blueprint.compname = serviceBean

Part 2: consumer class for testing

Blueprint

<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" default-activation="lazy">

    <reference id="MyService" interface="org.jrb.test.MyService"/>

    <bean id="b" class="org.ct.command.AddCommand" activation="eager" >
        <property name="serviceBn" ref="MyService" />
    </bean>

    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
        <command>
            <action class="org.ct.command.AddCommand"/>
        </command>
    </command-bundle>

</blueprint>

In Java:

package org.ct.command;

import org.apache.felix.gogo.commands.Action;
import org.apache.felix.gogo.commands.Argument;
import org.apache.felix.gogo.commands.Command;
import org.apache.felix.service.command.CommandSession;

import org.jrb.test.MyService;

@Command(scope = "onos", name = "service-add", description = "Adds a Client")
public class AddCommand implements Action
{
    private MyService serviceBn;

    public void setServiceBn(MyService serviceBn)
    {
        this.serviceBn = serviceBn;
    }

    public MyService getServiceBn()
    {
        return service;
    }

    @Override
    public Object execute(CommandSession session) throws Exception
    {
        System.out.println("Executing command add");

        if (serviceBn != null) {
            System.out.println("serviceBn is not null");
            System.out.println(serviceBn.echo("testing....."));
        } else {
            System.out.println("serviceBn is null !!");
        }
    }
}

In the above code, if i run the command "service-add", my serviceBn is always null. The reference is not injecting the bean.

Is there anything missing in my code?

Sean Bright
  • 118,630
  • 17
  • 138
  • 146
  • Does your consumer bundle import the service from the same exported package as the provider bundle? – Neil Bartlett Aug 28 '16 at 05:03
  • My Observations: In the setter function (setServiceBn(MyService serviceBn)) , if i check, the "MyService" is not null. That means it is injecting during activating the feature. But after that in function execute(), it is getting null. Any suggestion to this? – Jayanth Bhavani Sep 01 '16 at 09:10
  • Maybe you have somehow constructed a second instance of AddCommand. – Neil Bartlett Sep 01 '16 at 09:33

1 Answers1

1

Perhaps you could use a different approach. As you construct your AddCommand as a Blueprint bean you could provide the MyService object as a constructor parameter:

@Command(scope = "onos", name = "service-add", description = "Adds a Client")
public class AddCommand implements Action
{
   private MyService serviceBn;

   public AddCommand(MyService myService) {
      this.serviceBn = myService;
   }
   ...
}

In Blueprint you then specify:

    ...
    <reference id="MyService" interface="org.jrb.test.MyService"/>

    <bean id="b" class="org.ct.command.AddCommand" activation="eager" >
       <argument ref="MyService" />
    </bean>
    ...

In our project we prefer this approach to property injection.

Update:

With the current blueprint there are two instances created. The bean is instance seperatly created.

To inject the service to the command you could try something like this:

<reference id="MyService" interface="org.jrb.test.MyService" availability="mandatory" />

<command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
  <command name="service:add">
     <action class="org.ct.command.AddCommand">
        <property name="serviceBn" ref="MyService"/>
     </action>
  </command>
</command-bundle> 
Oliver Wespi
  • 55
  • 1
  • 4
  • I have tried that too, this is also not working. My Observations: In the setter function (setServiceBn(MyService serviceBn)) also in constructor (as you suggested), if i check, the "MyService" is not null. That means it is injecting during activating the feature. But after that in function execute(), it is getting null. Any suggestion to this? – Jayanth Bhavani Sep 01 '16 at 09:05
  • I tried your little test program with the "Update" solution above and it worked. You should give it a try. – Oliver Wespi Sep 01 '16 at 18:39
  • for me does'nt work there is some other workaround anyone can suggest to me? – 4535992 Oct 29 '19 at 08:16