【问题标题】:JMS MQ Connection closed in JSF 2 SessionBeanJMS MQ 连接在 JSF 2 SessionBean 中关闭
【发布时间】:2013-11-02 17:10:07
【问题描述】:

我使用带有 MQ 系列的 Websphere Application Server 8 作为消息队列。

当我在“postConstruct”方法中打开会话bean 中的连接并在另一个方法中使用它时,它会关闭。我的代码是:

import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.jms.JMSException;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.TextMessage;

@ManagedBean
@SessionScoped
public class MQRequest implements Serializable {
    private static final long serialVersionUID = 1L;

    @Resource(name = "jms/wasmqtest/wasmqtest_QCF")
    private QueueConnectionFactory connectionFactory;

    @Resource(name = "jms/wasmqtest/Request_Q")
    private Queue requestQueue;

    private QueueConnection connection;

    private String text = "";

    public void sendMessage() {
        System.out.println("Connection in sendMessage: \n" + connection);
        TextMessage msg;
        try {
            QueueSession queueSession = connection.createQueueSession(false,
                    Session.AUTO_ACKNOWLEDGE);

            QueueSender sender = queueSession.createSender(requestQueue);
            msg = queueSession.createTextMessage(text);

            sender.send(msg);

            queueSession.close();
            sender.close();

        } catch (JMSException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        text = "";

    }

    @PostConstruct
    public void openConenction() {
        System.out.println("Open Connection");
        try {
            connection = connectionFactory.createQueueConnection();

            connection.start();
            System.out.println("Connection in OpenConnectioN: \n" + connection);
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }

    @PreDestroy
    public void closeConnection() {
        try {
            System.out.println("Closing Connection");
            connection.close();
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }

    public void setText(String text) {
        this.text = text;
    }

    public String getText() {
        return text;
    }
}

在 PostConstruct 方法中初始化连接:

[21.10.13 07:36:05:574 CEST] 00000025 SystemOut     O Connection in OpenConnectioN: 
com.ibm.ejs.jms.JMSQueueConnectionHandle@36c9b1a
    managed connection = com.ibm.ejs.jms.JMSManagedQueueConnection@3657e8b
    physical connection = com.ibm.mq.jms.MQXAQueueConnection@36618b6
    closed = false
    invalid = false
    restricted methods enabled = false
    open session handles = []
    temporary queues = []

但是在 sendMessage() 方法中它不是,我得到一个 ConnectionClosed 问题:

[21.10.13 07:36:12:493 CEST] 00000025 SystemOut     O Connection in sendMessage: 
com.ibm.ejs.jms.JMSQueueConnectionHandle@36c9b1a
    managed connection = null
    physical connection = null
    closed = true
    invalid = false
    restricted methods enabled = false
    open session handles = []
    temporary queues = []

21.10.13 07:36:12:461 CEST] 00000025 SystemErr     R 15 [WebContainer : 3] INFO org.apache.bval.jsr303.ConfigurationImpl - ignoreXmlConfiguration == true
[21.10.13 07:36:12:601 CEST] 00000025 SystemErr     R javax.jms.IllegalStateException: Connection closed
[21.10.13 07:36:12:601 CEST] 00000025 SystemErr     R   at com.ibm.ejs.jms.JMSConnectionHandle.checkOpen(JMSConnectionHandle.java:821)
[21.10.13 07:36:12:601 CEST] 00000025 SystemErr     R   at com.ibm.ejs.jms.JMSQueueConnectionHandle.createQueueSession(JMSQueueConnectionHandle.java:206)
[21.10.13 07:36:12:601 CEST] 00000025 SystemErr     R   at de.volkswagen.wasmqtest.queue.MQRequest.sendMessage(MQRequest.java:51)
[21.10.13 07:36:12:601 CEST] 00000025 SystemErr     R   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[21.10.13 07:36:12:601 CEST] 00000025 SystemErr     R   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
[21.10.13 07:36:12:601 CEST] 00000025 SystemErr     R   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
[21.10.13 07:36:12:602 CEST] 00000025 SystemErr     R   at java.lang.reflect.Method.invoke(Method.java:611)
[21.10.13 07:36:12:602 CEST] 00000025 SystemErr     R   at org.apache.el.parser.AstValue.invoke(AstValue.java:262)
[21.10.13 07:36:12:602 CEST] 00000025 SystemErr     R   at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:278)
[21.10.13 07:36:12:602 CEST] 00000025 SystemErr     R   at org.apache.myfaces.view.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:83)
[21.10.13 07:36:12:602 CEST] 00000025 SystemErr     R   at javax.faces.component._MethodExpressionToMethodBinding.invoke(_MethodExpressionToMethodBinding.java:88)
[21.10.13 07:36:12:602 CEST] 00000025 SystemErr     R   at org.apache.myfaces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:100)
[21.10.13 07:36:12:602 CEST] 00000025 SystemErr     R   at javax.faces.component.UICommand.broadcast(UICommand.java:120)
[21.10.13 07:36:12:602 CEST] 00000025 SystemErr     R   at javax.faces.component.UIViewRoot._broadcastAll(UIViewRoot.java:973)
[21.10.13 07:36:12:602 CEST] 00000025 SystemErr     R   at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:275)
[21.10.13 07:36:12:602 CEST] 00000025 SystemErr     R   at javax.faces.component.UIViewRoot._process(UIViewRoot.java:1285)
[21.10.13 07:36:12:602 CEST] 00000025 SystemErr     R   at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:711)
[21.10.13 07:36:12:602 CEST] 00000025 SystemErr     R   at org.apache.myfaces.lifecycle.InvokeApplicationExecutor.execute(InvokeApplicationExecutor.java:34)
[21.10.13 07:36:12:603 CEST] 00000025 SystemErr     R   at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:171)
[21.10.13 07:36:12:603 CEST] 00000025 SystemErr     R   at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
[21.10.13 07:36:12:603 CEST] 00000025 SystemErr     R   at javax.faces.webapp.FacesServlet.service(FacesServlet.java:189)
[21.10.13 07:36:12:603 CEST] 00000025 SystemErr     R   at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1147)
[21.10.13 07:36:12:603 CEST] 00000025 SystemErr     R   at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:722)
[21.10.13 07:36:12:603 CEST] 00000025 SystemErr     R   at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:449)
[21.10.13 07:36:12:603 CEST] 00000025 SystemErr     R   at com.ibm.ws.webcontainer.servlet.ServletWrapperImpl.handleRequest(ServletWrapperImpl.java:178)
[21.10.13 07:36:12:603 CEST] 00000025 SystemErr     R   at com.ibm.ws.webcontainer.filter.WebAppFilterManager.invokeFilters(WebAppFilterManager.java:1020)
[21.10.13 07:36:12:603 CEST] 00000025 SystemErr     R   at com.ibm.ws.webcontainer.webapp.WebApp.handleRequest(WebApp.java:3703)
[21.10.13 07:36:12:603 CEST] 00000025 SystemErr     R   at com.ibm.ws.webcontainer.webapp.WebGroup.handleRequest(WebGroup.java:304)
[21.10.13 07:36:12:603 CEST] 00000025 SystemErr     R   at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:953)
[21.10.13 07:36:12:603 CEST] 00000025 SystemErr     R   at com.ibm.ws.webcontainer.WSWebContainer.handleRequest(WSWebContainer.java:1655)
[21.10.13 07:36:12:603 CEST] 00000025 SystemErr     R   at com.ibm.ws.webcontainer.channel.WCChannelLink.ready(WCChannelLink.java:195)
[21.10.13 07:36:12:604 CEST] 00000025 SystemErr     R   at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:452)
[21.10.13 07:36:12:604 CEST] 00000025 SystemErr     R   at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleNewRequest(HttpInboundLink.java:511)
[21.10.13 07:36:12:604 CEST] 00000025 SystemErr     R   at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.processRequest(HttpInboundLink.java:305)
[21.10.13 07:36:12:604 CEST] 00000025 SystemErr     R   at com.ibm.ws.http.channel.inbound.impl.HttpICLReadCallback.complete(HttpICLReadCallback.java:83)
[21.10.13 07:36:12:604 CEST] 00000025 SystemErr     R   at com.ibm.ws.tcp.channel.impl.AioReadCompletionListener.futureCompleted(AioReadCompletionListener.java:165)
[21.10.13 07:36:12:604 CEST] 00000025 SystemErr     R   at com.ibm.io.async.AbstractAsyncFuture.invokeCallback(AbstractAsyncFuture.java:217)
[21.10.13 07:36:12:604 CEST] 00000025 SystemErr     R   at com.ibm.io.async.AsyncChannelFuture.fireCompletionActions(AsyncChannelFuture.java:161)
[21.10.13 07:36:12:604 CEST] 00000025 SystemErr     R   at com.ibm.io.async.AsyncFuture.completed(AsyncFuture.java:138)
[21.10.13 07:36:12:604 CEST] 00000025 SystemErr     R   at com.ibm.io.async.ResultHandler.complete(ResultHandler.java:204)
[21.10.13 07:36:12:604 CEST] 00000025 SystemErr     R   at com.ibm.io.async.ResultHandler.runEventProcessingLoop(ResultHandler.java:775)
[21.10.13 07:36:12:604 CEST] 00000025 SystemErr     R   at com.ibm.io.async.ResultHandler$2.run(ResultHandler.java:905)
[21.10.13 07:36:12:605 CEST] 00000025 SystemErr     R   at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1650)

您知道连接关闭的原因吗?

【问题讨论】:

  • 这段代码很奇怪。当拥有支持 EJB 的环境时,通常您在 EJB 中而不是在 JSF bean 中执行业务逻辑(包括 JMS)。无论如何...也许您正在阅读关于 WAS 中 JMS 的过时教程?无需始终保持 JMS 连接打开。 JMS 连接是池化的,您应该在方法本地范围内创建和关闭 JMS 连接,而不是将其分配为会话范围 bean 的属性。试一试。我不会将此作为答案发布,因为我无法从经验中判断,也无法在真实环境中测试这是否真的有效。
  • 感谢您的评论。我使用 JSF 是因为这个应用程序也可以在 tomcat 上运行。目前我在需要时打开和关闭方法中的每个连接 - 这工作正常。但这篇文章告诉我用另一种方式来做:stackoverflow.com/questions/19442196/…
  • 我不会听从它的建议。另请参阅www-01.ibm.com/support/docview.wss?uid=swg21267957“修改应用程序以在每次调用 EJB 时创建新的 JMS 连接。这是推荐的解决方案”。显然,回答者在回答时考虑了 WAS
  • 非常感谢。请写下您的评论作为答案。我想接受它。您也可以回复其他帖子。

标签: java jsf-2 jms mq


【解决方案1】:

根据this IBM technote,似乎从 WAS 6 开始,您应该在每个 MQ 会话的基础上打开和关闭连接。因为,当您关闭会话时,负责创建 MQ 会话的底层连接会隐式返回到池中。

技术说明(疑难解答)

问题(摘要)

您使用 JMS 从位于 WebSphere Application Server 的 EJB bean 中的 Java™ 应用程序访问 WebSphere MQ V6.0 队列。该应用程序已在 WebSphere Application Server V5 中运行多年且没有出现任何错误。您现在正尝试在 WebSphere Application Server V6 上运行完全相同的 Java 应用程序。

...

ffdc 日志中失败方法堆栈的相关部分显示:

javax.jms.IllegalStateException: Connection closed
    at com.ibm.ejs.jms.JMSConnectionHandle.checkOpen(JMSConnectionHandle.java:671) 
    at com.ibm.ejs.jms.JMSQueueConnectionHandle.createQueueSession(JMSQueueConnectionHandle.java:172)
    ... 

...

原因

genericPut 方法完成后,从池中检索到的连接句柄与应用程序分离并返回到 JMS 连接池...

...

解决问题

  1. 修改应用程序以在每次调用 EJB 时创建新的 JMS 连接。这是推荐的解决方案。

    由于应用服务器的连接池机制的工作方式,这不会对性能产生太大影响。

...

因此,在您的特定情况下,正确的方法如下。把try-finally 想像在 JDBC 中一样!您只需不需要以they are already implicitly closed on close of a connection 显式关闭会话/发送者:

public void sendMessage() throws JMSException {
    QueueConnection connection = null;

    try {
        connection = connectionFactory.createQueueConnection();
        QueueSession session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
        QueueSender sender = session.createSender(requestQueue);
        TextMessage message = session.createTextMessage(text);
        sender.send(message);
    } finally {
        if (connection != null) try {
            connection.close();
        } catch (JMSException e) {
            // Log or ignore.
        }
    }
}

【讨论】:

    猜你喜欢
    • 2010-11-24
    • 2013-10-26
    • 1970-01-01
    • 2011-08-17
    • 2023-03-05
    • 2015-07-08
    • 2014-09-19
    • 2017-02-03
    • 1970-01-01
    相关资源
    最近更新 更多