我正在将 ActiveMQ Classic 升级到 ActiveMQ Artemis,同时维护客户端代码。我有多个地方的代码看起来像这样。
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jms.core.JmsTemplate;
public class TestV {
public static void main(String[] args) throws IOException {
ApplicationContext ctx = new ClassPathXmlApplicationContext("root.xml");
JmsTemplate jms = ctx.getBean(JmsTemplate.class);
Map<String, Object> map = new HashMap<>();
List<Integer> ids = new ArrayList<>();
ids.add(10);
ids.add(20);
map.put("ids", ids);
map.put("updated", true);
jms.convertAndSend("mytest", map);
}
}
如何修复来自上述代码的以下错误。
Exception in thread "main" org.springframework.jms.UncategorizedJmsException: Uncategorized exception occurred during JMS processing; nested exception is javax.jms.JMSException: org.apache.activemq.artemis.api.core.ActiveMQPropertyConversionException: class java.util.ArrayList is not a valid property type
at org.springframework.jms.support.JmsUtils.convertJmsAccessException(JmsUtils.java:311)
at org.springframework.jms.support.JmsAccessor.convertJmsAccessException(JmsAccessor.java:185)
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:507)
at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:584)
at org.springframework.jms.core.JmsTemplate.convertAndSend(JmsTemplate.java:661)
at com.mycompany.adhoc.TestV.main(TestV.java:33)
Caused by: javax.jms.JMSException: org.apache.activemq.artemis.api.core.ActiveMQPropertyConversionException: class java.util.ArrayList is not a valid property type
at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:54)
at org.apache.activemq.ActiveMQConnection.syncSendPacket(ActiveMQConnection.java:1404)
at org.apache.activemq.ActiveMQConnection.syncSendPacket(ActiveMQConnection.java:1437)
at org.apache.activemq.ActiveMQConnection.syncSendPacket(ActiveMQConnection.java:1324)
at org.apache.activemq.ActiveMQSession.send(ActiveMQSession.java:1981)
at org.apache.activemq.ActiveMQMessageProducer.send(ActiveMQMessageProducer.java:288)
at org.apache.activemq.ActiveMQMessageProducer.send(ActiveMQMessageProducer.java:223)
at org.apache.activemq.ActiveMQMessageProducerSupport.send(ActiveMQMessageProducerSupport.java:241)
at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:634)
at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:608)
at org.springframework.jms.core.JmsTemplate.lambda$send$3(JmsTemplate.java:586)
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:504)
在ActiveMQ Classic中我们可以在连接工厂中设置可信包。我如何在 ActiveMQ Artemis 中执行此操作?
此问题与 JMS 上设置可信包无关
ConnectionFactory
。
问题在于您的应用程序隐式使用 ActiveMQ Classic 提供的这个 JMS“扩展”。正如文档所述:
此 JMS 扩展功能允许您将映射和列表属性附加到任何 JMS 消息或在 MapMessage 中使用嵌套映射和列表。 [强调我的]
当您将
Map<String, Object>
变量 map
传递给 JmsTemplate.convertAndSend
时,它会使用默认的 SimpleMessageConverter
将 Map
转换为 javax.jms.MapMessage
。正如 MapMessage
的 JavaDoc 所述:
名称是 String 对象,值是 Java 编程语言中的“原始数据类型”。 [强调我的]
换句话说,根据 JMS 规范,
MapMessage
中的值只能是原始数据类型。然而,ActiveMQ Classic 提供了一个允许使用
List
实现的扩展。使用此扩展的代码无法移植到其他 JMS 代理,因为它不遵守 JMS 规范。这就是 ActiveMQ Artemis 抛出错误 ActiveMQPropertyConversionException: class java.util.ArrayList is not a valid property type
的原因。您必须更改应用程序代码以遵守 JMS 规范(即在 Map
的值中使用原始数据类型),或者必须由 ActiveMQ Artemis 实现相同的扩展。