2013-11-22 4 views
0

Я пытаюсь использовать cometd в качестве сервлета для dropwizard, но BayeuxServer, похоже, не вводится в мою службу. Я добавляю две мои сервлеты, как так (обратите внимание, что я не использую web.xml поэтому я Определяя Params себя):Использование cometd в dropwizard

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

и мое обслуживание (это где мой код не):

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

Я также попытался создать свой собственный экземпляр BayeuxServer, но затем, что приводит к отдельным NPE в BayeuxServerImpl.freeze();

Любой знает, как правильно использовать cometd с dropwizard?

+0

Не используйте 'Class.getCanonicalName()', поскольку я думаю, что он нарушит загрузку классов внутренних классов. Вместо этого используйте 'Class.getName()'. – sbordet

ответ

3

Для того, чтобы ввести экземпляр BayeuxServer, CometD должен иметь экземпляр службы для инъекции, в данном случае экземпляр вашего класса MyService.

К сожалению, из конструктора (который я думаю, что вы неверно названы выше, назвав его OrderService) вы вызываете initChannel() метод, который пытается использовать BayeuxServer поле, которое еще не впрыскивается, поскольку конструктор по-прежнему выполняется.

Решение отложить инициализацию канала на другой метод с аннотацией @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(); 
    } 
} 

CometD API используется из CometD 2.7.0, который я рекомендую использовать, если вы находитесь на более старых версиях CometD ,

+0

Спасибо, я попробовал использовать '@ PostConstruct', но я все еще получаю NPE. Когда я проверяю, 'bayeuxServer' по-прежнему является нулевым, хотя он теперь вызван позже. –

+0

Одна вещь, которую я поймал, что я пропустил, не аннотировал мое обслуживание с помощью '@ Service'. Я попробовал это снова без '@ PostConstruct', и он все еще не прошел, поэтому мне все равно понадобилось. Большое спасибо! –

Смежные вопросы