0. обновлённый пример без naming
Для перехода от Jakarta Naming (JNDI) к более современному подходу нам нужно модифицировать код. В основном это затронет настройку подключений и внедрение ресурсов. Давайте изменим файлы:
- Сначала обновим 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
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>jms-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jakarta.jakartaee-api.version>10.0.0</jakarta.jakartaee-api.version>
<wildfly.version>27.0.0.Final</wildfly.version>
</properties>
<dependencies>
<!-- Jakarta EE API -->
<dependency>
<groupId>jakarta.platform</groupId>
<artifactId>jakarta.jakartaee-api</artifactId>
<version>${jakarta.jakartaee-api.version}</version>
<scope>provided</scope>
</dependency>
<!-- JMS API -->
<dependency>
<groupId>jakarta.jms</groupId>
<artifactId>jakarta.jms-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- WildFly Remote Client -->
<dependency>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-client-all</artifactId>
<version>${wildfly.version}</version>
</dependency>
</dependencies>
<build>
<finalName>jms-demo</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.2</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
- JMSProducer.java остается практически без изменений, так как он уже использует CDI для внедрения ресурсов:
package com.example.jms;
import jakarta.annotation.Resource;
import jakarta.jms.*;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.logging.Logger;
import java.util.logging.Level;
@WebServlet("/producer")
public class JMSProducer extends HttpServlet {
private static final Logger LOGGER = Logger.getLogger(JMSProducer.class.getName());
@Resource(lookup = "java:/ConnectionFactory")
private ConnectionFactory connectionFactory;
@Resource(lookup = "java:/jms/queue/ExampleQueue")
private Queue queue;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/plain");
PrintWriter out = response.getWriter();
try {
Connection connection = connectionFactory.createConnection();
try {
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer producer = session.createProducer(queue);
TextMessage message = session.createTextMessage(
"Демо сообщение JMS: " + java.time.LocalDateTime.now()
);
message.setStringProperty("sender", "JMSProducerServlet");
message.setIntProperty("priority", 5);
producer.setDeliveryMode(DeliveryMode.PERSISTENT);
producer.send(message);
LOGGER.info("Сообщение отправлено: " + message.getText());
out.println("Сообщение успешно отправлено в очередь");
producer.close();
session.close();
connection.close();
} catch (JMSException e) {
LOGGER.log(Level.SEVERE, "Ошибка JMS", e);
out.println("Ошибка при отправке сообщения: " + e.getMessage());
throw new ServletException(e);
}
} catch (JMSException e) {
LOGGER.log(Level.SEVERE, "Ошибка соединения", e);
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
"Не удалось установить JMS-соединение");
}
}
public void sendMessage(String messageText) throws JMSException {
Connection connection = connectionFactory.createConnection();
try {
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer producer = session.createProducer(queue);
TextMessage message = session.createTextMessage(messageText);
producer.send(message);
} finally {
connection.close();
}
}
}
- JMSConsumer.java также остается похожим:
package com.example.jms;
import jakarta.annotation.Resource;
import jakarta.jms.*;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/consumer")
public class JMSConsumer extends HttpServlet {
@Resource(lookup = "java:/ConnectionFactory")
private ConnectionFactory connectionFactory;
@Resource(lookup = "java:/jms/queue/ExampleQueue")
private Queue queue;
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/plain");
PrintWriter out = response.getWriter();
try (Connection connection = connectionFactory.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE)) {
connection.start();
MessageConsumer consumer = session.createConsumer(queue);
Message message = consumer.receive(5000);
if (message instanceof TextMessage textMessage) {
out.println("Получено сообщение: " + textMessage.getText());
} else {
out.println("Сообщений нет");
}
} catch (JMSException e) {
throw new ServletException(e);
}
}
}
- JMSStandaloneClient.java требует наибольших изменений, так как использовал JNDI напрямую:
package com.example.jms;
import jakarta.jms.*;
import java.util.Properties;
import org.wildfly.common.function.ExceptionSupplier;
import org.wildfly.security.auth.client.*;
import javax.security.auth.callback.CallbackHandler;
import org.wildfly.security.auth.client.AuthenticationConfiguration;
import org.wildfly.security.auth.client.AuthenticationContext;
import org.wildfly.security.auth.client.MatchRule;
public class JMSStandaloneClient {
public static void main(String[] args) {
try {
// Настройка аутентификации
AuthenticationConfiguration authConfig = AuthenticationConfiguration.empty()
.useName("admin")
.usePassword("password");
AuthenticationContext context = AuthenticationContext.empty()
.with(MatchRule.ALL, authConfig);
// Установка контекста аутентификации
AuthenticationContext.getContextManager().setGlobalDefault(context);
// Создание фабрики подключений через WildFly Connector
RemoteConnectionFactory connectionFactory = new RemoteConnectionFactory();
// Создание соединения
try (JMSContext jmsContext = connectionFactory.createContext("admin", "password")) {
// Создание очереди
Queue queue = jmsContext.createQueue("java:/jms/queue/ExampleQueue");
// Получение сообщения
JMSConsumer consumer = jmsContext.createConsumer(queue);
String message = consumer.receiveBody(String.class, 5000);
if (message != null) {
System.out.println("Получено сообщение: " + message);
} else {
System.out.println("Сообщений нет");
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Основные изменения: 1. Удалили зависимость jakarta.naming-api 2. В standalone клиенте заменили JNDI на прямое создание подключения через WildFly Connector 3. Используем JMSContext вместо старого подхода с Connection/Session 4. Аутентификация теперь происходит через WildFly Security 5. Упростили работу с очередями используя современный API
web.xml остается без изменений, так как он не связан с JNDI напрямую.
Эти изменения делают код более современным и соответствующим текущим рекомендациям Jakarta EE.
пример
https://gitlab.com/javaee5603144/examples/-/tree/main/jms-demo?ref_type=heads