EJB MDB прослушивает через адаптер JCA при запуске - PullRequest
0 голосов
/ 06 октября 2018

Я пишу этот MDB, который будет прослушивать сообщение об очередях IBM MQ, а onMessage будет вызывать ilrsession для запуска jrules.Адаптер JCA и конфигурация активации настроены на консоли WAS

При запуске этого MDB выдает следующую ошибку.Является ли это статическим блоком, из-за которого происходит сбой.

Я публикую здесь, если что-то может просмотреть код и дать некоторые предложения.

Вот исключение, которое я получаю при запуске MDB.

An operation in the enterprise bean constructor failed. It is recommended that component initialization logic be placed in a PostConstruct method instead of the bean class no-arg constructor.; nested exception is:
            java.lang.NullPointerException
            at com.ibm.ws.ejbcontainer.runtime.SharedEJBRuntimeImpl.startBean(SharedEJBRuntimeImpl.java:620)
            at com.ibm.ws.runtime.component.WASEJBRuntimeImpl.startBean(WASEJBRuntimeImpl.java:586)
            at com.ibm.ws.ejbcontainer.runtime.AbstractEJBRuntime.fireMetaDataCreatedAndStartBean(AbstractEJBRuntime.java:1715)
            at com.ibm.ws.ejbcontainer.runtime.AbstractEJBRuntime.startModule(AbstractEJBRuntime.java:667)
            ... 52 more
    Caused by: java.lang.NullPointerException

Вот код MDB.

package com.abc.integration.ejb

import ilog.rules.res.model.IlrPath;
import ilog.rules.res.session.IlrEJB3SessionFactory;
import ilog.rules.res.session.IlrSessionException;
import ilog.rules.res.session.IlrSessionRequest;
import ilog.rules.res.session.IlrSessionResponse;
import ilog.rules.res.session.IlrStatelessSession;

import java.net.URL;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;


/**
 * Message-Driven Bean implementation class for: DecisionServiceMDB
 * 
 */


@MessageDriven(activationConfig = { @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue") })
public class DecisionServiceMDB implements MessageListener
{
    /**
     * default serial version id
     */
    private static final long serialVersionUID = 2300836924029589692L;
    private static final Logger responseTimeLogger = Logger.getLogger(PropertyManager.getResponseTimeLogger());
    private static final Logger errorLogger = Logger.getLogger(PropertyManager.getErrorLogger());
    private static final Logger ruleExceptionLogger = Logger.getLogger(PropertyManager.getRuleExceptionLogger());


    private static final String RULEAPP_NAME = PropertyManager.getRuleAppName();
    private static final String RULESET_NAME = PropertyManager.getRuleSetName();

    private static InitialContext ic;
    private static ConnectionFactory cf;
    private static Destination destination;
    private static String qcfLookup = PropertyManager.getQueueFactoryJndiName();
    private static String qLookup = PropertyManager.getQueueDestinationJndiName();

    private Connection c = null;
    private Session s = null;
    private MessageProducer mp = null;

    private boolean isInitializedOkay = true;

    private static IlrEJB3SessionFactory factory;
    private static IlrStatelessSession ruleSession;
    private static IlrPath path;
    private IlrSessionRequest sessionRequest;

    static {
        URL url = Thread.currentThread().getContextClassLoader().getResource("log4j.xml");
        DOMConfigurator.configure(url);
        errorLogger.info("log4j xml initialized::::::::::::::::");
    }

    public DecisionServiceMDB() throws NamingException, JMSException
    {
        try
        {

            if (ic == null)
            {
                ic = new InitialContext();
            }
            if (cf == null)
            {
                cf = (ConnectionFactory) ic.lookup(qcfLookup);
            }
            if (destination == null)
            {
                destination = (Destination) ic.lookup(qLookup);
            }

        } catch (NamingException e)
        {
            isInitializedOkay = false;
            errorLogger.error("FATAL:NamingException Occurred: " + e.getMessage());
            errorLogger.error(e.getMessage(), e);
            e.printStackTrace();
            //throw e;
        }

        // 1. Get a POJO Session Factory
         if (factory == null)
        {
             //factory = new IlrJ2SESessionFactory();
            //to log rule execution start time by using bre logger
            //transactionLogger.setRuleExecutionStartTime(new Date());
            factory = new IlrEJB3SessionFactory();

            // As the EJBS are embedded within the ear file, we need to prepend
            // the ear file name to the JNDI.
            factory.setStatelessLocalJndiName("ejblocal:ilog.rules.res.session.ejb3.IlrStatelessSessionLocal");
        }

        // 2. Create a stateless rule session using this factory
        try
        {
            if (ruleSession == null)
            {
                ruleSession = factory.createStatelessSession();
            }
        } catch (Exception e)
        {
            e.printStackTrace();

            return;
        }

        // 3. Create a session request to invoke the RES (defining the ruleset
        // path and the input ruleset parameters)
        if (path == null)
        {
            path = new IlrPath(RULEAPP_NAME, RULESET_NAME);
        }

        sessionRequest = factory.createRequest();
        sessionRequest.setRulesetPath(path);
    }

   public void onMessage(Message receivedMsg)
   { 
  // onMessage code goes here. 
   }

}

1 Ответ

0 голосов
/ 09 октября 2018

Вы нарушаете ограничения программирования (см. Спецификацию EJB 16.2.2):

Корпоративный компонент не должен использовать статические поля для чтения / записи.Использование статических полей только для чтения разрешено.Поэтому рекомендуется объявлять все статические поля в классе корпоративного компонента как окончательные.

Удалите свои (не окончательные) статические поля, статический инициализатор и конструктор.Инициализация выполняется в методе обратного вызова жизненного цикла postConstruct.

Ваш EJB может выглядеть следующим образом:

@MessageDriven(activationConfig = { @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue") })
public class DecisionServiceMDB implements MessageListener
{

    private Logger responseTimeLogger;
    private Logger errorLogger;
    private Logger ruleExceptionLogger;

    private String RULEAPP_NAME;
    private String RULESET_NAME;

    private InitialContext ic;
    private ConnectionFactory cf;
    private Destination destination;
    private String qcfLookup;
    private String qLookup;

    private Connection c;
    private Session s;
    private MessageProducer mp;

    private boolean isInitializedOkay = true;

    private IlrEJB3SessionFactory factory;
    private IlrStatelessSession ruleSession;
    private IlrPath path;
    private IlrSessionRequest sessionRequest;

    @PostConstruct
    public void init() {
        responseTimeLogger = Logger.getLogger(PropertyManager.getResponseTimeLogger());
        errorLogger = Logger.getLogger(PropertyManager.getErrorLogger());
        ruleExceptionLogger = Logger.getLogger(PropertyManager.getRuleExceptionLogger());

        RULEAPP_NAME = PropertyManager.getRuleAppName();
        RULESET_NAME = PropertyManager.getRuleSetName();

        qcfLookup = PropertyManager.getQueueFactoryJndiName();
        qLookup = PropertyManager.getQueueDestinationJndiName();

        ic = new InitialContext();
        cf = (ConnectionFactory) ic.lookup(qcfLookup);
        destination = (Destination) ic.lookup(qLookup);

        factory = new IlrEJB3SessionFactory();
        factory.setStatelessLocalJndiName("ejblocal:ilog.rules.res.session.ejb3.IlrStatelessSessionLocal");

        ruleSession = factory.createStatelessSession();
        sessionRequest.setRulesetPath(path);
    }

    public void onMessage(Message receivedMsg)
    {
        // onMessage code goes here. 
    }

}

Я удалил статический инициализатор.Похоже, вы пытаетесь настроить ведение журнала, что не должно быть сделано в вашем EJB.Обратитесь к документации вашего сервера приложений, чтобы узнать, как это сделать правильно.

Это просто пример кода, основанного на исходном коде.

Предоставленная вами реализация выглядит как простая реализация Java.Помните о требованиях в корпоративной среде (например, жизненный цикл EJB, ответственность поставщиков EJB, ...).Прежде чем продолжить, прочитайте спецификацию EJB и некоторые учебные пособия по JEE.

Имея это в виду, впоследствии вам следует взглянуть на PropertyManager.Это может быть не реализовано подходящим способом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...