Hi, all. I'm trying to do some OSGi app using Declarative Services. I faced a problem. I tried to describe it as simple as I could, but it still turned out a big one. Please spend a minute to understand it. I really need help 'cause there is
very few examples avaliable in the net. Thanks in advance.
So here is my problem. I have an interface:
public interface Greeter {public void setName(String text);
public void greet();
}
And I have a class that implements it:
public class BaseGreeter implements Greeter {String name = null;
public void setName(String text) {
name = text;
}
public void greet() {
System.out.println("Hello, " + name);
}
public void activate() {greet();
}
}
Next I have two classes that extends this base class:
public class MorningGreeter extends BaseGreeter {public void greet() {
System.out.println("Good morning, " + name);
}
}
public class AfternoonGreeter extends BaseGreeter {public void greet() {
System.out.println("Good afternoon, " + name);
}
}
In this example everything is simple - all the difference between the classes is in one word. In reality I want to build some "black boxes" - classes that implement the same interface but provide cardinally different functionality.
So, the main idea is as follows. I want some other people to write some other Greeters (black boxes). These people should know nothing about OSGi - they just write a class that extends BaseGreeter and override the greet() method.
My main program does the following: it reads some xml-config file that looks something like this:
<config><greeter class="org.example.MorningGreeter" name="Ann"/>
<greeter class="org.example.MorningGreeter" name="Sue"/>
<greeter class="org.example.AfternoonGreeter" name="Ann"/>
<greeter class="org.example.AfternoonGreeter" name="John"/>
</config>
It gets the ConfigurationAdmin Service:
ConfigurationAdmin ca = ...
And then for every <greeter> entry it posts a new Configuration:
Configuration conf = ca.createFactoryConfiguration("example.greeterfactory");
Hashtable d = ... // construct a dictionary that contains two entries: "greeter.class" (= "class" atribute of <greeter>) and "greeter.name" (= "name" attribute of <greeter>)
conf.update(d);
My OSGI-INF directory contains the following files:
- basegreeter.xml
<component name="basegreeter" factory="example.greeterfactory"><implementation class="org.example.BaseGreeter"/>
<service><provide interface="org.example.Greeter"/>
</service>
</component>
- greeterfactory.xml
<component name="example.greeterfactory"><implementation class="org.example.GreeterFactory"/>
<service><provide interface="org.osgi.service.component.ComponentFactory"/>
</service>
</component>
The GreeterFactory class is here:
public class GreeterFactory implements ComponentFactory {public ComponentInstance newInstance(Dictionary properties) {// here I take "greeter.class" property from properties and use the ClassLoader.getSystemClassLoader().loadClass(class ID) to load and construct the appropriate class: Greeter g = new ...
g.setName((String)properties.get("greeter.name"));
return null; // the first problem - how do I Construct ComponentInstance?
}
}
So the lifecycle as I see it must be as follows:
- Main program posts a new Configuration
- Some OSGi service (I can't be sure how it is called, it's all mixed up in my head) activates calls the factory newInstance method with given Dictionary
- The factory constructs a Greeter with the given properties and returns it to OSGi service
- OSGi service activates the component (which causes a simple hello sentence to appear)
Now what really happens. Here is what "services" command shows:
Code:
{org.osgi.service.component.ComponentFactory}={component.factory=example.greeterfactory, component.name=basegreeter, service.id=28}
Registered by bundle: initial@reference:file:../workspace/org.example/ [4]
No bundles using service.
{org.osgi.service.component.ComponentFactory}={greeter.class=org.example.MorningGreeter, service.pid=example.greeterfactory-1212569841845-0, service.factoryPid=example.greeterfactory, component.name=example.greeterfactory, component.id=1, greeter.name=Ann, service.id=29}
Registered by bundle: initial@reference:file:../workspace/org.example/ [4]
No bundles using service.
We see that the factory is present (service.id=28). Next should be the greeter: it has all the properties it needs
BUT it is not a Greeter - it is another GreeterFactory. I checked whether it is because I return null from newInstance and found out that newInstance is never called. I understand that I mixed something up, but can't figure out what it is

Thanks for reading this up to the end anyway. And if you could help me or if you know anyone who can - I would be very-very grateful. Thank you