Willy Pt Willy Pt - 11 days ago 7
Java Question

Inject EJB in @serverEndpoint class results in NullPointerException

I'm using Swarm Wildfly to deploy this application.
Basically I'm making a websocket enabled application.

I'd like to inject a singleton which will be started on the startup which modify the variable result.

Upon accessing the "/rafflethis" link, user will be able to see the result which will be sent via session.

The result is that the

roll
variable null

This is the class

@Singleton
@Startup
@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
public class runMe implements RaffleManager{
private static final Logger LOGGER = Logger.getLogger(runMe.class.getName());

private static String result;

@PostConstruct
public void onStartup() {
System.out.println("Initialization success.");
}

@Schedule(second = "*/10", minute = "*", hour = "*", persistent = false)
public void run() throws Exception{
int i = 0;
while (true) {
Thread.sleep(1000L);
result = UUID.randomUUID().toString().toUpperCase();
i++;
LOGGER.log(Level.INFO, "i : " + i);
}
}

public String getResult() {
return result;
}
}


interface

public interface RaffleManager {
String getResult();
}


And the "/rafflethis"

@ServerEndpoint("/rafflethis")
public class RaffleThis implements Serializable {
@EJB
RaffleManager roll;

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

private static void sendMessageToAll(String message) {
for (Session s : sessions) {
try {
s.getBasicRemote().sendText(message);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}

@OnOpen
public void monitorLuckyDip(Session session) throws Exception {
sessions.add(session);
while(true) {
sendMessageToAll(roll.getResult());
}
}
}


Any lead where should I head from this? Thanks!

Answer

The solution is rather hacky but a very simple one indeed. Take a look at the provided diagram.

Logic

And here's the code

Logic Implementation:

@Startup
@Singleton
public class RunMe{
  private static final Logger LOGGER = Logger.getLogger(RunMe.class.getName());


  @Inject
  MessageDTO messageDTO;


  @PostConstruct
  public void onStartup() {
    System.out.println("Initialization success.");
  }

  @Schedule(second = "*/10", minute = "*", hour = "*", persistent = false)
  public void run() throws Exception{
    //You can also substitute this method with constructor of the class -- removing the @Schedule annotation.
    int i = 0;
    while (true) {
      Thread.sleep(1000L);
      messageDTO.setText(UUID.randomUUID().toString().toUpperCase());
      i++;
      LOGGER.log(Level.INFO, "i : " + i);
    }
  }
}

MessageDTO:

@Singleton
public class MessageDTO {
  private static String text;

  public static String getText() {
    return text;
  }

  public static void setText(String text) {
    MessageDTO.text = text;
  }
}

Websocket Implementation:

@ServerEndpoint("/rafflethis")
public class RaffleThis implements Serializable {

  private static final Logger LOGGER = Logger.getLogger(RaffleThis.class.getName());
  private static final Set<Session> sessions = Collections.synchronizedSet(new HashSet<Session>());
  @Inject
  MessageDTO messageDTO;

  private static void sendMessageToAll(String message) {
    for (Session s : sessions) {
      try {
        s.getBasicRemote().sendText(message);
      } catch (IOException ex) {
        ex.printStackTrace();
      }
    }
  }

  @OnOpen
  public void monitorLuckyDip(Session session) throws Exception {
    sessions.add(session);
    while (true) {
      Thread.sleep(200);
      sendMessageToAll(messageDTO.getText());
    }
  }
}
Comments