OSGi Declarative Services - NullPointer Exception
I have a problem with my Declarative Services. I have 2 bundles, one is a server provider and another the user interface that consumes the service.
On server side, the implementation is:
public boolean checkUser(){
return true;
}
And the XML file inside OSGi-INF folder:
<component name="ZBService">
<implementation class="service.ZBService" />
<service>
<provide interface="service.IZBService" />
</service>
</component>
On client side, the implementation is:
public class GreetingServiceImpl extends RemoteServiceServlet implements GreetingService{
IZBService zb;
public void setZBService(IZBService eventAdmin) {
this.zb = eventAdmin;
}
public void unsetZBService(IZBService eventAdmin){
if(this.zb == eventAdmin){
this.zb = null;}
}
public boolean greetServer(String input, String input2) throws Exception {
return zb.checkUser();
}
}
And XML file:
<component name="ZBService">
<implementation class="main.java.com.gwt.app.server.GreetingServiceImpl" />
<service>
<provide interface="main.java.com.gwt.app.client.GreetingService"/>
</service>
<reference name="zb" interface="service.IZBService" bind="setZBService" unbind="unsetZBService" cardinality="0..n" policy="dynamic" />
</component>
Also, I have included the tag Service-Component on manifest file and I have deployed the equinox ds bundle that is ACTIVE.
The client is a GWT user interface, then I inject the service reference into server side of GWT. Well, when I deploy the application on Equinox it runs, but when I push the button, I launch an event to call ZBService. I have debugged the application and the error is zb attribute is null. It is to say, the dependence is nos injected. However the services are exposed on Equinox. If I write services on Equinox console, the services are deployed. Then, my conclusion is the error is due to the injection does not perform.
I would like to know if someone knows what is the reason??
Thanks a lot in advance!!
Nice day
EDIT:
I did your suggestions but it doesn't run. I change the component names and condinality/policy. The result is the same --> NullPointerException due to the injection isn't done.
Also I have debug the application to see if the methods bind and/or unbind are called, but they aren't.
The complete class is:
public class GreetingServiceImpl extends RemoteServiceServlet implements GreetingService{
static protected IZBService zb;
public GreetingServiceImpl(){
System.out.println("Constructor GreetingServiceImpl");
}
public IZBService getZb() {
return zb;
}
public void setZb(IZBService zb) {
GreetingServiceImpl.zb = zb;
}
public void unsetZb(IZBService zb) {
GreetingServiceImpl.zb = zb;
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// Cache the current thread
Thread currentThread = Thread.currentThread();
// We are going to swap the class loader
ClassLoader oldContextClassLoader = currentThread.getContextClassLoader();
currentThread.setContextClassLoader(this.getClass().getClassLoader());
super.service(req, resp);
currentThread.setContextClassLoader(oldContextClassLoader);
}
public void activate(ComponentContext context) {
System.out.println("Creating new greeter for " + context.getProperties().get("name")
+ ": " + context.getComponentInstance().toString());
}
public void activate() {
System.out.println("Activando la referencia al servicio");
}
public void deactivate(ComponentContext context) {
System.out.println("Deactivating greeter for " + context.getProperties().get("name")
+ ": " + context.getComponentInstance().toString());
}
public boolean greetServer(String input, String input2) throws Exception {
return zb.checkUser();
}
}
And the XML client is:
<?xml version="1.0" encoding="UTF-8" ?>
<scr:component name="serviceZB" xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0">
<implementation class="main.j开发者_JAVA百科ava.com.gwt.app.server.GreetingServiceImpl" />
<!-- <service>
<provide interface="main.java.com.gwt.app.client.GreetingService"/>
</service> -->
<reference name="zb" interface="service.IZBService"
bind="setZb" unbind="unsetZb" cardinality="1..1"
policy="static" />
</scr:component>
Why isn't the service injected if the service is deployed???
Here is a list of things you can try:
- First, remove the "static" of zb, that could be the problem.
- If you are using Equinox, add the -Dequinox.ds.print=true flag to the VM arguments and see more information about parsing XMLs and so
- Of course, add sysouts to setZB and unsetZB :)
- Remember that IZBService implementation needs a constructor without arguments
- If you are using Equinox use the "list -c" command to obtain information of each component (it's cool because says exactly why a component is not registered).
- Set the "inmediate=true" in XMLs to force to inmediatly activation.
You have both components with the same name, , which is kind of awkward when discussing them.
The reference on the client side has: cardinality="0..n" policy="dynamic". Which means it can be activated with zero to n references. Yet your code does not handle this. It seems to expect exactly one reference. Perhaps you should use cardinality="1..1" policy="static".
精彩评论