1

我的问题是,在主类中,我有一些 osgi 引用在调用类时工作得很好。但在那之后,所有的引用都变成了空值。当我关闭主窗口并调用关闭方法时, 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;
}
4

2 回答 2

0

我假设您的关闭方法是 DS 停用方法?如果是这样,您为什么要在 unset 方法中以及在 shutdown 方法中关闭?

总体而言,该设计似乎不是很健全。IHubService 用作工厂,应该返回一些对象,然后在 deactivate 方法中关闭该对象。您使 IHubService 有效地成为单例。因为它必须来自另一个包,它应该自己处理它的生命周期。

由于您也不使用注释,因此不清楚您的设置/取消设置方法是静态/动态和/或单个/多个。以下代码不应该有您的问题(带有 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; }
 }
于 2012-10-23T14:43:51.090 回答
0

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

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();
}
于 2012-10-22T15:50:08.267 回答