在@serverEndpoint类中注入EJB会导致NullPointerException

时间:2015-11-26 04:23:17

标签: java weld

我正在使用Swarm Wildfly来部署此应用程序。 基本上我正在创建一个支持websocket的应用程序。

我想注入一个将在启动时启动的单例,修改变量结果。

访问“/ rafflethis”链接后,用户将能够看到将通过会话发送的结果。

结果是 public void createEntry(String user, String name, String[] groups) throws XMPPException { // Create and send roster entry creation packet. RosterPacket rosterPacket = new RosterPacket(); rosterPacket.setType(IQ.Type.SET); RosterPacket.Item item = new RosterPacket.Item(user, name); if (groups != null) { for (String group : groups) { if (group != null) { item.addGroupName(group); } } } rosterPacket.addRosterItem(item); // Wait up to a certain number of seconds for a reply from the server. PacketCollector collector = connection.createPacketCollector( new PacketIDFilter(rosterPacket.getPacketID())); connection.sendPacket(rosterPacket); IQ response = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout()); collector.cancel(); if (response == null) { throw new XMPPException("No response from the server."); } // If the server replied with an error, throw an exception. else if (response.getType() == IQ.Type.ERROR) { throw new XMPPException(response.getError()); } // Create a presence subscription packet and send. Presence presencePacket = new Presence(Presence.Type.subscribe); presencePacket.setTo(user); connection.sendPacket(presencePacket); } 变量 null

这是班级

roll

接口

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

和“/ rafflethis”

public interface RaffleManager {
  String getResult();
}

我应该从哪里领先?谢谢!

2 个答案:

答案 0 :(得分:1)

查看来源,我可能会假设名称问题。 你的单身豆" runMe"是bean的实际名称而不是接口。

SIDE NOTE:类名的最佳做法是将第一个字母大写。 RunMe而不是runMe。

@Singleton - 不带参数会自动命名bean,以便使用类名中的bean约定进行查找。想象一下,如果你实现多个接口,EJB如何选择名称?因此,使用类名是合乎逻辑的。例如。如果您的类名是TestMe,则ejb名称将为testMe。

在您的情况下,因为您的类名是runMe,我认为bean名称将是runMe。

为确保查找不会失败,您可以在@Singleton和@EJB中指定名称。

@Singleton(name = "runMe")
@Startup
@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
public class runMe implements RaffleManager{

然后在您的服务端点类

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

答案 1 :(得分:0)

解决方案相当简陋但确实非常简单。看一下提供的图表。

Logic

这是代码

逻辑实施:

@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实施:

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