0
votes

I'm running an ear in glassfish, using EJB and WAR module. The EJB module contains a singleton that manages connections to remote machines and, in case of particular events, send a message using JMS. The WAR module contains a websocket server that intercept the JMS messages and send them to connected browser. It works perfectly. Now I'm introducing a "startup" method: when a new client connect I want to send it the list of the machines, so javascript can prepare the correct number of div. For doing it I have created a method in the singleton bean that return the list and I want to call it when the new session opens.

This is the singleton in the EJB module:

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

}

JMSQueueProducer is a stateless EJB used only for sending message to the JMS queue:

@Stateless
@LocalBean
public class JMSAsteriskQueueProducer {

  @Inject
  private JMSContext jmsContext;
  @Resource(mappedName = "jms/serverQueue")
  private Queue sQueue;

  public void textMessage(String message) {
    jmsContext.createProducer().send(sQueue, message);
  }
}

This is the websocket server in the WAR module:

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

  [...]
}

If I try to start a sessions I get a NullPointerException at tServer.list(), meaning that tServer is null. I've tried changing @EJB for @Inject with the same result. I think it's perfecly legal to call an EJB inside a CDI, what I'm doing wrong?

1
You need to mention, in your @EJB annotation, the JNDI path of your TServerLocal bean. Please refer to Glassfish docs for more info.António Ribeiro

1 Answers

0
votes

Your @Singleton requires an @LocalBean annotation because it is exposing other interfaces besides the no-interface view:

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