2013-11-13 3 views
5

У меня есть веб-проект с использованием Resteasy (который, в свою очередь, использует Weld), и его развертывают в Tomcat 7.0.22 (я помещаю конкретную версию здесь, если эта проблема относится именно к этой версии).Почему Свард говорит: «Инъекция в Слушатели не поддерживается» на Tomcat?

У меня есть контекста сервлета, который выглядит следующим образом:

@WebListener 
public class ApplicationInitialisationListener implements ServletContextListener { 
    // create a logger here   

    @Inject 
    HealthCheck healthCheck; 

    @Override 
    public void contextInitialized(ServletContextEvent event) { 
     if (healthCheck == null) { 
      log.error("healthCheck is null"); 
     } 
    } 

    @Override 
    public void contextDestroyed(ServletContextEvent servletContextEvent) { 
    } 
} 

После развертывания на сервере Tomcat healthCheck is null был зарегистрирован, и я также заметил эту строку в журнале:

<2013-11-13 13:27:40,191> <pack> INFO pool-2-thread-1 org.jboss.weld.environment.tomcat7.Tomcat7Container - Tomcat 7 detected, CDI injection will be available in Servlets and Filters. Injection into Listeners is not supported 

Вопрос 1 : почему инъекция CDI недоступна в Listeners?

Я посмотрел в этот answer, и он говорит Load on startup via @Startup. There is currently no equivalent to this in CDI.

Вопрос 2: это вопрос описано в вопросе 1 следствием этого?

Вопрос 3: Я использую org.jboss.weld.servlet:weld-servlet:1.2.0.Beta1. Есть ли какие-либо обновления по поддержке запуска в более поздних версиях?

Вопросы, относящиеся Я Посмотрел startup class in Weld

+0

Что касается вопроса 3:.? Обратите внимание, что сообщение говорит, что это не поддерживается _CDI_ т.е. КДИ спецификации Безразлично Это может быть добавлено к будущей версии и, следовательно, к любой версии Weld, которая реализует эту будущую версию CDI. – Thomas

+0

@Thomas CDI не относится к сервлетам, поэтому он не будет определять ничего, что связано с инъекцией в Java EE. Это функция сварки и JSR 299. –

+0

@SotiriosDelimanolis ah, да, вы правы. Συγνώμη :) – Thomas

ответ

1

Вот обходной путь я обнаружил, что может вводить CDI бобов при запуске приложения.

Требование проблемы можно резюмировать следующим образом:

  1. впрыснуть CDI боб при запуске приложения
  2. сделать что-то с боб

Решение очертание линии:

  1. Создайте WebListener, который вызывает BeanManager.fireEvent(new SomeDummyEvent())
  2. Создание боб ApplicationScoped, который реагирует на SomeDummyEvent и впрыскивает КДИ компонентов-

Пример кода:

@WebListener 
public class ApplicationInitialisationListener implements ServletContextListener { 
    private static final Logger LOG = Logger.getLogger(ApplicationInitialisationListener.class); 

    @Override 
    public void contextInitialized(ServletContextEvent event) { 
     BeanManager beanManager = lookUpBeanManager(); 
     if (beanManager != null) { 
      beanManager.fireEvent(new SomeDummyEvent()); 
      LOG.info("beanManager fired SomeDummyEvent."); 
     } else { 
      LOG.error("beanManager is null. Cannot fire startup event."); 
     } 
    } 

    @Override 
    public void contextDestroyed(ServletContextEvent servletContextEvent) { 
    } 

    public BeanManager lookUpBeanManager() { 
     try { 
      // See reference below about how I came up with this 
      InitialContext iniCtx = new InitialContext(); 
      BeanManager result = (BeanManager) iniCtx.lookup("java:comp/env/BeanManager"); 
      return result; 
     } catch (NamingException e) { 
      LOG.error("Could not construct BeanManager.", e); 
      return null; 
     } 
    } 

    public static class SomeDummyEvent implements Serializable { 
    } 
} 

@ApplicationScoped 
public class InitializationResourceBean { 

    private static final Logger LOG = Logger.getLogger(InitializationResourceBean.class); 

    @Inject 
    HealthCheck healthCheck; 

    public void listen(@Observes ApplicationInitialisationListener.SomeDummyEvent event) { 
    } 

    @PostConstruct 
    public void init() { 
     // Do something with healthCheck 
    } 

    @PreDestroy 
    public void destroy() { 
     // Do some other thing with healthCheck 
    } 
} 

Ссылки:

http://struberg.wordpress.com/tag/cdi/

0

Теперь все это очень легко сделать с помощью deltaspike модуля сервлетов

@ApplicationScoped 
public class InitializationResourceBean { 

@Inject 
HealthCheck healthCheck; 

    public void onCreate(@Observes @Initialized ServletContext context) { 
    //Do initialisation stuff here. 
    if(HealthCheck != null) { 
     ; 
    } 
    } 
    public void onDestroy(@Observes @Destroyed ServletContext context) { 
    System.out.println("Destroyed ServletContext: " + context.getServletContextName()); 
    } 

} 

http://deltaspike.apache.org/documentation/servlet.html

+1

Обратите внимание, что [ссылки только ответы] (http://meta.stackoverflow.com/tags/link- only-answers/info) обескуражены, SO ответы должны быть конечной точкой поиска, поскольку (vs. еще одна остановка ссылок, которые со временем становятся устаревшими). Пожалуйста, подумайте о добавлении отдельного резюме здесь, сохранив ссылку в качестве ссылки. – kleopatra

0

От: http://docs.jboss.org/weld/reference/latest-master/en-US/html/environments.html#_tomcat

«Tomcat 7 и 8 поддерживаются. Активация/дезактивация контекста и инъекция зависимостей в сервлетах и ​​фильтрах работают из коробки. Инъекция в Servlet слушателей работает на Tomcat 7.0.50 и новее «

Так может быть, вы можете обновить Tomcat

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

  • Нет связанных вопросов^_^