【问题标题】:Object with collection containing Serializable, non-primitive objects can't be set as ActiveMQ ObjectMessage具有包含可序列化、非原始对象的集合的对象不能设置为 ActiveMQ ObjectMessage
【发布时间】:2011-10-17 18:10:53
【问题描述】:

如果有任何帮助,我将不胜感激......

我有一个对象,我试图通过调用 setObject 在 JMS ObjectMessage 中发送。此对象包含一个 HashMap 内容以及一些其他字段。当地图包含原始元素时,消息构建得很好。同样,如果我向对象添加一个非原始可序列化字段,它也会发送 ok。

问题来了:每当我尝试将可序列化的非原始对象添加到 MAP 时,我都会收到以下 MessageFormatException:

javax.jms.MessageFormatException: Only objectified primitive objects, String, 
Map and List types are allowed but was: com.abc.ObjectInList

ObjectMessage 的 javadoc 指定...

只能使用可序列化的 Java 对象。

...检查。还有……

如果必须发送 Java 对象的集合,则可以使用自 JDK 1.2 以来提供的 Collection 类之一。

...仔细检查。虽然这并没有具体说明 Collection 中的 Serializable 对象,但我想我会假设这会得到支持。我在这里做错了吗?我是否只是硬着头皮在我的顶级对象中创建一个新字段,这样我就不必将它放在集合中?

使用 ActiveMQ 5.2。随后是相关的堆栈跟踪。

2011-08-01 21:06:05,767 错误 javax.jms.MessageFormatException:只允许对象化的原始对象、字符串、映射和列表类型,但是是:com.abc.engine.ejb.BasicSchedule@58f295b9 类型:类C om.abc.engine.ejb.BasicSchedule 2011-08-01 21:06:05,767 org.apache.activemq.command.ActiveMQMessage.checkValidObject 错误(ActiveMQMessage.java:468) 2011-08-01 21:06:05,767 org.apache.activemq.command.ActiveMQMapMessage.setObject 错误(ActiveMQMapMessage.java:705) 2011-08-01 21:06:05,767 com.abc.chronicle.ejb.ChronicleMessageBean.initMessage 错误(ChronicleMessageBean.java:149) 2011-08-01 21:06:05,767 com.abc.chronicle.ejb.ChronicleMessageBean.send 错误(ChronicleMessageBean.java:125) 2011-08-01 21:06:05,767 com.abc.chronicle.ejb.ChronicleMessageBean.onMessage 错误(ChronicleMessageBean.java:77) 2011-08-01 21:06:05,767 sun.reflect.NativeMethodAccessorImpl.invoke0 错误(本机方法)2011-08-01 21:06:05,768 sun.reflect.NativeMethodAccessorImpl.invoke 错误(NativeMethodAccessorImpl.java:39) 2011-08-01 21:06:05,777 错误 [com.abc.chronicle.ejb.ChronicleMessageBean] JMS 异常向 SDK.OUTGOING_NOTIFICATION 发送消息:javax.jms.MessageFormatException:仅对象化原始对象,字符串,马 p 和 List 类型是允许的,但是是:com.abc.engine.ejb.BasicSchedule@1003b2df 类型:com.abc.engine.ejb.BasicSchedule 2011-08-01 21:06:05,778 错误 javax.jms.MessageFormatException:仅允许对象化原始对象、字符串、映射和列表类型,但为:com.abc.engine.ejb.BasicSchedule@1003b2df 类型:c 类 om.abc.engine.ejb.BasicSchedule 2011-08-01 21:06:05,778 org.apache.activemq.command.ActiveMQMessage.checkValidObject 错误(ActiveMQMessage.java:468) 2011-08-01 21:06:05,778 org.apache.activemq.command.ActiveMQMapMessage.setObject 错误(ActiveMQMapMessage.java:705) 2011-08-01 21:06:05,778 com.abc.chronicle.ejb.ChronicleMessageBean.initMessage 错误(ChronicleMessageBean.java:149) 2011-08-01 21:06:05,778 com.abc.chronicle.ejb.ChronicleMessageBean.send 错误(ChronicleMessageBean.java:125) 2011-08-01 21:06:05,778 com.abc.chronicle.ejb.ChronicleMessageBean.onMessage 错误(ChronicleMessageBean.java:77)

【问题讨论】:

标签: java serialization collections jms activemq


【解决方案1】:

虽然我还没有检查过,但是看着source code,当 ActiveMQ 验证消息属性而不是正文时,您似乎遇到了这个异常。 JavaDoc 对应于 ObjectMessage 的内容为:

只能使用可序列化的 Java 对象。

我将各种 Java 对象与 ActiveMQ(任意复杂)一起使用,并且它始终有效。但是,当您设置消息属性时 (Message#setObjectProperty):

请注意,此方法仅适用于对象化的原始对象类型(IntegerDoubleLong ...)和String 对象。

检查上面引用的 ActiveMQ 代码库,您似乎正在尝试使用消息对象属性来发送复杂的 Java 对象。这滥用了消息属性的概念,它应该是简单的元数据,如 id 或对等名称。

此外,ActiveMQ 似乎可以选择支持MapList,但这是特定于供应商的。

【讨论】:

  • Message接口中有一个Message.setObjectProperty(Object),但是我使用的是ObjectMessage子类和setObject方法
  • 此外,我使用的所有对象都扩展了 Serializable
  • 好的,您可以将这个MessageFormatException 的堆栈跟踪添加到您的问题中吗?我不能再仅仅看 ActiveMQ 代码库了。
  • 感谢您查看 - 在问题中包含跟踪(抱歉格式化)
  • ChronicleMessageBean 中的第 149 行在您的代码中看起来如何?我有理由相信您使用的是MapMessage 而不是ObjectMessage。似乎您使用的版本与 5.2.0 略有不同,但这并不重要。你确定你创建了ObjectMessage
猜你喜欢
  • 1970-01-01
  • 2015-02-28
  • 2020-04-16
  • 2017-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-01
相关资源
最近更新 更多