1

Этот вопрос является ответвлением другого, который я опубликовал пару недель назад: log4j2 logging of code in EJB jar on JBoss EAP 7. В этой статье я поставил проблему и, в конечном итоге, решение для инициализации регистрации на EJB, развернутых как банки EJB (не EAR), на JBoss EAP 7 Server и вызвано из другого сервлета. Эти EJB вызывается через локальный интерфейс.@PostConstruct вызвал вызов Stateful EJB, но не без гражданства Почему?

Решение, которое я представил в этой ссылке, прекрасно работало для первого EJB, с которым я его попробовал, с помощью Stateful EJB. вызывается метод @ PostConstruct-annotated и инициализирует контекст ведения журнала, и все отлично работает.

Решение не выполнено на втором EJB, с которым я его попробовал. Этот EJB был без гражданства. Метод @PostConstruct никогда не вызывается, и первая попытка регистрации ведет к тому, что логгер имеет значение null. Единственное различие, которое я мог видеть между двумя фасолью, заключалось в том, что второй был без гражданства, тогда как первый был сдержанным. В качестве эксперимента я сделал второй из них состоятельным. Как только я это сделал, @PostConstruct был вызван, запись началась, и все было в порядке.

В соответствии с Oracle JavaEE6 tutorial, метод @PostConstruct должен быть вызван при создании экземпляра без объекта. Итак, почему создание экземпляра сеансового компонента bean @PostConstruct при создании экземпляра сессионного компонента без состояния, и что я могу сделать с ним?

Спасибо.

Обновление: добавление исходного кода.

-jar.xml EJB

<?xml version="1.0" encoding="UTF-8"?> 
<ejb-jar xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
     version="3.2" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/ejb-jar_3_2.xsd"> 
    <module-name>DealerLocatorBean</module-name> 
    <enterprise-beans> 
     <session> 
      <ejb-name>DealerLocatorBean</ejb-name> 
      <home>com.whatever.ServiceLogicHome</home> 
      <remote>com.whatever.ServiceLogic</remote> 
      <local-home>com.whatever.ServiceLogicLocalHome</local-home> 
      <local>com.whatever.ServiceLogicLocal</local> 
      <ejb-class>com.whatever.ejbs.DealerLocatorBean</ejb-class> 
      <session-type>Stateless</session-type> 
      <!-- <session-type>Stateful</session-type> No problem if this is made stateful--> 
      <transaction-type>Bean</transaction-type> 
     </session> 
    </enterprise-beans> 
</ejb-jar> 

DealerLocatorBean.java:

public class DealerLocatorBean implements SessionBean 
{ 

    private static final String LOGGER_CONFIG = "/path/to/log4j2.xml"; 
    private static final String LOGGER_CONTEXT_NAME = "VTDLLOC-EJB"; 
    private static LoggerContext logctx; 
    private static Logger logger = null; 

    public DealerLocatorBean() { 
     System.out.println("calling DealerLocatorBean() constructor"); 
    } 
    @PostConstruct 
    @TransactionAttribute(value=TransactionAttributeType.NOT_SUPPORTED) 
    private void postConstruct() { 
     System.out.println("DealerLocatorBean.postConstruct()"); 
     logctx = Configurator.initialize(LOGGER_CONTEXT_NAME, LOGGER_CONFIG); 
     logger = logctx.getLogger(getClass().getName()); 
     logger.log(Level.INFO, ("postConstruct() in DealerLocatorBean called")); 
     logger.log(Level.INFO, ("******END OF THE postConstruct() CALL******")); 
    } 

    @PreDestroy 
    @TransactionAttribute(value=TransactionAttributeType.NOT_SUPPORTED) 
    private void preDestroy() { 
     logger.log(Level.INFO, ("preDestroy() in DealerLocatorBean called. Shutting down logging.")); 
     Configurator.shutdown(logctx); 
    } 

Если компонент развертывается как с сохранением состояния (в EJB-jar.xml), @PostConstruct называется первым, когда компонент используется после развертывания, и все работает. DealerLocatorBean.postConstruct() видно на выходе, и все подзаголовки работают.

Если компонент разворачивается как апатрид (в ejb-jar.xml), @postConstruct никогда не вызывается. DealerLocatorBean.postConstruct() НЕ отображается на выходе. Ведение журнала не инициализируется, и результаты NullPointerException приводятся, как только код пытается зарегистрировать что-то через регистратор.

+0

Я не использую EAP, но со всеми сообществами JBOSS сообщества EE6 и EE7, которые я работал «@PostConstruct», работает безупречно, и это должно быть в случае версий EAP, которые должны быть более стабильными. Поиск журналов для исключения Runtime, которое в конечном итоге произошло во время «@PostConstruct» конкретного SLSB. – garfield

+0

Спасибо, но я не думаю, что это может быть причиной. Я добавил оператор System.out.println в качестве первой строки метода @PostConstruct и не появляется в server.log, когда компонент не имеет статуса (указывает на отсутствие вызова метода) и появляется, когда компонент bean сделан с сохранением состояния , В обоих случаях не происходит превышения времени выполнения. –

+0

Возможно, вам стоит публиковать код для конкретного SLSB. – garfield

ответ

0

Вы видели, как этот боб сообщается в журналы, которые были развернуты? Также в SLSB не допускается окончательная статика. Я бы предложил изменить частный статический LoggerContext logctx; для частного статического конечного LoggerContext logctx = Configurator.initialize (LOGGER_CONTEXT_NAME, LOGGER_CONFIG); если это возможно, и то же самое для регистратора и удалить соответствующие заявления из @PostConstruct или просто удалить статическое ключевое слово в объявлениях logctx и logger.