/ / Usando cometa no dropwizard - java, cometa, dropwizard

Usando o cometa no dropwizard - java, cometd, dropwizard

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 № 1

Para 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.