类成员在osgi绑定方法之后返回null

时间:2012-10-22 10:48:51

标签: service reference osgi declarative

我的问题是在主类中我有一些osgi引用,在调用类时工作得很好。但之后所有引用都变为null。当我关闭主窗口并调用shutdown方法时,hubService引用返回null。我在这做错了什么?

private void shutdown() {
if(hubService == null) {
    throw new NullPointerException();
}
hubService.shutdownHub(); // why is hubService null?
}

// bind hub service
public synchronized void setHubService(IHubService service) {
hubService = service;
try {
    hubService.startHub(PORT, authenticationHandler);
} catch (Exception e) {
    JOptionPane.showMessageDialog(mainFrame, e.toString(), "Server", JOptionPane.ERROR_MESSAGE);
    System.exit(0);
}
} 

// remove hub service
public synchronized void unsetHubService(IHubService service) {
hubService.shutdownHub();
hubService = null;
}

2 个答案:

答案 0 :(得分:0)

如果一个字段可以被多个线程读取和写入,则必须保护读取和写入的访问权限。您的第一个方法shutdown不保护hubService的读取,以便hubService的值可以在第一次读取和第二次读取之间更改。您不显示hubService字段的声明。您可以将其设置为volatile或仅在同步时读取(在写入字段时用于同步的同一对象)。然后您的关闭实现可能如下所示:

private volatile IHubService hubService;
private void shutdown() {
    IHubService service = hubService; // make a copy of the field in a local variable
    if (service != null) // use local var from now on since the field could have changed
        service.shutdownHub();
}

答案 1 :(得分:0)

我假设您的关机方法是DS停用方法?如果是这样,为什么在关闭方法中也会关闭unset方法?

整体而言,设计似乎不太合理。 IHubService用作工厂,应该返回一些在deactivate方法中关闭的对象。您使IHubService有效地成为单身人士。因为它必须来自另一个束,它应该自己处理它的生命周期。

由于您也不使用注释,因此不清楚您的set / unset方法是静态/动态和/或单个/多个。以下代码不应该有您的问题(带有bnd注释的例程代码):

@Component public class MyImpl {
    IHubService hub;

    @Activate
    void activate() {
      hubService.startHub(PORT, authenticationHandler);
    }

    @DeActivate
    void deactivate() {
      hubService.shutdown();
    }

    @Reference
    void setHub(IHubService hub) { this.hub = hub; }
 }