我正在使用带有 Glassfish 的 Java Enterprise (3.1)。我有两个单独的 EAR,它们通过 JMS 同步通信。进一步来说:
EAR1 使用 JMS 消息来告诉 EAR2 做什么。EAR1 开始侦听来自 EAR2 (QueueReceiver.receive) 的回答。EAR2 接收到消息并进行相应的处理,然后将 JMS 消息连同输出一起发送回 EAR1。
这一切都很好。直到我得到这个例外:
[#|2011-05-10T15:05:27.382+0200|WARNING|glassfish3.1|javax.enterprise.resource.resourceadapter.com.sun.enterprise.connectors|_ThreadID=90;_ThreadName=Thread-1;|RAR5117 : Failed to obtain/create connection from connection pool [ jms/QueueConnectionFactory ]. Reason : com.sun.appserv.connectors.internal.api.PoolingException: In-use connections equal max-pool-size and expired max-wait-time. Cannot allocate more connections.|#]
所以看起来容器没有重用 MDB。相反,它会创建新的,直到我达到极限。我知道这是因为 EAR2 中的 MDB 使用 JMS 发回结果。我的猜测是,MDB 实例中仍然分配了一些资源,这会导致这种行为。
如果我只是使用 MDB 打印收到的消息,我可以整天继续发送消息,所以它肯定与 JMS 连接有关。
我已经在这两天了,所以如果有人愿意提供一些帮助,将不胜感激。
此代码整天有效:
package xxx;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.MessageListener;
@MessageDriven(activationConfig = {
@ActivationConfigProperty(
propertyName="destinationType",
propertyValue="javax.jms.Queue")
}, mappedName = "AssociationQueue1")
public class AssociationMDB implements MessageListener {
@Override
public void onMessage(Message arg0) {
MapMessage msg = (MapMessage)arg0;
String source = null;
String target = null;
try {
source = msg.getString("source");
target = msg.getString("target");
} catch (JMSException e) {
e.printStackTrace();
}
System.out.println(source + " " + target);
}
}
虽然这个没有:
package xxx;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.MessageListener;
@MessageDriven(activationConfig = {
@ActivationConfigProperty(
propertyName="destinationType",
propertyValue="javax.jms.Queue")
}, mappedName = "AssociationQueue1")
public class AssociationMDB implements MessageListener {
@Override
public void onMessage(Message arg0) {
Logger logger = Logger.getLogger(this.getClass().getSimpleName());
QueueConnection qConnect = null;
QueueSession qSession = null;
QueueSender qSender = null;
try {
InitialContext context = new InitialContext();
Queue responseQ = (Queue)context.lookup("AssociationQueue2");
QueueConnectionFactory factory = (QueueConnectionFactory) context.lookup("jms/QueueConnectionFactory");
qConnect = factory.createQueueConnection();
qSession = qConnect.createQueueSession(false,Session.AUTO_ACKNOWLEDGE);
qConnect.start();
qSender = qSession.createSender(responseQ);
TextMessage answer = qSession.createTextMessage();
answer.setText("hey");
qSender.send(answer);
logger.info("message sent");
}
catch (JMSException jmse) {
jmse.printStackTrace();
} catch (NamingException e) {
e.printStackTrace();
}
finally {
try {
if(qSender != null) {
qSender.close();
logger.info("cleaning qSender");
}
if(qSession != null) {
qSession.close();
logger.info("cleaning qSession");
}
if(qConnect != null) {
qConnect.close();
logger.info("cleaning qConnect");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
(我也尝试过使用更新更花哨的 EJB 东西,比如符号等,但也没有用......)
塞巴斯蒂安