【问题标题】:OSGi Declarative Services - NullPointer ExceptionOSGi 声明式服务 - NullPointer 异常
【发布时间】:2011-09-03 07:12:52
【问题描述】:

我的声明式服务有问题。我有 2 个捆绑包,一个是服务器提供程序,另一个是使用服务的用户界面。

在服务器端,实现是:

public boolean checkUser(){
    return true;
}

以及 OSGi-INF 文件夹中的 XML 文件:

<component name="ZBService">
<implementation class="service.ZBService" />
   <service>
     <provide interface="service.IZBService" />
   </service>
</component>

在客户端,实现是:

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();
   }
}

还有XML文件:

<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>

另外,我已经在清单文件中包含了标签 Service-Component,并且我已经部署了处于活动状态的 equinox ds 捆绑包。

客户端是一个 GWT 用户界面,然后我将服务引用注入 GWT 的服务器端。好吧,当我在 Equinox 上部署应用程序时,它会运行,但是当我按下按钮时,我会启动一个事件来调用 ZBService。我已经调试了应用程序,错误是 zb 属性为空。也就是说,没有注入依赖。但是,这些服务在 Equinox 上公开。如果我在 Equinox 控制台上编写服务,则会部署服务。然后,我的结论是错误是由于注入没有执行。

我想知道是否有人知道是什么原因??

提前非常感谢!!

美好的一天

编辑:

我做了你的建议,但它没有运行。我更改了组件名称和 condinality/policy。结果是一样的 --> NullPointerException 由于注入没有完成。

我还调试了应用程序以查看方法 bind 和/或 unbind 是否被调用,但它们不是。

完整的类是:

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();
}
}

XML 客户端是:

<?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.java.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>

部署了服务为什么不注入服务???

【问题讨论】:

  • 你终于解决了这个问题吗?我目前面临同样的问题,并使用静态变量解决了它,但这不适用于“一个服务实例/servlet 实例”的要求

标签: osgi declarative-services


【解决方案1】:

以下是您可以尝试的列表:

  • 首先,删除 zb 的“静态”,这可能是问题所在。
  • 如果您使用的是 Equinox,请将 -Dequinox.ds.print=true 标志添加到 VM 参数中,并查看有关解析 XML 等的更多信息
  • 当然,将 sysouts 添加到 setZB 和 unsetZB :)
  • 请记住,IZBService 实现需要一个不带参数的构造函数
  • 如果您使用的是 Equinox,请使用“list -c”命令获取每个组件的信息(这很酷,因为它准确地说明了组件未注册的原因)。
  • 在 XML 中设置“inmediate=true”以强制立即激活。

【讨论】:

    【解决方案2】:

    两个组件的名称相同,讨论它们时有点尴尬。

    客户端的引用有:cardinality="0..n" policy="dynamic"。这意味着它可以通过零到 n 个引用来激活。但是您的代码无法处理此问题。它似乎只期望一个参考。也许您应该使用 cardinality="1..1" policy="static"。

    【讨论】:

    • 我做了你的建议,但它没有运行。我更改了组件名称和 condinality/policy。结果是一样的 --> NullPointerException 由于注入没有完成。
    猜你喜欢
    • 1970-01-01
    • 2012-04-27
    • 2013-10-09
    • 2018-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-14
    • 1970-01-01
    相关资源
    最近更新 更多