Jakarta ee 将@Singleton注入@ApplicationScoped会导致NullPointerException

Jakarta ee 将@Singleton注入@ApplicationScoped会导致NullPointerException,jakarta-ee,dependency-injection,glassfish,ejb,cdi,Jakarta Ee,Dependency Injection,Glassfish,Ejb,Cdi,我正在运行glassfish中的ear,使用EJB和WAR模块。EJB模块包含一个单例,用于管理到远程机器的连接,并在发生特定事件时使用JMS发送消息。WAR模块包含一个websocket服务器,用于截获JMS消息并将其发送到连接的浏览器。它工作得很好。 现在我引入了一个“启动”方法:当一个新的客户端连接时,我想向它发送机器列表,这样javascript就可以准备正确数量的div。为此,我在singleton bean中创建了一个方法,返回列表,并希望在新会话打开时调用它 这是EJB模块中的单例

我正在运行glassfish中的ear,使用EJB和WAR模块。EJB模块包含一个单例,用于管理到远程机器的连接,并在发生特定事件时使用JMS发送消息。WAR模块包含一个websocket服务器,用于截获JMS消息并将其发送到连接的浏览器。它工作得很好。 现在我引入了一个“启动”方法:当一个新的客户端连接时,我想向它发送机器列表,这样javascript就可以准备正确数量的div。为此,我在singleton bean中创建了一个方法,返回列表,并希望在新会话打开时调用它

这是EJB模块中的单例:

@Singleton
public class TServer implements ServerListener, TServerLocal {
  private HashMap<String, Servers> servers = new HashMap<>();

  @EJB
  private JMSQueueProducer jms;

  @Override
  public void connect(String hostname, String username, String password) {
    Server server = new Server(hostname, username, password);
    server.addListener(this);
  }

  private void onServerEvent(String host, String data) {
    this.jms.textMessage(host + " " + data);
  }

  [...]
}

@Local
public interface TServerLocal {

  public void connect(String hostname, String username, String password);
  public void disconnect(String hostname);
  public LinkedList<String> list();

}
这是WAR模块中的websocket服务器:

@ApplicationScoped
@ServerEndpoint("/websocket")
public class WebSocketServer {

  private static final Set<Session> sessions = Collections.synchronizedSet(new HashSet<Session>());

  @EJB
  private TServerLocal tServer;

  @OnOpen
  public void open(Session session) {
    sessions.add(session);
    LinkedList<String> servers = tServer.list();
  }

  [...]
}
@ApplicationScoped
@ServerEndpoint(“/websocket”)
公共类WebSocketServer{
私有静态最终集会话=Collections.synchronizedSet(newhashset());
@EJB
私有tServer本地tServer;
@奥诺彭
公开作废开放(会议){
添加(会话);
LinkedList servers=tServer.list();
}
[...]
}
如果我尝试启动会话,我会在tServer.list()上得到一个NullPointerException,这意味着tServer为null。
我尝试将@EJB更改为@Inject,但结果相同。我认为在CDI中调用EJB是完全合法的,我做错了什么?

您的@Singleton需要一个注释,因为它公开了除无接口视图之外的其他接口:

@LocalBean
@Singleton
public class TServer implements ServerListener, TServerLocal {
    ...
}

您需要在
@EJB
注释中提到
TServerLocal
bean的JNDI路径。有关更多信息,请参阅。我正在使用TServerLocal接口,带有本地注释,我认为这应该足够了。不管怎样,我试着放LocalBean,没有任何变化。阅读我在回答中链接的@LocalBean的javadoc。我已经阅读了,谢谢你的指针。无论如何,我已经添加了LocalBean注释,但没有任何更改。请显示您的Glassfish版本,并列出部署中的第三方JAR(因为它看起来像是GF之外的其他东西在试图管理您的WebSocketServer的生命周期)
@LocalBean
@Singleton
public class TServer implements ServerListener, TServerLocal {
    ...
}