Я использую mq-jms-spring-boot-starter
<dependency>
<groupId>com.ibm.mq</groupId>
<artifactId>mq-jms-spring-boot-starter</artifactId>
<version>3.0.6</version>
</dependency>
Я пытаюсь установить соединение JNDI с удаленным сервером IBM MQ.
Вот мой сервис
@Slf4j
@Service
public class JMSService {
static final String MESSAGE_FORMAT_MQSTR = "MQSTR";
private String destinationPromoJndiName = "jms/promoQueue";
@Autowired
private JmsTemplate jmsTemplate;
/**
* Sending a packet via MQSeries to the Promo queue
*/
public void sendPromoPacket(final byte[] paquet) throws TechnicalException {
try {
log.info("send message to '{}", this.destinationPromoJndiName);
jmsTemplate.convertAndSend(this.destinationPromoJndiName, paquet);
} catch (JmsException e) {
e.printStackTrace();
throw new TechnicalException("error sending promo packet ..");
}
}
}
Я получил следующую ошибку
2024-04-16T08:31:02.815Z INFO 1 --- [tpmc1000] [nio-8080-exec-4] c.package.fr.tpmc.storage.JMSService : send message to 'jms/PromoQueue
org.springframework.jms.IllegalStateException: JMSWMQ0018: Failed to connect to queue manager 'QM1' with connection mode 'Client' and host name 'Client'.; nested exception is com.ibm.mq.MQException: JMSCMQ0001: IBM MQ call failed with compcode '2' ('MQCC_FAILED') reason '2538' ('MQRC_HOST_NOT_AVAILABLE').
at org.springframework.jms.support.JmsUtils.convertJmsAccessException(JmsUtils.java:274)
at org.springframework.jms.support.JmsAccessor.convertJmsAccessException(JmsAccessor.java:199)
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:533)
at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:610)
...
Caused by: com.ibm.msg.client.jakarta.jms.DetailedIllegalStateException: JMSWMQ0018: Failed to connect to queue manager 'QM1' with connection mode 'Client' and host name 'Client'.
Check the queue manager is started and if running in client mode, check there is a listener running. Please see the linked exception for more information.
at com.ibm.msg.client.jakarta.wmq.common.internal.Reason.reasonToException(Reason.java:489)
at com.ibm.msg.client.jakarta.wmq.common.internal.Reason.createException(Reason.java:215)
at com.ibm.msg.client.jakarta.wmq.internal.WMQConnection.<init>(WMQConnection.java:458)
at com.ibm.msg.client.jakarta.wmq.factories.WMQConnectionFactory.createV7ProviderConnection(WMQConnectionFactory.java:8683)
at com.ibm.msg.client.jakarta.wmq.factories.WMQConnectionFactory.createProviderConnection(WMQConnectionFactory.java:8023)
at com.ibm.msg.client.jakarta.jms.admin.JmsConnectionFactoryImpl._createConnection(JmsConnectionFactoryImpl.java:322)
at com.ibm.msg.client.jakarta.jms.admin.JmsConnectionFactoryImpl.createConnection(JmsConnectionFactoryImpl.java:242)
at com.ibm.mq.jakarta.jms.MQConnectionFactory.createCommonConnection(MQConnectionFactory.java:6026)
at com.ibm.mq.jakarta.jms.MQConnectionFactory.createConnection(MQConnectionFactory.java:6055)
at org.springframework.jms.connection.SingleConnectionFactory.doCreateConnection(SingleConnectionFactory.java:452)
at org.springframework.jms.connection.SingleConnectionFactory.initConnection(SingleConnectionFactory.java:414)
at org.springframework.jms.connection.SingleConnectionFactory.getConnection(SingleConnectionFactory.java:328)
at org.springframework.jms.connection.SingleConnectionFactory.createConnection(SingleConnectionFactory.java:243)
at org.springframework.jms.support.JmsAccessor.createConnection(JmsAccessor.java:211)
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:517)
... 135 more
Caused by: com.ibm.mq.MQException: JMSCMQ0001: IBM MQ call failed with compcode '2' ('MQCC_FAILED') reason '2538' ('MQRC_HOST_NOT_AVAILABLE').
at com.ibm.msg.client.jakarta.wmq.common.internal.Reason.createException(Reason.java:203)
... 148 more
Caused by: com.ibm.mq.jmqi.JmqiException: CC=2;RC=2538;AMQ9204: Connection to host 'localhost(1414)' rejected. [1=com.ibm.mq.jmqi.JmqiException[CC=2;RC=2538;AMQ9204: Connection to host 'localhost/127.0.0.1:1414' rejected. [1=java.net.ConnectException[Connection refused],3=localhost/127.0.0.1:1414,4=TCP,5=Socket.connect]],3=localhost(1414),4=,5=RemoteTCPConnection.bindAndConnectSocket]
at com.ibm.mq.jmqi.remote.api.RemoteFAP$Connector.jmqiConnect(RemoteFAP.java:13670)
at com.ibm.mq.jmqi.remote.api.RemoteFAP$Connector.access$100(RemoteFAP.java:13202)
at com.ibm.mq.jmqi.remote.api.RemoteFAP.jmqiConnect(RemoteFAP.java:1451)
at com.ibm.mq.jmqi.remote.api.RemoteFAP.jmqiConnect(RemoteFAP.java:1392)
at com.ibm.mq.ese.jmqi.InterceptedJmqiImpl.jmqiConnect(InterceptedJmqiImpl.java:377)
at com.ibm.mq.ese.jmqi.ESEJMQI.jmqiConnect(ESEJMQI.java:562)
at com.ibm.msg.client.jakarta.wmq.internal.WMQConnection.<init>(WMQConnection.java:391)
... 147 more
Caused by: com.ibm.mq.jmqi.JmqiException: CC=2;RC=2538;AMQ9204: Connection to host 'localhost/127.0.0.1:1414' rejected. [1=java.net.ConnectException[Connection refused],3=localhost/127.0.0.1:1414,4=TCP,5=Socket.connect]
at com.ibm.mq.jmqi.remote.impl.RemoteTCPConnection.bindAndConnectSocket(RemoteTCPConnection.java:932)
at com.ibm.mq.jmqi.remote.impl.RemoteTCPConnection.protocolConnect(RemoteTCPConnection.java:1511)
at com.ibm.mq.jmqi.remote.impl.RemoteConnection.connect(RemoteConnection.java:1013)
at com.ibm.mq.jmqi.remote.impl.RemoteConnectionSpecification.getNewConnection(RemoteConnectionSpecification.java:691)
at com.ibm.mq.jmqi.remote.impl.RemoteConnectionSpecification.getSessionFromNewConnection(RemoteConnectionSpecification.java:283)
at com.ibm.mq.jmqi.remote.impl.RemoteConnectionSpecification.getSession(RemoteConnectionSpecification.java:170)
at com.ibm.mq.jmqi.remote.impl.RemoteConnectionPool.getSession(RemoteConnectionPool.java:128)
at com.ibm.mq.jmqi.remote.api.RemoteFAP$Connector.jmqiConnect(RemoteFAP.java:13402)
... 153 more
Caused by: java.net.ConnectException: Connection refused
at java.base/sun.nio.ch.Net.connect0(Native Method)
at java.base/sun.nio.ch.Net.connect(Net.java:589)
at java.base/sun.nio.ch.Net.connect(Net.java:578)
at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:583)
at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327)
at java.base/java.net.Socket.connect(Socket.java:751)
at java.base/java.net.Socket.connect(Socket.java:686)
at com.ibm.mq.jmqi.remote.impl.RemoteTCPConnection$4.run(RemoteTCPConnection.java:1111)
at com.ibm.mq.jmqi.remote.impl.RemoteTCPConnection$4.run(RemoteTCPConnection.java:1103)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:319)
at com.ibm.mq.jmqi.remote.impl.RemoteTCPConnection.connectSocket(RemoteTCPConnection.java:1103)
at com.ibm.mq.jmqi.remote.impl.RemoteTCPConnection.bindAndConnectSocket(RemoteTCPConnection.java:838)
... 160 more
2024-04-16T08:31:03.590Z ERROR 1 --- [tpmc1000] [nio-8080-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: com.package.fr.tpmc.exception.TechnicalException: error sending promo packet ..] with root cause
Как правильно настроить IBM MQ с JMS? Здесь все предоставленные свойства, которые я должен использовать
// connection factory ..
jndi-queue-factory: jms/prologQF
hostName: x.x.x.x
port: 1423
prologQF_channel: QMX0.SVRC.APPPROMO
prologQF_queueManager: QMX0
queueProxy_targetClient: MQJMS_CLIENT_NONJMS_MQ
queueProxy_ccsid: 819
promoQueue_baseQueueName: APP.PROMO
Пожалуйста, помогите, как настроить стартер Springboot?
Я добавил следующий JmsConfig
@Configuration
public class JmsConfig {
@Bean
public MQQueueConnectionFactory mqConnectionFactory(JmsProperties jmsProperties) throws JMSException {
MQQueueConnectionFactory mqQueueConnectionFactory = new MQQueueConnectionFactory();
mqQueueConnectionFactory.setHostName("x.x.x.x");
mqQueueConnectionFactory.setChannel("QMX0.SVRC.APPPROMO");
mqQueueConnectionFactory.setPort(1423);
mqQueueConnectionFactory.setQueueManager("QMX0");
mqQueueConnectionFactory.setTransportType(WMQConstants.WMQ_CLIENT_NONJMS_MQ);
return mqQueueConnectionFactory;
}
@Bean
public JmsTemplate jmsTemplate(MQQueueConnectionFactory mqConnectionFactory) {
JmsTemplate jmsTemplate = new JmsTemplate();
jmsTemplate.setConnectionFactory(mqConnectionFactory);
return jmsTemplate;
}
}
Я не получил никаких ошибок при загрузке приложения, но получил следующее при попытке отправить сообщение в очередь IBM
2024-04-16T10:31:20.862Z INFO 1 --- [tpmc1000] [nio-8080-exec-1] c.package.fr.app.storage.JMSService : send message to 'jms/queuePromo
org.springframework.jms.InvalidDestinationException: JMSWMQ2008: Failed to open MQ queue 'jms/queuePrologPromo'.; nested exception is com.ibm.mq.MQException: JMSCMQ0001: IBM MQ call failed with compcode '2' ('MQCC_FAILED') reason '2085' ('MQRC_UNKNOWN_OBJECT_NAME').
at org.springframework.jms.support.JmsUtils.convertJmsAccessException(JmsUtils.java:280)
at org.springframework.jms.support.JmsAccessor.convertJmsAccessException(JmsAccessor.java:199)
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:533)
at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:610)
...
Caused by: com.ibm.msg.client.jakarta.jms.DetailedInvalidDestinationException: JMSWMQ2008: Failed to open MQ queue 'jms/queuePrologPromo'.
JMS attempted to perform an MQOPEN, but IBM MQ reported an error.
Use the linked exception to determine the cause of this error. Check that the specified queue and queue manager are defined correctly.
at com.ibm.msg.client.jakarta.wmq.common.internal.Reason.reasonToException(Reason.java:513)
at com.ibm.msg.client.jakarta.wmq.common.internal.Reason.createException(Reason.java:215)
at com.ibm.msg.client.jakarta.wmq.internal.WMQMessageProducer.checkJmqiCallSuccess(WMQMessageProducer.java:1358)
at com.ibm.msg.client.jakarta.wmq.internal.WMQMessageProducer.checkJmqiCallSuccess(WMQMessageProducer.java:1313)
at com.ibm.msg.client.jakarta.wmq.internal.WMQMessageProducer.access$800(WMQMessageProducer.java:75)
at com.ibm.msg.client.jakarta.wmq.internal.WMQMessageProducer$SpiIdentifiedProducerShadow.initialise(WMQMessageProducer.java:900)
at com.ibm.msg.client.jakarta.wmq.internal.WMQMessageProducer.<init>(WMQMessageProducer.java:1288)
at com.ibm.msg.client.jakarta.wmq.internal.WMQSession.createProducer(WMQSession.java:1128)
at com.ibm.msg.client.jakarta.jms.internal.JmsSessionImpl.createProducer(JmsSessionImpl.java:1484)
at com.ibm.msg.client.jakarta.jms.internal.JmsQueueSessionImpl.createSender(JmsQueueSessionImpl.java:121)
at com.ibm.mq.jakarta.jms.MQQueueSession.createSender(MQQueueSession.java:143)
at com.ibm.mq.jakarta.jms.MQQueueSession.createProducer(MQQueueSession.java:248)
at org.springframework.jms.core.JmsTemplate.doCreateProducer(JmsTemplate.java:1141)
at org.springframework.jms.core.JmsTemplate.createProducer(JmsTemplate.java:1122)
at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:628)
at org.springframework.jms.core.JmsTemplate.lambda$send$3(JmsTemplate.java:612)
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:530)
... 135 more
Caused by: com.ibm.mq.MQException: JMSCMQ0001: IBM MQ call failed with compcode '2' ('MQCC_FAILED') reason '2085' ('MQRC_UNKNOWN_OBJECT_NAME').
at com.ibm.msg.client.jakarta.wmq.common.internal.Reason.createException(Reason.java:203)
... 150 more
2024-04-16T10:31:22.085Z ERROR 1 --- [tpmc1000] [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: com.package.fr.tpmc.exception.TechnicalException: error sending promo packet ..] with root cause
com.package.fr.tpmc.exception.TechnicalException: error sending promo packet ..
...
Не могу зарегистрировать фабрику соединений java:/jms/queueProlog
!
@ user207421, потому что он принимает конфигурацию по умолчанию. до сих пор я не указал IP:порт
Я пытался добавить spring.jms.jndi-name=java:/jms/queueProlog
, но все еще не понимаю, как использовать другие свойства (например, имя хоста/порт...)
Подробности вашего вопроса неясны: создали ли вы запись JNDI для jms/queuePrologPromo, которая ссылается на имя очереди IBM MQ APP.PROMO?
@MoragHughson да, он уже существует. Я пытаюсь подключиться к удаленному серверу с предоставленной информацией.
Сообщение об ошибке
org.springframework.jms.InvalidDestinationException: JMSWMQ2008: Failed to open MQ queue 'jms/queuePrologPromo'
предполагает, что Spring не может преобразовать имя JNDI в имя очереди.
У вас должен быть следующий набор в вашем application.properties
ibm.mq.jndi.providerUrl=...
ibm.mq.jndi.providerContextFactory=com.sun.jndi.fscontext.RefFSContextFactory
на основе документации mq-jms-spring-boot-starter для JNDI
В противном случае вы можете указать хост и порт через application.properties
, например.
ibm.mq.queueManager=QM1
ibm.mq.channel=DEV.APP.SVRCONN
ibm.mq.connName=server.example.com(1414)
ibm.mq.user=user1
ibm.mq.password=passw0rd
как описано в репозитории для mq-jms-spring-boot-starter
В противном случае вы можете добавить имя очереди в application.properties
. любым ключом по вашему выбору. например.
app.queue.name=DEV.QUEUE.1
затем внедрите это в свой код. например.
@Value("${app.queue.name}")
public String sendQueue;
нам не нужен JmsConfig (его следует удалить!), нам нужно только добавить следующую конфигурацию в application.yml
ibm:
mq:
queueManager: QMX0
channel: QMX0.SVRC.APPPROMO
connName: @ip(1423). # x.x.x.x(1423)
Кроме того, вместо имени очереди мы должны использовать APP.PROMO
.
Это работает как шарм (JNDI не нужен);)
java.net.ConnectException: Connection refused
: на IP-порте, к которому вы пытались подключиться, ничего не прослушивается.