我正在编写此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.
}
}
答案 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。可能无法以适当的方式实现。