jsr343-experts@jms-spec.java.net

[jsr343-experts] Re: [jms-spec users] Re: JMS 2.0 Late update: JMSProducer.getPropertyNames()

From: John D. Ament <john.d.ament_at_gmail.com>
Date: Fri, 1 Feb 2013 12:57:30 -0500

Nigel,

I'm good w/ Option B.

John


On Fri, Feb 1, 2013 at 10:14 AM, Nigel Deakin <nigel.deakin_at_oracle.com>wrote:

> (Please read and give your preference to A or B below)
>
> We're still debating whether the Set returned by
> JMSProducer#getPropertyNames (which returns all the property names
> configured on the JMSProducer) should be
>
> (1) A copy - so changing the JMSProducer would have no effect on the Set,
> and vice versa.
>
> (2) A "live" set backed by the underlying JMSProducer. If we follow the
> semantics of Map.keySet() changing the JMSProducer will change the Set, and
> vice versa.
>
> (3) A "live" set backed by the JMSProducer whereby changing the changing
> the JMSProducer will change the Set but where any attempt to change the Set
> would throw an exception. John Ament and Rüdiger were keen on this.
>
> I see a JMSProducer as a temporary place where message properties can be
> held prior to setting them on the message. They would simply be stored in a
> HashMap prior to being copied into the message when
> send(destination,message) is called.
>
> I can see the benefit of (2) since it doesn't require any copying of data.
> Although I originally proposed (1) I am now keener on (2). It is also
> consistent with the behaviour of Map.
>
> Rüdiger's argument for (3) was based on the possibility that the producer
> is "backed by a native system" for efficiency reasons and that this
> temporary store of properties might be as well. If this were the case it
> would defeat the purpose of using native storage if getPropertyNames were
> to return a copy.
>
> I can see the logic here, even though I don't think it is likely that an
> implementer would want to implement it any way other than using a Map (in
> the normal Java heap). However I don't see the logic in requiring this to
> be unmodifiable. A "native system" would already need to support methods on
> JMSProducer which allows properties to be set, modified and cleared, so I
> don't see why it would be particularly difficult to implement, say,
> Set#remove(key) so that it deletes the property with the specified key.
>
> There are two reasons why I don't think it is likely that an implementer
> would want to implement it any way other than using a Map. The first is
> that every time the JMSProducer is used to send a message, all its
> properties need to be copied to the message. So you might as well store it
> in the heap. The other is that it is safe to assume that the amount of data
> stored in message properties is small. JMS 1.1 already states that use of
> properties should be kept to a minimum:
>
> "JMS providers will likely handle data in a message’s body more
> efficiently than data in a message’s properties. For best performance,
> applications should use message properties only when they need to customize
> a message’s header." (JMS 1.1 3.5.3)
>
> So, I would like to propose two alternatives based on (2) and (3) above
> and ask for your views.
>
> OPTION A
> --------
>
>
> Set<String> getPropertyNames()
>
> Returns a Set view of the names of all the message properties that have
> been set on this JMSProducer.
>
> Note that JMS standard header fields are not considered properties and are
> not returned in this Set.
>
> The set is backed by the JMSProducer, so changes to the map are reflected
> in the set, and vice-versa. Its behaviour matches that defined in the
> java.util.Map method keySet.
>
> Returns:
> a Set containing the names of all the message properties that have
> been set on this JMSProducer
> Throws:
> JMSRuntimeException - if the JMS provider fails to get the property
> names due to some internal error.
> See Also:
> Map.keySet()
>
> OPTION B
> --------
>
> Set<String> getPropertyNames()
>
> Returns an unmodifiable Set view of the names of all the message
> properties that have been set on this JMSProducer.
>
>
> Note that JMS standard header fields are not considered properties and are
> not returned in this Set.
>
> The set is backed by the JMSProducer, so changes to the map are reflected
> in the set. However the set may not be modified. Attempts to modify the
> returned collection, whether directly or via its iterator, will result in
> an UnsupportedOperationException. Its behaviour matches that defined in the
> java.util.Collections method unmodifiableSet.
>
>
> Returns:
> a Set containing the names of all the message properties that have
> been set on this JMSProducer
> Throws:
> JMSRuntimeException - if the JMS provider fails to get the property
> names due to some internal error.
> See Also:
> Collections.unmodifiableSet()
>
>
>
> Please express your views! (If you don't care then please say so as well)
>
> Nigel
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> On 24/01/2013 21:11, Rüdiger zu Dohna wrote:
>
>> Nigel,
>>
>> On 2013-01-22, at 12:29, Nigel Deakin<nigel.deakin_at_oracle.com**> wrote:
>>
>>> If it's backed by the JMSProducer's internal map, why do you think it
>>> needs to be unmodifiable? There's no
>>> technical reason why this needs to be the case. This is just a simple
>>> map (and does not need to be threadsafe).
>>>
>>
>> It could be that the producer is backed by a native system, so the map
>> would be as well. Changing the map would have
>> to be forwarded to that native system. While quite possible, it would be
>> extra effort over the dedicated methods to
>> add/remove/change the properties. Maybe the native system doesn't
>> distinguish between header fields and properties...
>> things can get ugly for the implementers.
>>
>> I think the set returned should either be
>>>
>>> * backed by the JMSProducer's internal map, in which case it should
>>> follow the semantics of Map.keySet()
>>>
>>> * a simple copy of the keys in the JMSProducer's internal map, in which
>>> case it will follow the obvious semantics
>>> of a copy.
>>>
>>> My feeing is that to make it "backed", but not allow the application to
>>> delete properties by removing property
>>> names from the set, would be unnecessarily inconsistent. It should
>>> either be "fully" backed, or a simple copy.
>>>
>>
>> Right, this would have to be consistent.
>>
>> I think the question we should ask is: Do developers want to modify the
>> properties map/set directly or are the
>> methods sufficient? If the latter, make it immutable.
>>
>> Having a copy wouldn't help anybody, would it? It would just cause extra
>> load on the GC (maps are comparably huge!).
>> This reminds me of the Swing issues with all those defensive copies of
>> the mutable Rectangle/Point classes.
>>
>>
>> Rüdiger
>>
>>