I add an OSGI-service MyService
to apache karaf roughly that way:
public interface MyService {//...}
@OsgiServiceProvider(classes=MyService .class)
@Singleton
public class MyServiceImpl implements MyService {//...}
blueprint-maven-plugin
and maven-bundle-plugin
to process anotations. A declaration of OSGi-service and its implementation results in bundle.jar!/OSGI-INF/blueprint/autowire.xml:<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0">
<bean id="myServiceImpl" class="com.foo.bar.MyServiceImpl"
ext:field-injection="true" init-method="init">
<property name="contextFactory" ref="initialContextFactory-"/>
</bean>
<service ref="myServiceImpl" interface="com.foo.bar.MyService"/>
</blueprint>
That XML is known to the bundle since it's in MANIFEST.MF:
Bundle-Blueprint: OSGI-INF/blueprint/autowire.xml
Now I would like to bind that service to a JNDI-name for compatibility reasons. I try to achieve that by implementing init()
in MyServiceImpl
and using a ServiceTracker
:
@PostConstruct
public void init() {
BundleContext context = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
ServiceTracker tracker = new ServiceTracker(context, this.getClass(), null) {
@Override
public Object addingService(ServiceReference reference) {
Object serviceObj = super.addingService(reference);
try {
Context c = new InitialContext();
bind(c, "java:global/com.foo.bar.bundle/MyServiceImpl!com.foo.bar.MyService", serviceObj );
}
catch (NamingException e) { e.printStackTrace(); }
return serviceObj;
}
};
tracker.open();
}
private void bind(Context ctx, String name, Object value) { //... }
Unfortunately I get a javax.naming.NotContextException
if I do a lookup:
new InitialContext().lookup("java:global/com.foo.bar.bundle/MyServiceImpl!com.foo.bar.MyService");
To investigate that I firstly checked if the bundle was started and the service was added in the karaf console:
karaf@root()> bundle:list | grep bundle
155 | Active | 80 | 0.0.1.SNAPSHOT | bundle
karaf@root()> bundle:services 155
bundle (155) provides:
----------------------
[com.foo.bar.MyService]
Then I restarted karaf with debug parameter and set a breakpoint into init()
and addedService()
. The observation showed: init()
gets called so the ServiceTracker
should be added to the bundle properly. But addingService()
doesn't get called.
What am I missing?
In the blueprint.xml you publish the service with its interface "com.foo.bar.MyService". So you need to use the same name in the service tracker lookup.
Btw. why do you use a ServiceTracker at all? If you publish the service from @PostConstruct of your impl then just publish the impl using:
Context c = new InitialContext();
bind(c, "java:global/com.foo.bar.bundle/MyServiceImpl!com.foo.bar.MyService", this );