【问题标题】:Remove a JMS message property删除 JMS 消息属性
【发布时间】:2014-01-20 16:34:24
【问题描述】:

我正在编写一个 Java 批处理,它正在侦听来自队列 (Oracle AQ) 的消息并将它们发送到另一个队列 (Tibco EMS),在那里它们由 Tibco 进程 (BW) 处理。

问题在于 Oracle AQ 驱动程序会自动向消息(JMSXGroupID、JMSXGroupSeq)添加一些属性,这些属性在 Tibco 进程处理它们时会导致错误,因为它们具有错误的值:JMSXGroupSeq 应该是一个 int 但设置为 null。 Tibco 在尝试解析消息属性时出错...

所以我想从所有消息中只删除这两个属性,但似乎 jms api 只提供 clearProperties() 方法但没有单个属性删除方法(我使用的是 javax.jms.Message 接口)。

目前,我可以看到两种解决方案:

  1. 为这 2 个属性设置正确的值,因为我假设它们会 不会被 Tibco 进一步使用

  2. 读取所有属性并重建没有导致问题的 2 的消息。但是这种做法很丑……

谁有其他解决方案?

【问题讨论】:

    标签: java jms tibco-ems


    【解决方案1】:

    无法编辑/清除某些属性。我们需要按照here 的描述调用 clearProperties 方法来获得写入权限:

    一旦产生(发送)消息,其属性变为只读;属性不能更改。虽然消费者可以使用属性访问器方法 (getProperty()) 读取属性,但他们不能使用任何 mutator 方法 (setProperty()) 修改属性。如果消费者试图设置一个属性,mutator 方法会抛出一个 javax.jms.MessageNotWriteableException。

    收到消息后,唯一可以更改其属性的方法是使用 clearProperties( ) 方法清除所有属性。这会从消息中删除所有属性,以便可以添加新属性。发送消息后,无法修改或删除单个属性。

    【讨论】:

    • 作为补充说明,同样的情况也适用于在发送后更改邮件正文本身 (setText(...))...一旦发送邮件就无法设置。但是,解决此问题的方法是使用clearBody()。似乎clearXxx() 方法在后台重置了某种“可写”类型标志,然后允许再次写入。
    • 这是特定于实现的,应谨慎使用。例如,如果我正在处理 ByteMessage 并使用 ActiveMQ 作为我的底层队列,则清除属性可以正常工作,但在添加新属性时会引发异常,说“消息正文是只读的”,因为 ActiveMQ 在为 ByteMessage 添加属性之前有额外的检查。当undelying queue是TIBCO Queue时,情况并非如此,在这里它可以正常工作
    【解决方案2】:

    在javax.jms.Message接口的具体类实现中会有一个函数public void removeProperty(String name)。此类是特定于提供商的(在您的情况下为 Tibco EMS)。由于它是封闭源代码,我无法确定该功能的存在。但它存在于 HornetQ 中。它可以用来重置特定的 header 属性。

    除此之外,我认为选项 1 是最好的。您将其设置为 Tibco EMS 的消息头解析器可接受的一些非空值。

    【讨论】:

    • 感谢您的回复。我尝试了这个解决方案,但得到了 javax.jms.MessageNotWriteableException。我发现消息头属性受到保护,您需要调用 clearProperties() 来获得写入权限。以下是一些解释:link。所以我现在不得不采取第二种解决方案,但我们正在等待 Oracle 的答复,以解决标头值不正确的主要问题。
    猜你喜欢
    • 2012-06-29
    • 2011-04-13
    • 1970-01-01
    • 2013-09-30
    • 1970-01-01
    • 1970-01-01
    • 2020-09-15
    • 2013-10-11
    • 2011-12-04
    相关资源
    最近更新 更多