I'm still investigating the cause of premature and sproradic session closure in my tests. However I want to point that RabbitMQ does support several links per session. My original impression was wrong. Either way need to figure out how to pull RabbitMQ logs from Testcontainers when that test fails.
On Mon, Mar 30, 2026 at 2:36 PM Timothy Bish <[email protected]> wrote: > I don't really know anything about the RabbitMQ implementation so I cannot > really provide any insights into why it closed the session but I would > guess that is the cause of your failed test, it might be sporadic due to > this being something that happens after your test is done or in the > process of closing down so it only gets seems sometimes. > > This is where your session was closed by the remote so I'd suggest looking > into why you might get the specific error and session closure. > <- AMQP:[310426339:0] > End{error=Error{condition=amqp:session:unattached-handle, > description='Unattached link handle: 2', info=null}} > -> AMQP:[310426339:0] End{error=null} > > The protonj2 client allows you to manage sessions as you like so if > Rabbit needs a session per producer or consumer that is definitely > something you can do, if you are using the connection level APIs to create > them you would already be using a single session for the entirety of the > connection's resources. > > On Mon, Mar 30, 2026 at 1:05 PM Artem Bilan via users < > [email protected]> wrote: > >> Hi Tim! >> Thank you for the tip! >> I added that tracing for frames, however it does not say me too much. >> Just test sporadically fails like with this trace: >> >> -> SASL:[310426339:0] AMQP,3,1,0,0 >> <- SASL:[310426339:0] AMQP,3,1,0,0 >> <- SASL:[310426339:0] SaslMechanisms{saslServerMechanisms=[PLAIN, >> AMQPLAIN, ANONYMOUS]} >> 2026-03-28 05:35:21,659 WARN >> org.apache.qpid.protonj2.engine.sasl.client.SaslMechanismSelector >> [ClientConnection :(ID:a54be302-d329-4598-8bfc-55b1cfed2e33:1:1): I/O >> Thread] : Caught exception while trying to create SASL mechanism AMQPLAIN: >> No Matching SASL Mechanism with name: AMQPLAIN >> -> SASL:[310426339:0] SaslInit{mechanism=ANONYMOUS, initialResponse="", >> hostname='localhost'} >> <- SASL:[310426339:0] SaslOutcome{code=OK, additionalData=null} >> -> AMQP:[310426339:0] AMQP,0,1,0,0 >> <- AMQP:[310426339:0] AMQP,0,1,0,0 >> -> AMQP:[310426339:0] Open{ >> containerId='ID:a54be302-d329-4598-8bfc-55b1cfed2e33:1:1', >> hostname='localhost', maxFrameSize=65536, channelMax=65535, >> idleTimeOut=30000, outgoingLocales=null, incomingLocales=null, >> offeredCapabilities=null, desiredCapabilities=[ANONYMOUS-RELAY], >> properties=null} >> -> AMQP:[310426339:0] Begin{remoteChannel=null, nextOutgoingId=0, >> incomingWindow=1600, outgoingWindow=2147483647, handleMax=null, >> offeredCapabilities=null, desiredCapabilities=null, properties=null} >> -> AMQP:[310426339:0] >> Attach{name='receiver-ID:a54be302-d329-4598-8bfc-55b1cfed2e33:1:1:1:1', >> handle=0, role=RECEIVER, sndSettleMode=UNSETTLED, rcvSettleMode=FIRST, >> source=Source{address='/queues/enable_amqp_queue1', durable=NONE, >> expiryPolicy=LINK_DETACH, timeout=0, dynamic=false, >> dynamicNodeProperties=null, distributionMode=null, filter=null, >> defaultOutcome=Modified{deliveryFailed=true, undeliverableHere=false, >> messageAnnotations=null}, outcomes=[amqp:accepted:list, amqp:rejected:list, >> amqp:released:list, amqp:modified:list], capabilities=null}, >> target=Target{address='/queues/enable_amqp_queue1', durable=NONE, >> expiryPolicy=SESSION_END, timeout=0, dynamic=false, >> dynamicNodeProperties=null, capabilities=null}, unsettled=null, >> incompleteUnsettled=null, initialDeliveryCount=null, maxMessageSize=null, >> offeredCapabilities=null, desiredCapabilities=null, properties=null} >> -> AMQP:[310426339:0] Flow{nextIncomingId=null, incomingWindow=1600, >> nextOutgoingId=0, outgoingWindow=2147483647, handle=0, deliveryCount=null, >> linkCredit=55, available=null, drain=false, echo=null, properties=null} >> -> AMQP:[310426339:0] >> Attach{name='receiver-ID:a54be302-d329-4598-8bfc-55b1cfed2e33:1:1:1:2', >> handle=1, role=RECEIVER, sndSettleMode=UNSETTLED, rcvSettleMode=FIRST, >> source=Source{address='/queues/enable_amqp_queue1', durable=NONE, >> expiryPolicy=LINK_DETACH, timeout=0, dynamic=false, >> dynamicNodeProperties=null, distributionMode=null, filter=null, >> defaultOutcome=Modified{deliveryFailed=true, undeliverableHere=false, >> messageAnnotations=null}, outcomes=[amqp:accepted:list, amqp:rejected:list, >> amqp:released:list, amqp:modified:list], capabilities=null}, >> target=Target{address='/queues/enable_amqp_queue1', durable=NONE, >> expiryPolicy=SESSION_END, timeout=0, dynamic=false, >> dynamicNodeProperties=null, capabilities=null}, unsettled=null, >> incompleteUnsettled=null, initialDeliveryCount=null, maxMessageSize=null, >> offeredCapabilities=null, desiredCapabilities=null, properties=null} >> -> AMQP:[310426339:0] Flow{nextIncomingId=null, incomingWindow=1600, >> nextOutgoingId=0, outgoingWindow=2147483647, handle=1, deliveryCount=null, >> linkCredit=55, available=null, drain=false, echo=null, properties=null} >> -> AMQP:[310426339:0] >> Attach{name='receiver-ID:a54be302-d329-4598-8bfc-55b1cfed2e33:1:1:1:3', >> handle=2, role=RECEIVER, sndSettleMode=UNSETTLED, rcvSettleMode=FIRST, >> source=Source{address='/queues/enable_amqp_queue1', durable=NONE, >> expiryPolicy=LINK_DETACH, timeout=0, dynamic=false, >> dynamicNodeProperties=null, distributionMode=null, filter=null, >> defaultOutcome=Modified{deliveryFailed=true, undeliverableHere=false, >> messageAnnotations=null}, outcomes=[amqp:accepted:list, amqp:rejected:list, >> amqp:released:list, amqp:modified:list], capabilities=null}, >> target=Target{address='/queues/enable_amqp_queue1', durable=NONE, >> expiryPolicy=SESSION_END, timeout=0, dynamic=false, >> dynamicNodeProperties=null, capabilities=null}, unsettled=null, >> incompleteUnsettled=null, initialDeliveryCount=null, maxMessageSize=null, >> offeredCapabilities=null, desiredCapabilities=null, properties=null} >> -> AMQP:[310426339:0] Flow{nextIncomingId=null, incomingWindow=1600, >> nextOutgoingId=0, outgoingWindow=2147483647, handle=2, deliveryCount=null, >> linkCredit=55, available=null, drain=false, echo=null, properties=null} >> <- AMQP:[310426339:0] Open{ containerId='rabbit@69e87c0daa99', >> hostname='null', maxFrameSize=131072, channelMax=63, idleTimeOut=30000, >> outgoingLocales=null, incomingLocales=null, >> offeredCapabilities=[LINK_PAIR_V1_0, ANONYMOUS-RELAY], >> desiredCapabilities=null, properties={node=rabbit@69e87c0daa99, >> cluster_name=rabbit@69e87c0daa99, copyright=Copyright (c) 2007-2026 >> Broadcom Inc and/or its subsidiaries, information=Licensed under the MPL >> 2.0. Website: https://rabbitmq.com, platform=Erlang/OTP 27.3.4.9, >> product=RabbitMQ, version=4.2.5}} >> <- AMQP:[310426339:0] Begin{remoteChannel=0, nextOutgoingId=0, >> incomingWindow=400, outgoingWindow=4294967295, handleMax=255, >> offeredCapabilities=null, desiredCapabilities=null, properties=null} >> -> AMQP:[310426339:0] >> Attach{name='sender-ID:a54be302-d329-4598-8bfc-55b1cfed2e33:1:1:1:1', >> handle=3, role=SENDER, sndSettleMode=UNSETTLED, rcvSettleMode=FIRST, >> source=Source{address='null', durable=NONE, expiryPolicy=LINK_DETACH, >> timeout=0, dynamic=false, dynamicNodeProperties=null, >> distributionMode=null, filter=null, defaultOutcome=null, >> outcomes=[amqp:accepted:list, amqp:rejected:list, amqp:released:list, >> amqp:modified:list], capabilities=null}, target=Target{address='null', >> durable=NONE, expiryPolicy=SESSION_END, timeout=0, dynamic=false, >> dynamicNodeProperties=null, capabilities=null}, unsettled=null, >> incompleteUnsettled=null, initialDeliveryCount=0, maxMessageSize=null, >> offeredCapabilities=null, desiredCapabilities=null, properties=null} >> <- AMQP:[310426339:0] >> Attach{name='receiver-ID:a54be302-d329-4598-8bfc-55b1cfed2e33:1:1:1:1', >> handle=0, role=SENDER, sndSettleMode=UNSETTLED, rcvSettleMode=FIRST, >> source=Source{address='/queues/enable_amqp_queue1', durable=NONE, >> expiryPolicy=LINK_DETACH, timeout=0, dynamic=false, >> dynamicNodeProperties=null, distributionMode=null, filter=null, >> defaultOutcome=Released{}, outcomes=[amqp:accepted:list, >> amqp:rejected:list, amqp:released:list, amqp:modified:list], >> capabilities=null}, target=null, unsettled=null, incompleteUnsettled=null, >> initialDeliveryCount=0, maxMessageSize=null, offeredCapabilities=null, >> desiredCapabilities=null, properties=null} >> <- AMQP:[310426339:0] >> Attach{name='receiver-ID:a54be302-d329-4598-8bfc-55b1cfed2e33:1:1:1:2', >> handle=1, role=SENDER, sndSettleMode=UNSETTLED, rcvSettleMode=FIRST, >> source=Source{address='/queues/enable_amqp_queue1', durable=NONE, >> expiryPolicy=LINK_DETACH, timeout=0, dynamic=false, >> dynamicNodeProperties=null, distributionMode=null, filter=null, >> defaultOutcome=Released{}, outcomes=[amqp:accepted:list, >> amqp:rejected:list, amqp:released:list, amqp:modified:list], >> capabilities=null}, target=null, unsettled=null, incompleteUnsettled=null, >> initialDeliveryCount=0, maxMessageSize=null, offeredCapabilities=null, >> desiredCapabilities=null, properties=null} >> <- AMQP:[310426339:0] >> Attach{name='receiver-ID:a54be302-d329-4598-8bfc-55b1cfed2e33:1:1:1:3', >> handle=2, role=SENDER, sndSettleMode=UNSETTLED, rcvSettleMode=FIRST, >> source=Source{address='/queues/enable_amqp_queue1', durable=NONE, >> expiryPolicy=LINK_DETACH, timeout=0, dynamic=false, >> dynamicNodeProperties=null, distributionMode=null, filter=null, >> defaultOutcome=Released{}, outcomes=[amqp:accepted:list, >> amqp:rejected:list, amqp:released:list, amqp:modified:list], >> capabilities=null}, target=null, unsettled=null, incompleteUnsettled=null, >> initialDeliveryCount=0, maxMessageSize=null, offeredCapabilities=null, >> desiredCapabilities=null, properties=null} >> <- AMQP:[310426339:0] >> Attach{name='sender-ID:a54be302-d329-4598-8bfc-55b1cfed2e33:1:1:1:1', >> handle=3, role=RECEIVER, sndSettleMode=UNSETTLED, rcvSettleMode=FIRST, >> source=Source{address='null', durable=NONE, expiryPolicy=LINK_DETACH, >> timeout=0, dynamic=false, dynamicNodeProperties=null, >> distributionMode=null, filter=null, defaultOutcome=null, >> outcomes=[amqp:accepted:list, amqp:rejected:list, amqp:released:list, >> amqp:modified:list], capabilities=null}, target=Target{address='null', >> durable=NONE, expiryPolicy=SESSION_END, timeout=0, dynamic=false, >> dynamicNodeProperties=null, capabilities=null}, unsettled=null, >> incompleteUnsettled=null, initialDeliveryCount=null, >> maxMessageSize=16777216, offeredCapabilities=null, >> desiredCapabilities=null, properties=null} >> <- AMQP:[310426339:0] Flow{nextIncomingId=0, incomingWindow=400, >> nextOutgoingId=0, outgoingWindow=4294967295, handle=3, deliveryCount=0, >> linkCredit=170, available=null, drain=null, echo=null, properties=null} >> -> AMQP:[310426339:0] Transfer{handle=3, deliveryId=0, deliveryTag={0}, >> messageFormat=0, settled=false, more=false, rcvSettleMode=null, state=null, >> resume=null, aborted=null, batchable=null} - >> "\x00Sp\xc0\x04\x02AP\x00\x00Ss\xd0\x00\x00\x00B\x00\x00\x00\x0a@ >> "...(truncated) >> <- AMQP:[310426339:0] Transfer{handle=0, deliveryId=0, >> deliveryTag=DeliveryTag: {[0, 0, 0, 0]}, messageFormat=0, settled=false, >> more=false, rcvSettleMode=null, state=null, resume=null, aborted=null, >> batchable=null} - "\x00Sp\xc0\x07\x05AP\x00@AC >> \x00Sr\xc12\x04\xa3\x0ax-exchange\xa1"...(truncated) >> <- AMQP:[310426339:0] Disposition{role=RECEIVER, first=0, last=0, >> settled=true, state=Accepted{}, batchable=false} >> -> AMQP:[310426339:0] Flow{nextIncomingId=1, incomingWindow=1600, >> nextOutgoingId=1, outgoingWindow=2147483647, handle=0, deliveryCount=1, >> linkCredit=0, available=null, drain=false, echo=null, properties=null} >> -> AMQP:[310426339:0] Detach{handle=0, closed=true, error=null} >> -> AMQP:[310426339:0] Flow{nextIncomingId=1, incomingWindow=1600, >> nextOutgoingId=1, outgoingWindow=2147483647, handle=1, deliveryCount=0, >> linkCredit=0, available=null, drain=false, echo=null, properties=null} >> <- AMQP:[310426339:0] Detach{handle=0, closed=true, error=null} >> -> AMQP:[310426339:0] Flow{nextIncomingId=1, incomingWindow=1600, >> nextOutgoingId=1, outgoingWindow=2147483647, handle=2, deliveryCount=0, >> linkCredit=0, available=null, drain=false, echo=null, properties=null} >> <- AMQP:[310426339:0] Transfer{handle=1, deliveryId=1, >> deliveryTag=DeliveryTag: {[0, 0, 0, 0]}, messageFormat=0, settled=false, >> more=false, rcvSettleMode=null, state=null, resume=null, aborted=null, >> batchable=null} - "\x00Sp\xc0\x07\x05AP\x00@BC >> \x00Sr\xc12\x04\xa3\x0ax-exchange\xa1"...(truncated) >> -> AMQP:[310426339:0] Detach{handle=2, closed=true, error=null} >> <- AMQP:[310426339:0] Detach{handle=2, closed=true, error=null} >> -> AMQP:[310426339:0] Detach{handle=1, closed=true, error=null} >> <- AMQP:[310426339:0] >> End{error=Error{condition=amqp:session:unattached-handle, >> description='Unattached link handle: 2', info=null}} >> -> AMQP:[310426339:0] End{error=null} >> I don't know if that is the case, but might be that RabbitMQ requires >> explicit session management for consumer and/or producers. >> At the same time I saw somewhere that some AMQP brokers requires one >> session per connection... >> I might consider to add a session management into my components if that >> is the case. >> >> Any thoughts? >> >> Thank you very much! >> >> On 2026/03/26 14:40:32 Timothy Bish wrote: >> > On 3/25/26 11:59, Artem Bilan via users wrote: >> > > Hi there! >> > > >> > > I am developing Spring Framework client based on the QPid ProtonJ 2 >> > > Client: >> > > >> https://github.com/spring-projects/spring-amqp/tree/main/spring-amqp-client/src >> . >> > > >> > > One of my tests is sporadically failing like: >> > >> > Without an AMQP frame trace it is not possible to say why this is >> > failing, it is valid for the error to occur if the session is remotely >> > closed. The configuration guide in the docs explains how to enable >> frame >> > tracing, with that enabled you can see the frames that arrived around >> > the time this error occurs. >> > >> > >> https://github.com/apache/qpid-protonj2/blob/main/protonj2-client-docs/Configuration.md#logging >> > >> > >> > > >> > > Caused by: java.lang.IllegalStateException: Cannot create new >> Receiver >> > > from closed Session >> > > >> > > >> > > at >> > > >> org.apache.qpid.protonj2.engine.impl.ProtonSession.checkSessionClosed(ProtonSession.java:670) >> >> > > >> > > >> > > at >> > > >> org.apache.qpid.protonj2.engine.impl.ProtonSession.receiver(ProtonSession.java:396) >> >> > > >> > > >> > > at >> > > >> org.apache.qpid.protonj2.engine.impl.ProtonSession.receiver(ProtonSession.java:59) >> >> > > >> > > >> > > at >> > > >> org.apache.qpid.protonj2.client.impl.ClientReceiverBuilder.createReceiver(ClientReceiverBuilder.java:142) >> >> > > >> > > >> > > at >> > > >> org.apache.qpid.protonj2.client.impl.ClientReceiverBuilder.receiver(ClientReceiverBuilder.java:61) >> >> > > >> > > >> > > at >> > > >> org.apache.qpid.protonj2.client.impl.ClientSession.internalOpenReceiver(ClientSession.java:391) >> >> > > >> > > >> > > at >> > > >> org.apache.qpid.protonj2.client.impl.ClientConnection.lambda$openReceiver$3(ClientConnection.java:279) >> >> > > >> > > >> > > at >> > > >> io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:148) >> >> > > >> > > >> > > at >> > > >> io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:141) >> >> > > >> > > >> > > at >> > > >> io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:535) >> >> > > >> > > >> > > at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:405) >> > > >> > > at >> > > >> io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:1195) >> >> > > >> > > >> > > at >> > > >> io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) >> > > >> > > >> > > I have a single connection object per test suite lifecycle. >> > > The code I try to create a Receiver is like: >> > > ClientReceiver receiver = >> > > (ClientReceiver)connection.openReceiver(queue,receiverOptions) >> > > .addCredit(this.initialCredits); >> > > Which apparently leads to the shared internal session in that >> connection. >> > > >> > > The broker I test against is RabbitMQ 4.2. >> > > >> > > So, the question is: if I'm doing something wrong or missing anything. >> > > I also do have a reconnectEnabled on the connection. >> > > >> > > Please, let me know if you need anything else. >> > > >> > > Thank you! >> > > >> > > Regards, >> > > Artem Bilan >> > >> > >> > -- >> > Tim Bish >> > >> > > > -- > -- > Tim Bish > >
smime.p7s
Description: S/MIME Cryptographic Signature
