从 ActiveMQ Classic 升级到 ActiveMQ Artemis - 类 java.util.ArrayList 不是有效的属性类型

问题描述 投票:0回答:1

我正在将 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 中执行此操作?

activemq-classic spring-jms activemq-artemis
1个回答
1
投票

此问题与 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 实现相同的扩展。

    

© www.soinside.com 2019 - 2024. All rights reserved.