OSGi 声明性服务 - NullPointer 异常

发布于 2024-11-10 11:59:33 字数 3940 浏览 4 评论 0原文

我的声明式服务有问题。我有 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 控制台上编写服务,则会部署服务。然后,我的结论是错误是由于注入不执行造成的。

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

预先非常感谢!

美好的一天

编辑:

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

我还调试了应用程序以查看是否调用了绑定和/或取消绑定方法,但它们没有。

完整的类是:

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>

如果部署了服务,为什么没有注入服务???

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

Why isn't the service injected if the service is deployed???

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

莫言歌 2024-11-17 11:59:33

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

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

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.
鹤仙姿 2024-11-17 11:59:33

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

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

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文