Hello fellow programmers,
I recently started working on an OSGi project. I was trying to get used to OSGi services using Declarative Services. I have created an inteface bundle (A), a bundle(B) implementing this interface and a bundle consuming the service(C). So far so good. But when I tried to create a bundle implementing another interface(D) I found out that I couldn't use the service provided by bundle (A).
So I have 4 bundles:
- Bundle A: API
- Bundle B: Bundle implements A
- Bundle D: implements E
- Bundle E: another api bundle
Why can't I consume service E from bundle B?
Bundle A
package liqueurplant.osgi.silo.driver.api;
import org.osgi.annotation.versioning.ProviderType;
@ProviderType
public interface SiloDriverIf {
void openDriver();
void closeDriver();
}
Bundle B
package liqueurplant.osgi.silo.driver;
import liqueurplant.osgi.silo.controller.api.SiloCtrlIf;
import liqueurplant.osgi.silo.driver.api.SiloDriverIf;
import org.osgi.service.component.annotations.*;
@Component
public class SimpleSiloDriver implements SiloDriverIf {
private SiloCtrlIf siloCtrl;
@Activate
public void activate() {
System.out.println("Driver activated.");
}
@Deactivate
public void deactivate() {
siloCtrl.put2EventQueue("High lever reached");
}
@Override
public void openDriver() {
}
@Override
public void closeDriver() {
}
@Reference(
name = "siloCtrl.service",
service = SiloCtrlIf.class,
/* Cardinality (Whether the bundle works with or without service.
// Mandatory: mandatory and unary 1..1
// At least one: mandatory and multiple 1..n
// Multiple: optional and multiple 0..n
// Optional: optional and unary 0..1
//*/
cardinality = ReferenceCardinality.MANDATORY,
policy = ReferencePolicy.DYNAMIC,
unbind = "unsetSiloCtrlIf"
)
protected void setSiloCtrlIf(SiloCtrlIf siloCtrl){
System.out.println("Binding silo controller service");
this.siloCtrl = siloCtrl;
}
protected void unsetSiloCtrlIf(SiloCtrlIf siloCtrl){
System.out.println("Unbinding silo controller service.");
this.siloCtrl = null;
}
}
Bundle D
package liqueurplant.osgi.silo.controller;
import liqueurplant.osgi.silo.controller.api.SiloCtrlIf;
import org.osgi.service.component.annotations.*;
import java.util.concurrent.ArrayBlockingQueue;
@Component
public class SimpleSiloCtrl implements SiloCtrlIf, Runnable {
private ArrayBlockingQueue<String> eventQueue;
public SimpleSiloCtrl() {
eventQueue = new ArrayBlockingQueue<String>(20);
}
@Activate
public void activate() {
System.out.println("Silo controller activated.");
}
@Override
public void put2EventQueue(String event) {
try {
eventQueue.put(event);
System.out.println(eventQueue.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while(true){
if(!eventQueue.isEmpty()){
try {
System.out.println(eventQueue.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
Bundle E
package liqueurplant.osgi.silo.controller.api;
import org.osgi.annotation.versioning.ProviderType;
@ProviderType
public interface SiloCtrlIf {
void put2EventQueue(String event);
}
When I try to run the code the @Activate methods on Bundle B are not working and the Service siloCtrl.service is not binding. Any help would be appreciated. Thank you in advance!