Using cometd in dropwizard

ⅰ亾dé卋堺 提交于 2019-12-13 04:29:57

问题


I'm trying to use cometd as a servlet to dropwizard but BayeuxServer doesn't seem to get injected in my service. I'm adding my two servlets as so (note, I'm not using web.xml so I'm defining the params myself):

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

And my service (this is where my code fails):

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

I have also tried creating my own instance of the BayeuxServer but then that leads to a separate NPE in BayeuxServerImpl.freeze();

Anyone know how to properly use cometd with dropwizard?


回答1:


In order to inject the BayeuxServer instance, CometD must have the instance of the service to inject to, in this case an instance of your class MyService.

Unfortunately, from the constructor (which I think you misnamed above, calling it OrderService) you are calling the initChannel() method, which tries to use the BayeuxServer field which is not yet injected because the constructor is still executing.

The solution is to defer your channel initialization to a different method annotated with @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();
    }
}

The CometD API used is from CometD 2.7.0, which I recommend to use if you are on older CometD versions.



来源:https://stackoverflow.com/questions/20154457/using-cometd-in-dropwizard

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!