通过JCA适配器侦听的EJB MDB启动失败

时间:2018-10-05 23:39:13

标签: java ejb jca

我正在编写此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 :(得分:0)

您违反了编程限制(请参阅EJB规范16.2.2):

  

企业bean一定不能使用读/写静态字段。允许使用只读静态字段。因此,建议将企业bean类中的所有静态字段都声明为final。

删除您的(非最终)静态字段,静态初始化程序和构造函数。初始化是在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。可能无法以适当的方式实现。