Estou tentando usar o cometa como um servlet para dropwizard, mas o BayeuxServer não parece ter sido injetado no meu serviço. Estou adicionando meus dois servlets dessa forma (observe, não estou usando web.xml
então eu mesmo estou definindo os parâmetros):
cometdConfig.put("services", MyService.class.getCanonicalName());
System.out.print("OrderService name: " + MyService.class.getCanonicalName());
environment.addServlet(AnnotationCometdServlet.class, "/cometd/*").addInitParams(cometdConfig).setInitOrder(1);
environment.addServlet(new MyServiceServlet(), "/orders/*").setInitOrder(2);
E meu serviço (é aqui que meu código falha):
public class MyService
implements MyWatcher.Listener
{
@Inject
private BayeuxServer bayeuxServer;
@Session
private LocalSession sender;
private final String _channelName;
private ServerChannel _channel = null;
public OrderService() {
_channelName = "/cometd/";
initChannel();
}
private void initChannel() {
// I get an NPE here
bayeuxServer.createIfAbsent(_channelName, new ConfigurableServerChannel.Initializer() {
@Override
public void configureChannel(ConfigurableServerChannel channel) {
// ...
}
});
_channel = bayeuxServer.getChannel(_channelName);
}
}
Também tentei criar minha própria instância do BayeuxServer, mas isso levou a um NPE separado em BayeuxServerImpl.freeze();
Alguém sabe como usar corretamente o cometa com dropwizard?
Respostas:
3 para resposta № 1Para injetar o BayeuxServer
instância, o CometD deve ter a instância do serviço para injetar, neste caso, uma instância da sua classe MyService
.
Infelizmente, do construtor (que eu acho que você deu um nome errado acima, chamando-o OrderService
) você está chamando o initChannel()
método, que tenta usar o BayeuxServer
campo que ainda não foi injetado porque o construtor ainda está em execução.
A solução é adiar a inicialização do canal para um método diferente anotado com @PostConstruct
:
public class MyService
{
@Inject
private BayeuxServer bayeuxServer;
@Session
private LocalSession sender;
private final String _channelName;
private ServerChannel _channel;
public MyService()
{
_channelName = "/cometd/";
}
@PostConstruct
private void initChannel()
{
_channel = bayeuxServer.createChannelIfAbsent(_channelName).getReference();
}
}
A API do CometD usada é do CometD 2.7.0, que eu recomendo usar se você estiver em versões anteriores do CometD.