IBM Liberty迁移后启动首次发送MQ数据失败:会话已关闭
将应用从IBM WebSphere 8.5迁移至IBM Liberty Server 24后,应用连接IBM MQ收发数据时出现异常:启动后首次向MQ发送数据失败,后续发送均正常,报错信息如下:
com.ibm.msg.client.jms.DetailedIllegalStateException: MQJCA1020: The session is closed. at com.ibm.mq.connector.services.JCAExceptionBuilder.buildException(JCAExceptionBuilder.java:189) ~[com.ibm.mq.connector.jar:?] at com.ibm.mq.connector.services.JCAExceptionBuilder.buildException(JCAExceptionBuilder.java:111) ~[com.ibm.mq.connector.jar:?] at com.ibm.mq.connector.outbound.SessionWrapper.assertOpen(SessionWrapper.java:939) ~[com.ibm.mq.connector.jar:?] at com.ibm.mq.connector.outbound.SessionWrapper.createObjectMessage(SessionWrapper.java:210) ~[com.ibm.mq.connector.jar:?]
已确认MQ连接无异常,当前Liberty的server.xml配置如下:
<featureManager> <!--The following features are available in all editions of Liberty.--> <feature>appSecurity-2.0</feature> <feature>ejbLite-3.2</feature> <feature>jdbc-4.0</feature> <feature>jsp-2.3</feature> <feature>servlet-3.1</feature> <feature>wmqJmsClient-2.0</feature> <feature>jmsMdb-3.2</feature> </featureManager> <applicationManager autoExpand="true"/> <httpEndpoint host="*" httpPort="-1" httpsPort="${httpsPort}" id="defaultHttpEndpoint"/> <httpSession cookieName="${cookiename}" cookiePath="${cookiepath}" securityIntegrationEnabled="false" cookieHttpOnly="${cookiehttpOnly}" cookiesEnabled="${cookiesenabled}" cookieSecure="true"/> <enterpriseApplication id="" location="/location/EAR.ear" name="EAR"> <web-ext context-root="" id="EAR.ear_web-ext_" moduleName="app"/> </enterpriseApplication> <library id="mssqllib"> <fileset dir="${JDBC_DRIVER_PATH}" includes="${JDBC_DRIVER_FNAME}"/> </library> <dataSource beginTranForResultSetScrollingAPIs="false" beginTranForVendorAPIs="false" id="MssqlDS" jndiName="${JndiName}" type="javax.sql.ConnectionPoolDataSource"> <jdbcDriver libraryRef="mssqllib"/> <properties databaseName="${DbName}" portNumber="${DbPort}" serverName="${DbHost}" useNTLMv2="true" user="${DbUser}" password="${DbPasswd}"/> <connectionManager connectionTimeout="180" maxPoolSize="10"/> </dataSource> <transaction heuristicRetryWait="0" propogatedOrBMTTranLifetimeTimeout="300"/> <jmsActivationSpec id="jms/MQActSpec" maxSequentialFailureCount="10"> <properties.mqJmsRa brokerCCDurSubQueue="SYSTEM.JMS.D.CC.SUBSCRIBER.QUEUE" brokerCCSubQueue="SYSTEM.JMS.ND.CC.SUBSCRIBER.QUEUE" brokerControlQueue="SYSTEM.BROKER.CONTROL.QUEUE" brokerSubQueue="SYSTEM.JMS.ND.SUBSCRIBER.QUEUE" brokerVersion="1" channel="${MQCHNL}" cleanupInterval="3600000" destination-ref="jms/MQQ" destination="jms/MQQ" hostName="${MQHOST}" maxPoolDepth="20" messageRetention="YES" poolTimeout="300000" port="${MQPORT}" sparseSubscriptions="FALSE" maxSequentialFailureCount="10" subscriptionDurability="Nondurable" subscriptionStore="MIGRATE" useJNDI="true"/> </jmsActivationSpec> <jmsQueueConnectionFactory id="jms/MQQCF" jndiName="jms/MQQCF"> <properties.mqJmsRa channel="${MQCHNL}" hostName="${MQHOST}" port="${MQPORT}" temporaryModel="SYSTEM.DEFAULT.MODEL.QUEUE"/> <connectionManager connectionTimeout="180" maxPoolSize="20" minPoolSize="1"/> </jmsQueueConnectionFactory> <jmsQueue id="jms/MQQ" jndiName="jms/MQQ"> <properties.mqJmsRa baseQueueName="${MQQ}" receiveCCSID="1208" receiveConversion="QMGR"/> </jmsQueue> <ssl id="defaultSSLConfig" keyStoreRef="defaultKeyStore" trustStoreRef="defaultTrustStore" clientAuthenticationSupported="true" clientKeyAlias="${clientalias}" sslProtocol="${sslProtocol}"/> <keyStore id="defaultKeyStore" location="/location/sslconf.jks" type="JKS" password="${jkspassword}"/> <keyStore id="defaultTrustStore" location="/location/sslconf.jks"/> <resourceAdapter id="mqJmsRa" location="${MQlibpath}/wmq.jmsra.rar"> <classloader apiTypeVisibility="spec, ibm-api, api, third-party"/> </resourceAdapter> <variable name="wmqJmsClient.rar.location" value="${MQlibpath}/wmq.jmsra.rar"/> </server>
针对首次发送失败的MQJCA1020: The session is closed错误,可尝试以下调整:
调整连接池初始化策略:当前
jmsQueueConnectionFactory的connectionManager配置minPoolSize="1",Liberty启动时会初始化1个连接,但对应的Session可能未正确激活。添加initialPoolSize="1",确保启动时连接和Session都完成初始化:<connectionManager connectionTimeout="180" maxPoolSize="20" minPoolSize="1" initialPoolSize="1"/>禁用连接池超时回收:首次请求前,若连接池中的空闲连接被提前回收,会导致Session关闭。可调整
poolTimeout参数,延长空闲连接存活时间,或设置为0禁用超时:<!-- 在resourceAdapter的properties.mqJmsRa中添加 --> <properties.mqJmsRa poolTimeout="0"/>检查应用端Session复用逻辑:确认应用是否在启动时提前获取了Session但未保持活跃状态,导致Liberty连接池回收该Session。建议修改应用逻辑,在发送消息前才获取Session,或添加Session有效性检查,若已关闭则重新获取。
升级WMQ JMS RA版本:当前使用的
wmq.jmsra.rar版本可能与Liberty 24存在兼容性问题,尝试使用与Liberty 24匹配的最新IBM MQ Resource Adapter版本,确保JCA层的Session管理逻辑适配新环境。调整事务配置:检查
transaction配置中的propogatedOrBMTTranLifetimeTimeout,若首次发送涉及事务,超时时间过短可能导致Session提前关闭。可适当延长该值,或确认应用是否正确处理了事务边界。
内容的提问来源于stack exchange,提问作者tepaja

