Featured post

Docker setup for Liferay 7 with MySQL

Tuesday 10 April 2018

Osgi Target, Property attributes and Multiple Implementations

Osgi Target and Property attributes

In Spring you can use @Qualifier to get the correct class for respective instances.
How can we achieve this in OSGI framework is the question?

With help of Osgi and it's SCR(Service Component Runtime) you can use dynamic instantiation of Declarative Services.
Correct implementation should be selected for each instance to develop and use IS-A relationships.

Developers can instantiate a interface with different implementations by utlizing "target" attribute inside @Reference annotation. All you need is to enable the classes to get it from SCR with "property" attribute inside @Component annotation.

Below is the sample code to achieve the described matter

Problem Statement : We need to convert Numbers from string in different formats like Integer, Double, Float etc. and use them in different osgi components.


We will create interface and two classes which will implement this interface and consume them in another component for demonstration purpose.



public interface OsgiTarget {

 public Number convert(String str);
}

As you can see we defined multiple properties inside @Component annotation.

@Component(property = {
        "osgi.target.example.integer=true",
        "osgi.target.example.integer.again=true" // Dummy entry for multiple target example, you can get this instance with this property as well
})
public class OsgiTargetIntegerImpl implements OsgiTarget {
 @Override
 public Integer convert(String str) {
  return Integer.valueOf(str);
 }
}

Here we have single property for the same.

@Component(property = "osgi.target.example.double=true")
public class OsgiTargetDoubleImpl implements OsgiTarget{

 @Override
 public Double convert(String str) {
  return Double.valueOf(str);
 }
}


Now we have basic converters with different implementations.
We will use them in our component to show how it's going to work.


@Component(immediate = true)
public class OsgiTargetExampleConsumer {
 
 // Osgi target property for OsgiTargetIntegerImpl
 @Reference(target = "(osgi.target.example.integer=true)")
 OsgiTarget osgiTargetInteger;
 
 // Osgi target property for OsgiTargetIntegerImpl with another property but same instance 
 @Reference(target = "(osgi.target.example.integer.again=true)")
 OsgiTarget osgiTargetIntegerAgain;
 
 // Osgi target property for OsgiTargetDoubleImpl
 @Reference(target = "(osgi.target.example.double=true)")
 OsgiTarget osgiTargetDouble;

 
 @Activate
 public void run() {
  System.out.println("__________________" + osgiTargetInteger.convert("21"));
  System.out.println("__________________");
  System.out.println("__________________" + osgiTargetInteger.convert("12"));
  System.out.println("__________________");
  System.out.println("__________________" + osgiTargetDouble.convert("1987"));
 }
}


In the above class we are using the interface with @Reference annotation to get the object from SCR with respective classes just by adding target . If you look closely, you can see one class can be invoked by multiple properties as well.

Output will be similar like this :



You are just done, Try & Enjoy the function.............:)