Kinda seems like you didnt read my mail which both explained exactly why it does/has to work the way it does and noted that potential solution :)
On Sun, 15 Mar 2026 at 22:18, John <[email protected]> wrote: > > Hi Everyone- > > We've figured out a solution. > > After stepping through the Apache NMS AMQP code (which isn't easy > because it starts out with some kind of funky dynamic plugin like > loading, which makes it difficult to step through), we saw that when > the Client ID is auto-generated, it pulls in a prefix variable. After > following that rabbit, we figured out that it comes in from the Uri. > At practically the same time, it was "rediscovered" in the connection > documentation, there is a Uri parameter named nms.clientIdPrefix. This > parameter allows the auto-generated Client ID to be prefixed with > whatever is wanted. Doh! What is so funny (or should I say sad) here > is that this was originally seen but not understood, as far as how it > would relate to us with what we want to do. At that earlier time, we > didn't know the significance of the auto-generated Client IDs and > Shared Subscribers. As I said before, and I'll say again, what does it > matter between an auto-generated unique Client ID and a self-created > unique Client ID? (Don't answer that) I know what the group will say, > "...because that's what the documentation says..." ;-) > > So, anyway, using the prefix to name the auto-generated Client IDs so > that they can be differentiated solves our problem. > > Thank you to everyone who helped with our issue. > > Cheers! > > > > On Sat, Mar 14, 2026 at 6:47 AM Robbie Gemmell <[email protected]> > wrote: > > > > The only bit which sounds like it may be a bug in the NMS client is if > > you can't create multiple consumers on a shared subscription on the > > same connection in a situation you actually should be able to. That > > doesnt actually seem to be your main complaint though, so I'll > > concentrate on your other thoughts that different connections each > > with distinct ClientIDs explicitly set, getting the same messages, > > whilst using a shared subscriber with the same shared subscription > > name, would be a bug. It is not. > > > > This is required JMS spec-defined behaviour from 2013 [and before] > > with the release of JMS 2.0 API specification when shared > > subscriptions were added, along with the ability to not actually set a > > ClientID on a Connection and yet still use shared [durable] > > subscriptions. > > > > The spec requires that a shared subscription on a Connection with a > > ClientID specified behaves one way, giving totally separate > > ClientID-scoped namespaces for durable and non-durable named shared > > subscriptions, and further that there is only a single joined > > subscription namespace for both the shared durable and > > previously-existing JMS 1 non-shared durable named subscriptions that > > were already ClientID-scoped since 1998. The spec also requires that > > shared subscriptions on a Connection without a ClientID specified > > behave in a completely different way, with each of durable and > > non-durable shared subscriptions being in separate namespaces > > (distinct from both each other, and from those on Connections with a > > ClientID specified) with a given named subscription of a given type > > then shareable between all such Connections similarly without any > > ClientID specified. For completeness, you can't have a non-shared > > durable subscription on a Connection without a ClientID specified. > > > > If you do specify a ClientID, the spec thus inherently requires that > > you can then only have other shared consumers for that ClientID-scoped > > shared subscription on that very same Connection, since only one > > Connection can use a ClientID at a given time and the subscription is > > scoped to that ClientID, meaning no other Connection can share that > > subscription at the same time, end of story. Different Connections > > with a distinct specified ClientID can each have their own similar > > subscriptions with the same subscription name, but that is a totally > > separate subscription scoped to their ClientID, and they thus receive > > their own copy of the messages like any distinct subscription should. > > If that doesnt meet your needs because e.g. you want to share a single > > subscription across multiple different Connections, then you would > > need to not set a ClientID on your Connections in which case all such > > Connections without ClientID can share that distinct > > not-ClientID-scoped named subscription since they are then all > > accessing the same subscription, or else you would need to use a > > regular Queue with competing consumers (this behaving the same > > regardless of the ClientID being explicitly specified or not since its > > not a topic subscription), as has been explained before. > > > > The ClientID if specified is conveyed on the wire in the container-id > > field which must have a value, so the client generates a value for > > this if a ClientID was not explicitly specified. It is known whether a > > ClientID has been explicitly specified or not, and then in turn it is > > known when a shared[/non-shared durable] subscription is being created > > whether a ClientID was specified or not, and a different thing is done > > in these cases resulting in the different required behaviours detailed > > by the JMS specification and outlined above and previously in the > > thread. The NMS behaviour is based on this JMS behaviour. > > > > I know that in Qpid JMS we allow defining a 'ClientIDPrefix' to be > > used within the auto-generated values if you dont actually specify a > > ClientID. I dont know for sure if that functionality was copied in the > > NMS AMQP client but I would guess it was. If so perhaps you can use > > that to help discriminate between different connections if your main > > concern is harder identification of things using a generated > > container-id value that's being displayed as a ClientID in the > > console. > > > > In terms of the overall behaviour you can avail yourself of the > > formerly-JMS / now Jakarta Messaging specification at: > > https://jakarta.ee/specifications/messaging/3.1/apidocs/jakarta.messaging/jakarta/jms/package-summary > > > > Of particular relation to the discussion would be the 8 shared and > > non-shared subscription methods that cover all the behaviour as it has > > already been explained: > > https://jakarta.ee/specifications/messaging/3.1/apidocs/jakarta.messaging/jakarta/jms/session#createDurableConsumer(jakarta.jms.Topic,java.lang.String) > > https://jakarta.ee/specifications/messaging/3.1/apidocs/jakarta.messaging/jakarta/jms/session#createDurableConsumer(jakarta.jms.Topic,java.lang.String,java.lang.String,boolean) > > https://jakarta.ee/specifications/messaging/3.1/apidocs/jakarta.messaging/jakarta/jms/session#createDurableSubscriber(jakarta.jms.Topic,java.lang.String) > > https://jakarta.ee/specifications/messaging/3.1/apidocs/jakarta.messaging/jakarta/jms/session#createDurableSubscriber(jakarta.jms.Topic,java.lang.String,java.lang.String,boolean) > > https://jakarta.ee/specifications/messaging/3.1/apidocs/jakarta.messaging/jakarta/jms/session#createSharedConsumer(jakarta.jms.Topic,java.lang.String) > > https://jakarta.ee/specifications/messaging/3.1/apidocs/jakarta.messaging/jakarta/jms/session#createSharedConsumer(jakarta.jms.Topic,java.lang.String,java.lang.String) > > https://jakarta.ee/specifications/messaging/3.1/apidocs/jakarta.messaging/jakarta/jms/session#createSharedDurableConsumer(jakarta.jms.Topic,java.lang.String) > > https://jakarta.ee/specifications/messaging/3.1/apidocs/jakarta.messaging/jakarta/jms/session#createSharedDurableConsumer(jakarta.jms.Topic,java.lang.String,java.lang.String) > > > > Robbie > > > > On Sat, 14 Mar 2026 at 05:48, John <[email protected]> wrote: > > > > > > On Thu, Mar 12, 2026 at 7:47 PM Justin Bertram <[email protected]> > > > wrote: > > > > > > > If I may interject... > > > > > > > > I'm not super familiar with the NMS client you're using, but my > > > > understanding is that it should essentially act like a traditional JMS > > > > client for this use-case. Assuming that's true, I think everything > > > > you're seeing is the expected behavior. > > > > > > > > Here are a few things to keep in mind (distilling what Tim already > > > > said): > > > > > > > > 1) Any client wishing to connect to the broker with a client ID must > > > > ensure that ID is unique among all connected clients. Clients > > > > attempting to connect using a client ID already in use will be > > > > rejected. > > > > > > > > > > I agree with this. Where a client is considered a connection. As it is our > > > observation that each connection is either given a unique Client ID when > > > not explicitly set, or if the Client ID is assigned via the nms.clientId > > > parameter, then it must be unique; otherwise, an exception is thrown. > > > > > > > > > > 2) If set, the client ID will become part of any shared subscription > > > > created. Receiving messages from that shared subscription requires the > > > > same client ID. > > > > > > > > > > This does not track with what we are seeing. So, I almost think that the > > > terminology in NMS differs from that in JMS. Almost, thinking that > > > possibly > > > "Shared Subscriptions" or "Client ID" for the observed behaviors for NMS > > > doesn't mean the same as in JMS. > > > > > > I say observed behaviors, because we have not found much documentation on > > > NMS, and so here is what we have figured out in NMS: > > > > > > The Client ID is always set. Either automatically when creating the > > > connection or explicitly via the NMS.clientId Uri parameter. In either > > > case, the Client ID will/must be unique. > > > > > > When creating a Shared Subscriber (e.g., > > > session.CreateSharedConsumer(topic, subscriptionName)), messages from that > > > topic are supposed to be distributed among the Shared Subscribers. (They > > > don't each receive all the messages. The messages are divided among the > > > Shared Subscribers.) > > > > > > And to create a Shared Subscriber, one must have a unique Client ID > > > (whether set implicitly or explicitly) and a common Subscription Name. > > > > > > And for (#2), to make sense (somewhat) in NMS, instead of "Client ID," as > > > stated, maybe it should read "Subscription Name". As I already stated in > > > NMS, the Client ID is always set, no matter what. > > > > > > And in NMS, the only way any type of subscriber would have the same Client > > > ID is to be on the same connection. But if one were to try to create more > > > than one Shared Subscriber on a connection (whether the Client ID is > > > implicitly or explicitly set), an exception is thrown: "The key already > > > existed in the dictionary." > > > > > > > > > > 3) The client ID may be null when creating a shared subscription. > > > > > > > > > > With NMS, if a Client ID is not explicitly assigned, then it is > > > automatically generated for the connection. So, this isn't true in NMS. > > > There will always be a Client ID. > > > > > > Now, as I mentioned above (#2), in NMS, if the "Client ID" was meant to > > > read as "Subscription Name", then yes, the Subscription Name can be null > > > when creating Shared Subscribers. However, they do not behave like Shared > > > Subscribers, as each receives all messages for the topic, just like a > > > regular subscriber (e.g., session.CreateConsumer(topic)), defeating the > > > purpose of Shared Subscribers. > > > > > > > > > > > > > 4) If you want to share a subscription among several simultaneously > > > > connected clients, do not set the client ID. > > > > > > > > The whole client ID + shared subscription combo just doesn't make a > > > > lot of sense. Shared subscriptions were added to the JMS specification > > > > years after client ID was established so not everything fits perfectly > > > > conceptually. However, once you understand the basic rules it's pretty > > > > straight-forward. > > > > > > > > > > > Well, this is true. Not explicitly setting the Client ID and allowing the > > > connection to generate its own unique Client ID allows for Shared > > > Consumers > > > to work correctly. But this is what I'm complaining about. > > > > > > And for some, sharing (dividing) messages on a topic makes sense. > > > Let's walk through a use case: > > > Let's say multiple "microservices" are subscribed to a topic, each > > > handling > > > the messages received on that topic. Then, let's say one of these services > > > takes a long time to handle messages from the topic. Then, for this one > > > service, it makes sense to scale out, meaning running more than one > > > instance of it. Then, for this one service, it would want the message > > > divided among its instances, with each instance handling its share, > > > thereby > > > spreading the workload. > > > Now, let's say many of the "microservices", each need to scale out to > > > handle the workload generated by the many more messages on that topic > > > during a large traffic spike. Each instance of each service needs to > > > handle > > > its share of messages, but overall, each service needs to receive all > > > messages from the topic. Now, imagine these service instances are all > > > coming and going as traffic ramps up and down. And then say someone (or > > > another service) has the task of monitoring or troubleshooting these > > > connections and subscribers, but since all these connections that are > > > coming and going can't be named, but instead must each be given an > > > auto-generated UUID, they become very difficult to tell apart. If one were > > > a mere human working in the Broker's Management console, I would dare to > > > say it is impossible. > > > > > > I hope that makes sense. And in our case, it's a bit more complicated > > > because some services run on the same hosts (to save money), and when a > > > host scales, those services scale together. > > > > > > And back to what I originally was trying to convey in my first email to > > > the > > > group: > > > > > > When creating Shared Consumers with our own unique Client IDs via the Uri > > > nms.clientId parameter, each Shared Subscriber receives all messages from > > > the topic, just like a regular subscriber (e.g., > > > session.CreateConsumer(topic) ). > > > > > > To us, this does not make sense. Why would the Shared Subscribers (e.g., > > > session.CreateSharedConsumer(topic, subscriptionName)) each receive all > > > messages when they have an explicitly set unique Client ID and a common > > > Subscription Name, but if you don't set the Client ID, it works as it > > > should, even though a unique Client ID is auto-generated for the > > > connection? (That's a rhetorical question.) > > > > > > This has to be a bug. And if it is by design, it should be changed. Well, > > > that is my two cents anyway. > > > > > > Thanks > > > > > > John > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Hope that helps! > > > > > > > > > > > > Justin > > > > > > > > On Thu, Mar 12, 2026 at 9:09 PM John <[email protected]> wrote: > > > > > > > > > > Hi Tim, > > > > > > > > > > I'm writing back again to talk about this issue more. > > > > > > > > > > Per our prior conversation, we've confirmed that, with Artemis (not > > > > > ActiveMQ) for Shared Consumers, using a single connection and setting > > > > > the > > > > > nms.clientId parameter in the URI, any Shared Consumer created after > > > > > the > > > > > first one throws an exception ("The key already existed in the > > > > > dictionary"). This same exception is thrown under the same > > > > > circumstances > > > > > when the Client ID is not on the URI and is instead generated by the > > > > > library. > > > > > > > > > > And anyway, even if it would let us, using a single connection would > > > > > not > > > > > work for us. This is because we have several services that subscribe > > > > > to a > > > > > topic. One of the services takes a bit of time to process the messages > > > > from > > > > > the topic. For this particular service, we want to scale out to > > > > distribute > > > > > the message workload. And, technically, we want this ability for each > > > > > service. Also, using a queue for this service is not ideal as it > > > > > defeats > > > > > the purpose of having a topic. > > > > > > > > > > Also, in our examination, the Client ID does not appear to be a shared > > > > > namespace, per se, as discussed earlier. Or, to clarify further, if > > > > > the > > > > > Client ID is not assigned to the connections via nms.clientId, the > > > > > library-generated Client IDs are unique for each Shared Consumer's > > > > > connection and have the following format: "ID:HOSTNAME:UUID:N", where > > > > UUID > > > > > is unique for each connection. > > > > > This is odd regarding the earlier discussion, since the generated > > > > > Client > > > > > IDs are unique. Why would our unique Client ID via nms.clientId be > > > > treated > > > > > any differently? > > > > > > > > > > Nevertheless, as far as we can tell, the only way Shared Consumers > > > > > work > > > > > correctly is without setting our own Client IDs. But it would be > > > > > advantageous for us to use our own Client IDs, and it seems we should > > > > > be > > > > > able to do so. And if so, we are back to the idea that this is a bug. > > > > > > > > > > Please let me know what your thoughts are. > > > > > > > > > > Thanks > > > > > > > > > > John > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > On Tue, Mar 10, 2026 at 9:48 PM John <[email protected]> wrote: > > > > > > > > > > > Thank you for the explanation. I better understand now. And I think > > > > > > switching to regular consumers will probably work. > > > > > > > > > > > > Thanks again. > > > > > > > > > > > > On Tue, Mar 10, 2026 at 7:53 PM Timothy Bish <[email protected]> > > > > wrote: > > > > > > > > > > > >> On 3/10/26 21:29, John wrote: > > > > > >> > Yes, you are correct. I've confirmed that we are using Artemis > > > > > >> > for > > > > the > > > > > >> > subscriptions. ActiveMQ is being used for other purposes. The > > > > exception > > > > > >> > from earlier was when using Artemis. > > > > > >> > > > > > > >> > So to me, this means it's a bug. If the Client IDs are the same, > > > > > >> > an > > > > > >> > exception is thrown when Artemis is used as the broker. Would the > > > > > >> > developers be interested in looking into this? If so, how should > > > > > >> > we > > > > > >> submit > > > > > >> > the issue to them? > > > > > >> > > > > > > >> > Thanks > > > > > >> > > > > > >> Sorry I was unclear earlier as I was in a rush and I misled you a > > > > > >> bit. > > > > > >> > > > > > >> A JMS client if setting a client ID must give a unique ID which is > > > > > >> why > > > > > >> you got the error shown as your clients are all trying to connect > > > > > >> with > > > > > >> the same client ID. This is the issue though that prevents you > > > > > >> from > > > > > >> using shared subscriptions in they way you want since if you set > > > > client > > > > > >> IDs the shared subscriptions cannot be shared across connections, > > > > > >> only > > > > > >> from consumers created by sessions under the same connection. > > > > > >> Think > > > > of > > > > > >> the client ID as a namespace and the lack of one as a global > > > > namespace. > > > > > >> Shared subscriptions will work for you if your clients do not set a > > > > > >> client ID as you've seen because the namespace of all shared > > > > > >> subscriptions without a client ID is shared as a global namespace > > > > > >> for > > > > > >> that subscription across connections. Once you set a client ID you > > > > are > > > > > >> effectively in a private namespace owned by the connection that set > > > > that > > > > > >> ID and no two connections can share the same client ID. > > > > > >> > > > > > >> ActiveMQ does not implement shared subscriptions at all so if you > > > > > >> try > > > > to > > > > > >> use those APIs from the NMS client against that broker the result > > > > > >> will > > > > > >> likely be an error response or something not doing what you want so > > > > you > > > > > >> need to use Apache Artemis if you want shared subscriptions but you > > > > will > > > > > >> need to stick to no client ID if you want to share across > > > > > >> connections. > > > > > >> Likely you can accomplish what you want by simply moving to using a > > > > > >> Queue as consumers on a Queue all compete for messages (work > > > > > >> sharing) > > > > > >> which seems like what you are going for. but your exact > > > > > >> requirements > > > > > >> wasn't fully clear so you'd need to provide more info on why you > > > > > >> want > > > > to > > > > > >> use shared subs. > > > > > >> > > > > > >> > > > > > >> > > > > > > >> > On Tue, Mar 10, 2026 at 5:33 PM Timothy Bish > > > > > >> > <[email protected]> > > > > > >> wrote: > > > > > >> > > > > > > >> >> On 3/10/26 20:15, John wrote: > > > > > >> >>> Thank you for your reply. > > > > > >> >>> > > > > > >> >>> If I understand correctly, we should use the same client ID for > > > > each > > > > > >> >>> client. And, if that is the case, then this has already been > > > > tried, > > > > > >> >>> and the result is that every client after the first throws this > > > > > >> >>> exception: > > > > > >> >> I know that ActiveMQ doesn't support shared subscriptions of any > > > > sort > > > > > >> so > > > > > >> >> if you tried this with ActiveMQ you will not get anything to > > > > > >> >> work, > > > > and > > > > > >> >> if it did somehow create a subscription it would not be a valid > > > > one. > > > > > >> >> You would need to use Apache Artemis for shared subscription > > > > support as > > > > > >> >> that has full support for the AMQP JMS mapping. As the > > > > specification > > > > > >> >> states the subscription is named by the subscription name and > > > > > >> >> the > > > > > >> client > > > > > >> >> ID so if you want to share your clients either need no client > > > > > >> >> ID or > > > > > >> they > > > > > >> >> all need the same for the subscription in question. > > > > > >> >> > > > > > >> >> > > > > > >> >>> Unhandled exception. Apache.NMS.NMSException: , ErrorInfo = { > > > > > >> >>> key: invalid-field, value: container-id; > > > > > >> >>> } > > > > > >> >>> ---> Apache.NMS.AMQP.Util.NMSProviderError: > > > > > >> >>> amqp:invalid-field > > > > > >> >>> at > > > > > >> >>> Apache.NMS.AMQP.Util.ExceptionSupport.GetException(Error > > > > > >> >>> amqpErr, String message, Exception e) > > > > > >> >>> at > > > > > >> Apache.NMS.AMQP.Provider.Amqp.AmqpConnection.OnClosed(IAmqpObject > > > > > >> >>> sender, Error error) > > > > > >> >>> at Amqp.AmqpObject.NotifyClosed(Error error) > > > > > >> >>> at Amqp.Connection.OnEnded(Error error) > > > > > >> >>> at Amqp.Connection.OnClose(Close close) > > > > > >> >>> at Amqp.Connection.OnFrame(ByteBuffer buffer) > > > > > >> >>> at Amqp.AsyncPump.PumpAsync(UInt32 maxFrameSize, Func`2 > > > > onHeader, > > > > > >> >>> Func`2 onBuffer) > > > > > >> >>> at > > > > > >> >> > > > > > >> > > > > System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.ExecutionContextCallback(Object > > > > > >> >>> s) > > > > > >> >>> at > > > > System.Threading.ExecutionContext.RunInternal(ExecutionContext > > > > > >> >>> executionContext, ContextCallback callback, Object state) > > > > > >> >>> at > > > > > >> >> > > > > > >> > > > > System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext(Thread > > > > > >> >>> threadPoolThread) > > > > > >> >>> at > > > > > >> >> > > > > > >> > > > > System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext() > > > > > >> >>> at > > > > > >> >> > > > > > >> > > > > System.Runtime.CompilerServices.TaskAwaiter.<>c.<OutputWaitEtwEvents>b__12_0(Action > > > > > >> >>> innerContinuation, Task innerTask) > > > > > >> >>> at > > > > > >> >> > > > > System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(Action > > > > > >> >>> action, Boolean allowInlining) > > > > > >> >>> at System.Threading.Tasks.Task.RunContinuations(Object > > > > > >> >> continuationObject) > > > > > >> >>> at System.Threading.Tasks.Task`1.TrySetResult(TResult > > > > > >> >>> result) > > > > > >> >>> at > > > > > >> >> > > > > > >> > > > > System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.SetExistingTaskResult(Task`1 > > > > > >> >>> task, TResult result) > > > > > >> >>> at Amqp.AsyncPump.ReceiveBufferAsync(Byte[] buffer, Int32 > > > > offset, > > > > > >> >>> Int32 count) > > > > > >> >>> at > > > > > >> >> > > > > > >> > > > > System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.ExecutionContextCallback(Object > > > > > >> >>> s) > > > > > >> >>> at > > > > System.Threading.ExecutionContext.RunInternal(ExecutionContext > > > > > >> >>> executionContext, ContextCallback callback, Object state) > > > > > >> >>> at > > > > > >> >> > > > > > >> > > > > System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext(Thread > > > > > >> >>> threadPoolThread) > > > > > >> >>> at > > > > > >> >> > > > > > >> > > > > System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext() > > > > > >> >>> at > > > > > >> >> > > > > > >> > > > > System.Runtime.CompilerServices.TaskAwaiter.<>c.<OutputWaitEtwEvents>b__12_0(Action > > > > > >> >>> innerContinuation, Task innerTask) > > > > > >> >>> at > > > > > >> >> > > > > System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(Action > > > > > >> >>> action, Boolean allowInlining) > > > > > >> >>> at System.Threading.Tasks.Task.RunContinuations(Object > > > > > >> >> continuationObject) > > > > > >> >>> at System.Threading.Tasks.Task`1.TrySetResult(TResult > > > > > >> >>> result) > > > > > >> >>> at > > > > > >> >> > > > > > >> > > > > System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.SetExistingTaskResult(Task`1 > > > > > >> >>> task, TResult result) > > > > > >> >>> at > > > > > >> >> > > > > Amqp.TcpTransport.TcpSocket.Amqp.IAsyncTransport.ReceiveAsync(Byte[] > > > > > >> >>> buffer, Int32 offset, Int32 count) > > > > > >> >>> at > > > > > >> >> > > > > > >> > > > > System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.ExecutionContextCallback(Object > > > > > >> >>> s) > > > > > >> >>> at > > > > System.Threading.ExecutionContext.RunInternal(ExecutionContext > > > > > >> >>> executionContext, ContextCallback callback, Object state) > > > > > >> >>> at > > > > > >> >> > > > > > >> > > > > System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext(Thread > > > > > >> >>> threadPoolThread) > > > > > >> >>> at > > > > > >> >> > > > > > >> > > > > System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext() > > > > > >> >>> at > > > > > >> >> > > > > > >> > > > > System.Runtime.CompilerServices.TaskAwaiter.<>c.<OutputWaitEtwEvents>b__12_0(Action > > > > > >> >>> innerContinuation, Task innerTask) > > > > > >> >>> at > > > > > >> >> > > > > System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(Action > > > > > >> >>> action, Boolean allowInlining) > > > > > >> >>> at System.Threading.Tasks.Task.RunContinuations(Object > > > > > >> >> continuationObject) > > > > > >> >>> at System.Threading.Tasks.Task`1.TrySetResult(TResult > > > > > >> >>> result) > > > > > >> >>> at > > > > > >> >> System.Threading.Tasks.TaskCompletionSource`1.TrySetResult(TResult > > > > > >> result) > > > > > >> >>> at Amqp.SocketExtensions.Complete[T](Object sender, > > > > > >> >>> SocketAsyncEventArgs args, Boolean throwOnError, T result) > > > > > >> >>> at Amqp.TcpTransport.TcpSocket.<>c.<.ctor>b__6_1(Object s, > > > > > >> >>> SocketAsyncEventArgs a) > > > > > >> >>> at > > > > System.Threading.ExecutionContext.RunInternal(ExecutionContext > > > > > >> >>> executionContext, ContextCallback callback, Object state) > > > > > >> >>> at > > > > > >> >> System.Net.Sockets.SocketAsyncEventArgs.<>c.<.cctor>b__174_0(UInt32 > > > > > >> >>> errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped) > > > > > >> >>> at > > > > > >> >> > > > > System.Threading.PortableThreadPool.IOCompletionPoller.Event.Invoke() > > > > > >> >>> at > > > > > >> >> > > > > > >> > > > > System.Threading.ThreadPoolTypedWorkItemQueue.System.Threading.IThreadPoolWorkItem.Execute() > > > > > >> >>> at System.Threading.ThreadPoolWorkQueue.Dispatch() > > > > > >> >>> at > > > > > >> >> > > > > System.Threading.PortableThreadPool.WorkerThread.WorkerThreadStart() > > > > > >> >>> at System.Threading.Thread.StartCallback() > > > > > >> >>> > > > > > >> >>> --- End of inner exception stack trace --- > > > > > >> >>> at > > > > > >> Apache.NMS.AMQP.NmsConnection.CreateNmsConnectionInternal(Boolean > > > > > >> >> sync) > > > > > >> >>> at > > > > > >> >> > > > > > >> > > > > Apache.NMS.AMQP.Util.Synchronization.TaskExtensions.AwaitRunContinuationAsync(Task > > > > > >> >>> task) > > > > > >> >>> at Apache.NMS.AMQP.NmsConnection.StartAsync() > > > > > >> >>> at > > > > > >> >> > > > > Apache.NMS.AMQP.Util.Synchronization.TaskExtensions.GetAsyncResult(Task > > > > > >> >>> task) > > > > > >> >>> at Apache.NMS.AMQP.NmsConnection.Start() > > > > > >> >>> > > > > > >> >>> > > > > > >> >>> > > > > > >> >>> > > > > > >> >>> On Tue, Mar 10, 2026 at 4:48 PM Timothy Bish > > > > > >> >>> <[email protected] > > > > > > > > > > >> >> wrote: > > > > > >> >>>> On 3/10/26 19:42, John wrote: > > > > > >> >>>>> Hi Tim, > > > > > >> >>>>> > > > > > >> >>>>> Yes, each client has a unique Client ID. And this has been > > > > verified. > > > > > >> >>>>> However, should the Client ID follow a specific pattern? > > > > > >> >>>> That's your problem then, you are creating many uniquely > > > > identified > > > > > >> >>>> shared subscriptions. > > > > > >> >>>> > > > > > >> >>>> From the JMS specification > > > > > >> >>>> > > > > > >> >>>> "A shared non-durable subscription is identified by a name > > > > specified > > > > > >> by > > > > > >> >>>> the client and by the client > > > > > >> >>>> identifier if set. If the client identifier was set when the > > > > shared > > > > > >> >>>> non-durable subscription was first > > > > > >> >>>> created then a client which subsequently wishes to create a > > > > consumer > > > > > >> on > > > > > >> >>>> that shared non-durable > > > > > >> >>>> subscription must use the same client identifier." > > > > > >> >>>> > > > > > >> >>>> > > > > > >> >>>>> On Tue, Mar 10, 2026 at 4:17 PM Timothy Bish < > > > > [email protected]> > > > > > >> >> wrote: > > > > > >> >>>>>> On 3/10/26 18:51, John wrote: > > > > > >> >>>>>>> Hi, > > > > > >> >>>>>>> > > > > > >> >>>>>>> I have stumbled across an issue that I believe is with > > > > > >> >> Apache.NMS.AMQP > > > > > >> >>>>>>> library. I'm using the latest stable version, 2.4.0, for my > > > > .NET > > > > > >> C# > > > > > >> >>>>>> service > > > > > >> >>>>>>> for message handling, with the latest Apache Artemis and > > > > Apache > > > > > >> >> ActiveMQ > > > > > >> >>>>>>> message brokers. > > > > > >> >>>>>>> Both the web page on Uri Configuration ( > > > > > >> >>>>>>> > > > > > >> >> > > > > > >> > > > > https://activemq.apache.org/components/nms/providers/amqp/uri-configuration > > > > > >> >>>>>> ) > > > > > >> >>>>>>> and the GitHub project ( > > > > > >> >>>>>>> > > > > > >> >> > > > > > >> > > > > https://github.com/apache/activemq-nms-amqp/blob/main/docs/configuration.md > > > > > >> >>>>>> ) > > > > > >> >>>>>>> state that "nms.clientId" should be used in the Connection > > > > Uri to > > > > > >> >>>>>> configure > > > > > >> >>>>>>> the Client ID. > > > > > >> >>>>>>> However, I have found that using "nms.clientId" breaks > > > > consumer > > > > > >> >>>>>>> functionality for Shared Consumers, who will then receive > > > > every > > > > > >> >> message > > > > > >> >>>>>> in > > > > > >> >>>>>>> the topic. And that, excluding the query parameter, allows > > > > Shared > > > > > >> >>>>>> Consumers > > > > > >> >>>>>>> to function correctly, with each consumer receiving only > > > > > >> >>>>>>> their > > > > > >> share > > > > > >> >> of > > > > > >> >>>>>> the > > > > > >> >>>>>>> messages. > > > > > >> >>>>>>> Please also note that if one does not include the parameter > > > > in the > > > > > >> >> Uri > > > > > >> >>>>>> but > > > > > >> >>>>>>> instead sets the ClientId on the connection object itself, > > > > > >> >>>>>>> the > > > > > >> Shared > > > > > >> >>>>>>> Customer will still not function correctly, having the same > > > > issue > > > > > >> as > > > > > >> >>>>>> using > > > > > >> >>>>>>> the parameter in the Uri. > > > > > >> >>>>>>> However, by not including the nms.clientId parameter, a > > > > Client ID > > > > > >> is > > > > > >> >>>>>>> automatically generated, which I guess is why it works > > > > correctly. > > > > > >> >>>>>>> Nevertheless, it is less than ideal not being able to use > > > > > >> >>>>>>> my > > > > own > > > > > >> >> Client > > > > > >> >>>>>> ID. > > > > > >> >>>>>>> But maybe I'm doing something wrong. Here is some simple > > > > example > > > > > >> code > > > > > >> >>>>>> using > > > > > >> >>>>>>> the nms.clientId parameter that has the issue: > > > > > >> >>>>>>> > > > > > >> >>>>>>> static async Task SharedAsync(string clientId, > > > > CancellationToken > > > > > >> >>>>>>> stoppingToken) > > > > > >> >>>>>>> { > > > > > >> >>>>>>> string uri = > > > > > >> >>>>>>> > > > > > >> >> > > > > > >> > > > > $"amqp://localhost:61616?nms.username=artemis&nms.password=artemis&nms.clientId={clientId}"; > > > > > >> >>>>>> Are you giving each client the same ID or are they each > > > > > >> >>>>>> being > > > > > >> assigned > > > > > >> >>>>>> there own unique client ID ? > > > > > >> >>>>>> > > > > > >> >>>>>> > > > > > >> >>>>>>> var connecturi = new Uri(uri); > > > > > >> >>>>>>> var factory = new NMSConnectionFactory(connecturi); > > > > > >> >>>>>>> using IConnection connection = await > > > > > >> >>>>>> factory.CreateConnectionAsync(); > > > > > >> >>>>>>> connection.Start(); > > > > > >> >>>>>>> using ISession session = await > > > > > >> >> connection.CreateSessionAsync(); > > > > > >> >>>>>>> ITopic destination = await > > > > > >> >> session.GetTopicAsync("topic-name"); > > > > > >> >>>>>>> using var consumer = await > > > > > >> >>>>>>> session.CreateSharedConsumerAsync(destination, "sub-name"); > > > > > >> >>>>>>> while (!stoppingToken.IsCancellationRequested) > > > > > >> >>>>>>> { > > > > > >> >>>>>>> var msg = await > > > > > >> >>>>>>> consumer.ReceiveAsync(TimeSpan.FromMicroseconds(250)) as > > > > > >> >> ITextMessage; > > > > > >> >>>>>>> if (msg is not null) > > > > > >> >>>>>>> { > > > > > >> >>>>>>> // process message > > > > > >> >>>>>>> } > > > > > >> >>>>>>> } > > > > > >> >>>>>>> } > > > > > >> >>>>>>> > > > > > >> >>>>>>> > > > > > >> >>>>>>> Thanks, > > > > > >> >>>>>>> John > > > > > >> >>>>>>> > > > > > >> >>>>>> -- > > > > > >> >>>>>> Tim Bish > > > > > >> >>>>>> > > > > > >> >>>>>> > > > > > >> >>>>>> > > > > > >> --------------------------------------------------------------------- > > > > > >> >>>>>> To unsubscribe, e-mail: > > > > > >> >>>>>> [email protected] > > > > > >> >>>>>> For additional commands, e-mail: > > > > [email protected] > > > > > >> >>>>>> For further information, visit: > > > > > >> https://activemq.apache.org/contact > > > > > >> >>>>>> > > > > > >> >>>>>> > > > > > >> >>>>>> > > > > > >> >>>> -- > > > > > >> >>>> Tim Bish > > > > > >> >>>> > > > > > >> >>>> > > > > > >> >>>> > > > > --------------------------------------------------------------------- > > > > > >> >>>> To unsubscribe, e-mail: [email protected] > > > > > >> >>>> For additional commands, e-mail: > > > > > >> >>>> [email protected] > > > > > >> >>>> For further information, visit: > > > > https://activemq.apache.org/contact > > > > > >> >>>> > > > > > >> >>>> > > > > > >> >>> > > > > --------------------------------------------------------------------- > > > > > >> >>> To unsubscribe, e-mail: [email protected] > > > > > >> >>> For additional commands, e-mail: [email protected] > > > > > >> >>> For further information, visit: > > > > https://activemq.apache.org/contact > > > > > >> >>> > > > > > >> >>> > > > > > >> >> -- > > > > > >> >> Tim Bish > > > > > >> >> > > > > > >> >> > > > > > >> >> > > > > --------------------------------------------------------------------- > > > > > >> >> To unsubscribe, e-mail: [email protected] > > > > > >> >> For additional commands, e-mail: [email protected] > > > > > >> >> For further information, visit: > > > > https://activemq.apache.org/contact > > > > > >> >> > > > > > >> >> > > > > > >> >> > > > > > >> > > > > > >> -- > > > > > >> Tim Bish > > > > > >> > > > > > >> > > > > > >> --------------------------------------------------------------------- > > > > > >> To unsubscribe, e-mail: [email protected] > > > > > >> For additional commands, e-mail: [email protected] > > > > > >> For further information, visit: https://activemq.apache.org/contact > > > > > >> > > > > > >> > > > > > >> > > > > > > > > --------------------------------------------------------------------- > > > > To unsubscribe, e-mail: [email protected] > > > > For additional commands, e-mail: [email protected] > > > > For further information, visit: https://activemq.apache.org/contact > > > > > > > > > > > > > > > > --------------------------------------------------------------------- > > To unsubscribe, e-mail: [email protected] > > For additional commands, e-mail: [email protected] > > For further information, visit: https://activemq.apache.org/contact > > > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [email protected] > For additional commands, e-mail: [email protected] > For further information, visit: https://activemq.apache.org/contact > > --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected] For further information, visit: https://activemq.apache.org/contact
