0

I have a very simple example of declarative services. I'm following this tutorial http://www.eclipsezone.com/eclipse/forums/t97690.html?start=0. Every thing is working as expected. However, I cannot figure out how I can make the "SampleImporter" (which is the bundle that is expected to use other bundles' services) aware of the list of "SampleExporter" (bundle providing a service). In other words, I want the "SamlpeImporter" to see the ID of the bundle(s) that it is eventually using. This information is very useful for my application.

here is the XML file for SampleExporter:

<?xml version="1.0"?>
<component name="samplerunnable">
<implementation class="org.example.ds.SampleRunnable"/>
<property name="ID" value="expoter" />
<service>
<provide interface="java.lang.Runnable"/>
</service>

while for the SampleImporter:

<?xml version="1.0"?>
<component name="commandprovider1">
<implementation class="org.example.ds.SampleCommandProvider1"/>
<service>
<provide interface="org.eclipse.osgi.framework.console.CommandProvider"/>
</service>
<reference name="RUNNABLE"
    interface="java.lang.Runnable"
    bind="setRunnable"
    unbind="unsetRunnable"
    cardinality="0..1"
    policy="dynamic"/>
</component>

In the Importer side, I have the following function:

public class SampleCommandProvider1 implements CommandProvider {
    private Runnable runnable;
public synchronized void setRunnable(Runnable r) {
    runnable = r;
}
public synchronized void unsetRunnable(Runnable r) {
    runnable = null;
}
public synchronized void _run(CommandInterpreter ci) {
    if(runnable != null) {
            runnable.run();
    } else {
        ci.println("Error, no Runnable available");
    }
}
public String getHelp() {
    return "\trun - execute a Runnable service";
}

}

This works fine but then if I want to get the value of the property, using

public synchronized void setRunnable(Runnable r, Map properties)

or

public synchronized void setRunnable(Runnable r, ServiceReference reference)

the method run of the exporter is never called which means that the bind function (setRunnable is not called).Hwever, using the console command "services" I see that the exporter bundle is used by the imporeter one. Also, using ss and ls I can see that the component eporter is "satisfied". What is wrong with my implementetion?

Thanks in advance

Cheers

Marie

mimou
  • 81
  • 1
  • 6
  • 1
    I would suggest that you add at least your declarative services XML. It is not very convenient to go read an article just to figure out what your question is. Otherwise, if you specify that you want to receive `ServiceReference` instead of the service objects directly, you can use the `ServiceReference.getBundle()` method to retrieve the bundle, which registered the service. – Danail Nachev Oct 06 '11 at 08:53
  • Thanks for the quick reply. And sorry for the misleading initial question. I have edited my question and tried to be as clear as possible. I guess my probelm is not that complicated but I'm mising some points since I'm newbie. I would really appreciate any help or hint. – mimou Oct 06 '11 at 14:56
  • The problem is that your method sigurnature is unsupported. According to the specification, the following signatures are supported: `void (ServiceReference);`,`void ();`,`void (, Map)` – Danail Nachev Oct 06 '11 at 19:14
  • Danail is correct, though these extended signatures are only available in DS 1.1, which further requires adding the 1.1 namespace to the XML document. See my answer below for details. – Neil Bartlett Oct 07 '11 at 06:29

1 Answers1

2

The following bind signature is not supported by any version of DS:

public void setRunnable(Runnable r, ServiceReference ref)

Instead you will have to take only the ServiceReference and use either the ComponentContext or BundleContext to access the service instance object.

Alternatively if you want a more POJO-style way of accessing service properties, the following bind signature is allowed in DS 1.1 (but not in DS 1.0):

public void setRunnable(Runnable r, Map properties)

To access DS 1.1 features, you need to add the correct namespace to your XML as follows:

<component xmlns='http://www.osgi.org/xmlns/scr/v1.1.0' name='...'>

By the way, I wrote this original article a very long time ago! These days I would use bnd annotations to avoid having to write the XML document by hand.

Neil Bartlett
  • 23,743
  • 4
  • 44
  • 77