我有两个完全独立的应用程序。一个应用程序向 ActiveMQ 代理(ActiveMQ 版本 5.18.2)上的队列发送一条消息,另一个应用程序应该接收该消息。这两个应用程序都使用 Spring Boot 版本 2.4.1。
我可以看到消息已被代理接收,然后被消费者应用程序消费。问题是消费者无法转换 JMS 消息,因为它首先没有找到用于构建消息的类。
我的生产者应用程序的粗略实现:
@SpringBootApplication
public class MyProducerApplication implements ApplicationRunner{
private static Logger log = LoggerFactory.getLogger(MyProducerApplication.class);
@Autowired
private FooMessageSender fooMessageSender;
@Override
public void run(ApplicationArguments applicationArguments) throws Exception {
log.info("Spring Boot Embedded ActiveMQ Configuration Example");
final MyObjectMessage msg = new MyObjectMessage(MyObjectMessage.type);
...
//msg setter methods here
...
fooMessageSender.send("remotingQueue", msg);
}
FooMessageConverter:
它使用以下 ObjectMapper 类导入:
import com.fasterxml.jackson.databind.ObjectMapper;
@Component
public class FooMessageConverter implements MessageConverter {
private static final Logger LOGGER =
LoggerFactory.getLogger(FooMessageConverter.class);
ObjectMapper mapper;
public FooMessageConverter() {
mapper = new ObjectMapper();
}
@Override
public Message toMessage(Object object, Session session)
throws JMSException {
final Message toSend = session.createObjectMessage((Serializable) object);
return toSend;
}
@Override
public Object fromMessage(Message message) throws JMSException, MessageConversionException {
MyObjectMessage msg = null;
if (message instanceof ActiveMQObjectMessage) {
ObjectMessage objMessage = (ObjectMessage) message;
msg = (MyObjectMessage) objMessage.getObject()
}
return msg;
}
FooMessage:-不再使用
public class FooMessage implements Serializable {
...
Message implementation here
...
}
我的消费者应用程序的实现:
@SpringBootApplication
public class myConsumer implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
// TODO Auto-generated method stub
}
FooMessageConverter
与 Producer 应用程序相同
QueueConsumer类:
@Component
public class QueueConsumer {
private static Logger log = LoggerFactory.getLogger(QueueConsumer.class);
@JmsListener(destination = "remotingQueue")
public void receiveMessage(
@Payload MyObjectMessage myMessage) {
log.info("Q Message received: <" + myMessage + ">");
}
}
FooMessageSender 类:
@Service
public class FooMessageSender {
private static Logger log = LoggerFactory.getLogger(FooMessageSender.class);
@Autowired
private JmsTemplate jmsTemplate;
public void send(String queue, MyObjectMessage msg) {
log.info("sending with convertAndSend() to queue <" + msg + ">");
jmsTemplate.convertAndSend(queue, msg);
}
}
我不确定应该如何配置
MessageConverter
才能正确发送和使用对象消息。我希望 FooMessageConverter 类是关键。
堆栈跟踪:(注意,我不允许将任何内容列入白名单,因此 ActiveMQ 建议将可以使用 ObjectMessages 交换的包列入白名单,但不适用于我的情况)
<WARN> [DefaultMessageListenerContainer-1] [2023-09-18 15:22:17,113] Execution of JMS message listener failed, and no ErrorHandler has been set.
org.springframework.jms.listener.adapter.ListenerExecutionFailedException: Listener method 'public void com.package2.api.service.QueueConsumer.receiveMessage(com.otherpackage.MyObjectMessage)' threw exception; nested exception is org.springframework.jms.support.converter.MessageConversionException: Could not convert JMS message; nested exception is javax.jms.JMSException: Failed to build body from content. Serializable class not available to broker. Reason: java.lang.ClassNotFoundException: Forbidden class com.otherpackage.MyObjectMessage! 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.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:122) ~[spring-jms-5.3.2.jar:5.3.2]
at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.onMessage(MessagingMessageListenerAdapter.java:77) ~[spring-jms-5.3.2.jar:5.3.2]
at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:736) ~[spring-jms-5.3.2.jar:5.3.2]
at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:696) ~[spring-jms-5.3.2.jar:5.3.2]
at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:674) ~[spring-jms-5.3.2.jar:5.3.2]
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:318) [spring-jms-5.3.2.jar:5.3.2]
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:257) [spring-jms-5.3.2.jar:5.3.2]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1189) [spring-jms-5.3.2.jar:5.3.2]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1179) [spring-jms-5.3.2.jar:5.3.2]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1076) [spring-jms-5.3.2.jar:5.3.2]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_291]
Caused by: org.springframework.jms.support.converter.MessageConversionException: Could not convert JMS message; nested exception is javax.jms.JMSException: Failed to build body from content. Serializable class not available to broker. Reason: java.lang.ClassNotFoundException: Forbidden class com.otherpackage.MyObjectMessage! 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.springframework.jms.listener.adapter.AbstractAdaptableMessageListener.extractMessage(AbstractAdaptableMessageListener.java:256) ~[spring-jms-5.3.2.jar:5.3.2]
at org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener$MessagingMessageConverterAdapter.extractPayload(AbstractAdaptableMessageListener.java:475) ~[spring-jms-5.3.2.jar:5.3.2]
at org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener$MessagingMessageConverterAdapter$LazyResolutionMessage.unwrapPayload(AbstractAdaptableMessageListener.java:542) ~[spring-jms-5.3.2.jar:5.3.2]
at org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener$MessagingMessageConverterAdapter$LazyResolutionMessage.getPayload(AbstractAdaptableMessageListener.java:524) ~[spring-jms-5.3.2.jar:5.3.2]
at org.springframework.messaging.handler.annotation.support.PayloadMethodArgumentResolver.resolveArgument(PayloadMethodArgumentResolver.java:116) ~[spring-messaging-5.3.2.jar:5.3.2]
at org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:117) ~[spring-messaging-5.3.2.jar:5.3.2]
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:148) ~[spring-messaging-5.3.2.jar:5.3.2]
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:116) ~[spring-messaging-5.3.2.jar:5.3.2]
at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:114) ~[spring-jms-5.3.2.jar:5.3.2]
... 10 common frames omitted
Caused by: javax.jms.JMSException: Failed to build body from content. Serializable class not available to broker. Reason: java.lang.ClassNotFoundException: Forbidden class com.otherpackage.MyObjectMessage! 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:36) ~[activemq-client-5.16.0.jar:5.16.0]
at org.apache.activemq.command.ActiveMQObjectMessage.getObject(ActiveMQObjectMessage.java:213) ~[activemq-client-5.16.0.jar:5.16.0]
at com.package2.api.service.FooMessageConverter.fromMessage(FooMessageConverter.java:61) ~[classes/:na]
at org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener.extractMessage(AbstractAdaptableMessageListener.java:251) ~[spring-jms-5.3.2.jar:5.3.2]
... 18 common frames omitted
Caused by: java.lang.ClassNotFoundException: Forbidden class com.otherpackage.MyObjectMessage! 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.ClassLoadingAwareObjectInputStream.checkSecurity(ClassLoadingAwareObjectInputStream.java:111) ~[activemq-client-5.16.0.jar:5.16.0]
at org.apache.activemq.util.ClassLoadingAwareObjectInputStream.resolveClass(ClassLoadingAwareObjectInputStream.java:56) ~[activemq-client-5.16.0.jar:5.16.0]
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1984) ~[na:1.8.0_291]
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1848) ~[na:1.8.0_291]
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2158) ~[na:1.8.0_291]
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1665) ~[na:1.8.0_291]
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:501) ~[na:1.8.0_291]
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:459) ~[na:1.8.0_291]
at org.apache.activemq.command.ActiveMQObjectMessage.getObject(ActiveMQObjectMessage.java:211) ~[activemq-client-5.16.0.jar:5.16.0]
... 20 common frames omitted