Мне нужно подключиться к узлу Artemis с помощью SSL.
Если я использую org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory
и ввожу вbrokerURL все параметры:
String brokerURL = "tcp://*:61617?sslEnabled=true&keyStorePath = " + keyStorePath + "&keyStorePassword = " + keyStorePassword + "&trustStorePath = " + pathToTrustStore + "&trustStorePassword = " + trustStorePassword;
Все работает нормально, могу отправлять сообщения. Эта фабрика создает javax.jms.Connection
.
Я хочу работать с jakarta.org.apache.activemq.ActiveMQSslConnectionFactory
или с другим ActiveMQSslConnectionFactory
.
Приложение запустилось, но не отправляет/не получает сообщения.
В файле журнала все ошибки такие:
ERROR \[org.springframework.jms.JmsListenerEndpointContainer#0-1\] Could not refresh JMS Connection for destination 'queue.payments.v3.batch.response' - retrying using FixedBackOff{interval=5000, currentAttempts=9, maxAttempts=unlimited}. Cause: Cannot send, channel has already failed: tcp://*\*.\**:61617
и отладочные сообщения типа:
DEBUG [ActiveMQ Transport: tcp://*/:61617@50959] Async exception with no exception listener: {}
java.io.EOFException: null
at java.base/java.io.DataInputStream.readInt(DataInputStream.java:398)
at org.apache.activemq.openwire.OpenWireFormat.unmarshal(OpenWireFormat.java:280)
at org.apache.activemq.transport.tcp.TcpTransport.readCommand(TcpTransport.java:240)
at org.apache.activemq.transport.tcp.TcpTransport.doRun(TcpTransport.java:232)
at org.apache.activemq.transport.tcp.TcpTransport.run(TcpTransport.java:215)
at java.base/java.lang.Thread.run(Thread.java:833)
Вот мой класс конфигурации:
package com.bottomline.cfrm.ps.notification;
import javax.validation.constraints.NotEmpty;
import org.apache.activemq.ActiveMQSslConnectionFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.annotation.EnableJms;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
import org.springframework.jms.config.JmsListenerContainerFactory;
import jakarta.jms.Connection;
import jakarta.jms.ConnectionFactory;
import jakarta.jms.JMSException;
@Configuration
@EnableJms
public class ActiveMQConfiguration {
@NotEmpty(message = "Name may not be empty")
@Value("${spring.activemq.user}")
private String username;
@NotEmpty(message = "Password may not be empty")
@Value("${spring.activemq.password}")
private String password;
@NotEmpty(message = "Broker URL cannot be empty")
@Value("${spring.activemq.broker-url}")
private String brokerURL;
@NotEmpty(message = "Password cannot be empty")
@Value("${spring.activemq.ssl.keyStorePass}")
private String keyStorePass;
@Value("${spring.activemq.ssl.keyStorePath}")
private String keyStorePath;
@Value("${spring.activemq.ssl.trustStorePath}")
private String trustStorePath;
@Bean
public ActiveMQSslConnectionFactory activeMQSslConnectionFactory() {
ActiveMQSslConnectionFactory factory = new ActiveMQSslConnectionFactory(brokerURL);
try {
factory.setTrustStore(trustStorePath);
} catch (Exception e) {
e.printStackTrace();
}
factory.setTrustStorePassword(keyStorePass);
try {
factory.setKeyStore(keyStorePath);
} catch (Exception e) {
e.printStackTrace();
}
factory.setKeyStorePassword(keyStorePass);
factory.setUserName(username);
factory.setPassword(password);
Connection connection;
try {
connection = factory.createConnection();
connection.start();
} catch (JMSException e) {
e.printStackTrace();
}
return factory;
}
@Bean
public JmsListenerContainerFactory<?> jmsListenerContainerFactory(
@Qualifier("activeMQSslConnectionFactory") ConnectionFactory connectionFactory,
DefaultJmsListenerContainerFactoryConfigurer configurer) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
configurer.configure(factory, connectionFactory);
return factory;
}
}
И pom.xml
<?xml version = "1.0" encoding = "UTF-8"?>
<project xmlns = "http://maven.apache.org/POM/4.0.0" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.intellinx.solutions</groupId>
<artifactId>TestArtemisMQApplication</artifactId>
<version>1.0.3</version>
<name>TestArtemisMQApplication</name>
<description>Send and Read from Artemis queue</description>
<properties>
<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.source>17</maven.compiler.source>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<dependencies>
<!-- For Spring RestClient -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-artemis</artifactId>
</dependency> -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
<!--
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-artemis-native</artifactId>
<version>2.0.0</version>
</dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-jms-client-all</artifactId>
<version>2.6.3</version>
</dependency>
<dependency>
<groupId>javax.json</groupId>
<artifactId>javax.json-api</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.0.4</version>
</dependency>
</dependencies>
</project>
Я удалил jmsListenerContainerFactory
, просто чтобы проверить возможность подключения и отправки. Пытался использовать javax
вместо jakarta
, но мне нужны все функции Spring Boot для других частей приложения.
Полученный вами EOFException
и связанная с ним трассировка стека указывают, что вы пытаетесь использовать JMS-клиент OpenWire (т. е. org.apache.activemq.ActiveMQSslConnectionFactory
) для подключения к порту ActiveMQ Artemis, который поддерживает только протокол Core (т. е. не OpenWire).
Я рекомендую вам вернуться к использованию org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory
, и если вы хотите получить jakarta.jms.Connection
вместо javax.jms.Connection
, вам просто нужно использовать правильные зависимости. Прямо сейчас вы используете это:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
Вам следует удалить это и использовать это (которое было закомментировано):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-artemis</artifactId>
</dependency>
Эта зависимость имеет зависимость от org.apache.activemq:artemis-jakarta-client
, что даст вам реализацию Connection
в Джакарте.
Кроме того, вам необходимо удалить это, поскольку оно будет мешать зависимости клиента Artemis Jakarta:
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-jms-client-all</artifactId>
<version>2.6.3</version>
</dependency>
Если вы используете правильные зависимости, как указано в моем ответе, вы получите jakarta.jms.Connection
, а не javax.jms.Connection
.
Итак, решение
Используйте org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory из Spring-boot-starter-artemis.
Добавить зависимость
org.apache.activemq Артемида-Джакарта-серверДляbrokerURL используйте "" , а не "//" в путях к сертификатам.
спасибо за помощь. Мне следует использовать org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory только потому, что эта фабрика получает URL-адрес типа tcp://*:61617?sslEnabled=true&keyStorePath=... Но она создает javax.jms.Connection, а затем я нельзя использовать DefaultJmsListenerContainerFactory и JmsTemplate. Знаете ли вы другие зависимости или методы maven для подключения Listener к соединению? Без SSL все работает нормально. И я не могу найти способ добавить SSL.