I am trying to get bind/unbind methods called on a DS component. I've reduced it to the simplest example that doesn't work.
If I remove the @Reference on the bind method then the test is successful. Obviously the log statements don't get called. Otherwise it fails on the AssertNotNull.
Any suggestions on what I'm doing wrong? What is the right way to add bind/unbind methods to a component?
Updated code to show correct approach.
Interface
public interface Foo {
public abstract String bar();
}
Class
@Component(immediate = true, enabled = true, service = Foo.class, scope = ServiceScope.SINGLETON)
public class FooImpl implements Foo {
private final static Logger logger = LoggerFactory.getLogger(FooImpl.class);
@Override
public String bar() {
return "bar";
}
@Activate
public synchronized void bind() {
logger.debug(String.format("bind called for %s", this.getClass().getName()));
}
@Deactivate
public synchronized void unbind(Foo service) {
logger.debug(String.format("unbind called for %s", this.getClass().getName()));
}
}
Generated component definition
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.3.0" activate="bindFoo" deactivate="unbindFoo" enabled="true" immediate="true" name="com.vogelware.experiment.FooImpl">
<service scope="singleton">
<provide interface="com.vogelware.experiment.Foo"/>
</service>
<implementation class="com.vogelware.experiment.FooImpl"/>
</scr:component>
Test class
class FooTest {
@Test
void test() throws InterruptedException {
ServiceTracker<Foo, Foo> testTracker = new ServiceTracker<Foo, Foo>(Activator.getContext(), Foo.class, null);
testTracker.open();
testTracker.waitForService(500);
Foo user = testTracker.getService();
testTracker.close();
assertNotNull(user); <= fails here
}
}
The answer to my question is that in the 1.3 spec, use @Activate and @Deactivate. I've modified the original question to show the solution in code.
Check out http://blog.vogella.com/2016/06/21/getting-started-with-osgi-declarative-services/ for more details.