我正在尝试使用 ActiveMQ“Classic”发送
ObjectMessage
。为此,我创建了两个 Spring Boot 项目 - 客户和生产者。我使用下面的代码从生产者发送。
@GetMapping("/send-letter")
public String sendLetter() {
var letter = new Letter("Hello " + UUID.randomUUID(), "Jack", "Jill");
template.convertAndSend("test_letter", letter);
return "Letter sent!";
}
然后,我使用下面的代码来捕获客户中的该对象。
@JmsListener(destination = "test_letter")
public void getTest(Letter letter) {
System.out.printf("From %s to %s with content %s", letter.getSender(), letter.getReceiver(), letter.getContent());
}
此外,这是我在
application.yaml
文件上的配置。我也尝试使用 trust-all: true
参数但没有任何效果。
spring:
activemq:
broker-url: tcp://localhost:61616
user: admin
password: admin
packages:
trusted: com.example.demo.Entities.Letter
完全相同的结构适用于字符串。
我能够将
ObjectMessage
发送到 ActiveMQ,正如我从管理面板中看到的那样,但是当我运行侦听器时,它会抛出一堆错误,我将“主要”错误放在下面:
org.springframework.jms.listener.adapter.ListenerExecutionFailedException: Listener method 'public void com.example.demo.controller.MessageConsumer.getTest(com.example.demo.Entities.Letter)' threw exception
at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:118)
Caused by: org.springframework.jms.support.converter.MessageConversionException: Could not convert JMS message
at org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener.extractMessage(AbstractAdaptableMessageListener.java:255)
Caused by: jakarta.jms.JMSException: Failed to build body from content. Serializable class not available to broker. Reason: java.lang.ClassNotFoundException: Forbidden class com.example.demo.Entities.Letter! This class is not trusted to be serialized as ObjectMessage payload. Please take a look at http://activemq.apache.org/objectmessage.html for more information on how to configure trusted classes.
at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:49) ~[activemq-client-jakarta-5.18.2.jar:5.18.2]
Caused by: java.lang.ClassNotFoundException: Forbidden class com.example.demo.Entities.Letter! This class is not trusted to be serialized as ObjectMessage payload. Please take a look at http://activemq.apache.org/objectmessage.html for more information on how to
我通过阅读本教程编写了代码。我阅读并尝试了我能找到的关于此问题的所有答案(包括将对象转换为字节),但我无法使它们工作。
我期待在客户控制台中看到该对象。
看起来您将受信任的包配置为使用 class 名称(即
com.example.demo.Entities.Letter
)而不是 package 名称(即 com.example.demo.Entities
)。尝试用这个代替:
spring:
activemq:
broker-url: tcp://localhost:61616
user: admin
password: admin
packages:
trusted: com.example.demo.Entities
也就是说,您应该尽可能避免使用 JMS
ObjectMessage
。它们依靠 Java 序列化来编组和解组其对象负载。这不仅速度慢,而且通常被认为是不安全的,因为恶意负载可以利用主机系统。为此创建了许多 CVE,这也是您必须首先显式配置哪些包受信任的原因。使用 ObjectMessage
还会限制架构的灵活性,因为非 JMS 客户端无法使用它们。
我强烈建议您使用其他格式的消息,例如JSON、XML、Protobuf 等。这将更快、更安全,并且与其他语言和协议广泛兼容,使您的架构更加健壮。