[ 
https://issues.apache.org/jira/browse/JAMES-4238?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18129894#comment-18129894
 ] 

Benoit Tellier commented on JAMES-4238:
---------------------------------------

Hello Felix

Really nice findings this narrows it a lot.

My feeling is that we need to prevent concurrent access in the first place.

Here are some thoughts:
 - locks don't seem like a good idea ( performance collapse under load, do not 
play well with blocking stuff in reactor)
 - other option ThreadLocal means we would have a lot of sessions... Not 
optimal either.
 - opening a new session each time, if i's cheap ?
 - or maybe better, do session pooling and we have an exemple in RemoteDelivery 
(DeliverMailToHost maybe)

I'd be encline to give a go at pooling. I can piece something but more sunday: 
feel free to give that fix a try!

Best regards

Benoit

> Artemis Invalid concurrent session usage
> ----------------------------------------
>
>                 Key: JAMES-4238
>                 URL: https://issues.apache.org/jira/browse/JAMES-4238
>             Project: James Server
>          Issue Type: Bug
>          Components: Queue
>    Affects Versions: 3.10
>            Reporter: Felix Auringer
>            Priority: Major
>
> The new embedded MailQueue implementation of James uses one session 
> concurrently in multiple threads. This is not supported behavior.
> In our instance, the corresponding warning appears maybe a dozen times per 
> day but we have already set the threads for spooler and mail delivery to 1.
> If concurrent access occurs, there is a warning in the logs:
>  
> {code:java}
> Oct 21 17:17:01 2026-10-21T17:17:01.230Z [WARN ] 
> org.apache.activemq.artemis.core.client - AMQ212051: Invalid concurrent 
> session usage. Sessions are not supposed to be used by more than one thread 
> concurrently.
> Oct 21 17:17:01 java.lang.Exception: trace
> Oct 21 17:17:01         at 
> org.apache.activemq.artemis.core.client.impl.ClientSessionImpl.startCall(ClientSessionImpl.java:1492)
> Oct 21 17:17:01         at 
> org.apache.activemq.artemis.core.client.impl.ClientProducerImpl.doSend(ClientProducerImpl.java:223)
> Oct 21 17:17:01         at 
> org.apache.activemq.artemis.core.client.impl.ClientProducerImpl.send(ClientProducerImpl.java:142)
> Oct 21 17:17:01         at 
> org.apache.activemq.artemis.core.client.impl.ClientProducerImpl.send(ClientProducerImpl.java:124)
> Oct 21 17:17:01         at 
> org.apache.activemq.artemis.jms.client.ActiveMQMessageProducer.doSendx(ActiveMQMessageProducer.java:483)
> Oct 21 17:17:01         at 
> org.apache.activemq.artemis.jms.client.ActiveMQMessageProducer.send(ActiveMQMessageProducer.java:203)
> Oct 21 17:17:01         at 
> org.apache.james.queue.jms.JMSCacheableMailQueue.produceMail(JMSCacheableMailQueue.java:401)
> Oct 21 17:17:01         at 
> org.apache.james.queue.jms.JMSCacheableMailQueue.enQueue(JMSCacheableMailQueue.java:340)
> Oct 21 17:17:01         at 
> org.apache.james.queue.api.MailQueue.enQueue(MailQueue.java:103)
> Oct 21 17:17:01         at 
> org.apache.james.queue.jms.JMSCacheableMailQueue.enQueue(JMSCacheableMailQueue.java:369)
> Oct 21 17:17:01         at 
> org.apache.james.smtpserver.SendMailHandler.lambda$onMessage$4(SendMailHandler.java:117)
> Oct 21 17:17:01         at 
> com.github.fge.lambdas.runnable.RunnableChainer.doRun(RunnableChainer.java:18)
> Oct 21 17:17:01         at 
> com.github.fge.lambdas.runnable.ThrowingRunnable.run(ThrowingRunnable.java:16)
> Oct 21 17:17:01         at 
> java.base/java.util.Optional.ifPresentOrElse(Unknown Source)
> Oct 21 17:17:01         at 
> org.apache.james.smtpserver.SendMailHandler.onMessage(SendMailHandler.java:89)
> Oct 21 17:17:01         at 
> org.apache.james.smtpserver.DataLineJamesMessageHookHandler.executeJamesMessageHooks(DataLineJamesMessageHookHandler.java:216)
> Oct 21 17:17:01         at 
> org.apache.james.smtpserver.DataLineJamesMessageHookHandler.processExtensions(DataLineJamesMessageHookHandler.java:198)
> Oct 21 17:17:01         at 
> org.apache.james.smtpserver.DataLineJamesMessageHookHandler.onLine(DataLineJamesMessageHookHandler.java:115)
> Oct 21 17:17:01         at 
> org.apache.james.protocols.smtp.core.DataCmdHandler$DataLineFilterWrapper.onLine(DataCmdHandler.java:87)
> Oct 21 17:17:01         at 
> org.apache.james.protocols.smtp.core.DataCmdHandler$DataLineFilterWrapper.onLine(DataCmdHandler.java:75)
> Oct 21 17:17:01         at 
> org.apache.james.protocols.smtp.core.SeparatingDataLineFilter.onBodyLine(SeparatingDataLineFilter.java:100)
> Oct 21 17:17:01         at 
> org.apache.james.protocols.smtp.core.SeparatingDataLineFilter.onLine(SeparatingDataLineFilter.java:58)
> Oct 21 17:17:01         at 
> org.apache.james.protocols.smtp.core.DataCmdHandler$DataLineFilterWrapper.onLine(DataCmdHandler.java:87)
> Oct 21 17:17:01         at 
> org.apache.james.protocols.smtp.core.DataCmdHandler$DataLineFilterWrapper.onLine(DataCmdHandler.java:75)
> Oct 21 17:17:01         at 
> org.apache.james.protocols.smtp.core.esmtp.MailSizeEsmtpExtension.onLine(MailSizeEsmtpExtension.java:158)
> Oct 21 17:17:01         at 
> org.apache.james.protocols.smtp.core.DataCmdHandler$DataLineFilterWrapper.onLine(DataCmdHandler.java:87)
> Oct 21 17:17:01         at 
> org.apache.james.protocols.smtp.core.DataCmdHandler$DataLineFilterWrapper.onLine(DataCmdHandler.java:75)
> Oct 21 17:17:01         at 
> org.apache.james.protocols.netty.LineHandlerUpstreamHandler.channelRead(LineHandlerUpstreamHandler.java:52)
> Oct 21 17:17:01         at 
> org.apache.james.protocols.netty.BasicChannelInboundHandler.channelRead(BasicChannelInboundHandler.java:182)
> Oct 21 17:17:01         at 
> io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444)
> Oct 21 17:17:01         at 
> io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
> Oct 21 17:17:01         at 
> io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
> Oct 21 17:17:01         at 
> io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:361)
> Oct 21 17:17:01         at 
> io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:325)
> Oct 21 17:17:01         at 
> io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444)
> Oct 21 17:17:01         at 
> io.netty.channel.AbstractChannelHandlerContext.access$600(AbstractChannelHandlerContext.java:61)
> Oct 21 17:17:01         at 
> io.netty.channel.AbstractChannelHandlerContext$7.run(AbstractChannelHandlerContext.java:425)
> Oct 21 17:17:01         at 
> io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:173)
> Oct 21 17:17:01         at 
> io.netty.util.concurrent.DefaultEventExecutor.run(DefaultEventExecutor.java:66)
> Oct 21 17:17:01         at 
> io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:998)
> Oct 21 17:17:01         at 
> io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
> Oct 21 17:17:01         at java.base/java.lang.Thread.run(Unknown 
> Source){code}
>  
> This warning itself seems to be harmless in most cases.
> However, if the following warning is directly after it, the queue is left in 
> an invalid state:
> {code:java}
> Oct 21 17:17:01 2026-10-21T17:17:01.232Z [WARN ] 
> org.apache.activemq.artemis.core.server - AMQ222106: Replacing incomplete 
> LargeMessage with ID=23623536710{code}
> After this has been logged, James is not able to dequeue messages anymore. No 
> email can leave the spool or outgoing queue anymore. New emails can still be 
> spooled. Without manual intervention, James does not recover from this.
> When James tries to dequeue a message, the following error is thrown and the 
> operation fails:
> {code:java}
> 2026-10-19T15:05:13.235Z ESC[1;31m[ERROR]ESC[0;39m 
> reactor.core.publisher.Operators - Operator called default onErrorDropped
> java.lang.NullPointerException: Cannot read the array length because 
> "<parameter1>" is null
>         at java.base/java.io.ByteArrayInputStream.<init>(Unknown Source)
>         at 
> jakarta.mail.util.SharedByteArrayInputStream.<init>(SharedByteArrayInputStream.java:46)
>         at 
> org.apache.james.queue.jms.MimeMessageObjectMessageSource.<init>(MimeMessageObjectMessageSource.java:52)
>         at 
> org.apache.james.queue.jms.JMSCacheableMailQueue.mimeMessage(JMSCacheableMailQueue.java:466)
>         at 
> org.apache.james.queue.jms.JMSCacheableMailQueue.createMail(JMSCacheableMailQueue.java:453)
>         at 
> org.apache.james.queue.jms.JMSCacheableMailQueue.createMailQueueItem(JMSCacheableMailQueue.java:592)
>         at 
> org.apache.james.queue.jms.JMSCacheableMailQueue.deQueueOneItem(JMSCacheableMailQueue.java:298)
>         ... 12 common frames omitted
> Wrapped by: org.apache.james.queue.api.MailQueue$MailQueueException: Unable 
> to dequeue next message;
>   nested exception is:
>         java.lang.NullPointerException: Cannot read the array length because 
> "<parameter1>" is null
>         at 
> org.apache.james.queue.jms.JMSCacheableMailQueue.deQueueOneItem(JMSCacheableMailQueue.java:312)
>         at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:45)
>         at 
> reactor.core.publisher.FluxRepeatPredicate$RepeatPredicateSubscriber.resubscribe(FluxRepeatPredicate.java:120)
>         at 
> reactor.core.publisher.MonoRepeatPredicate.subscribeOrReturn(MonoRepeatPredicate.java:48)
>         at 
> reactor.core.publisher.InternalFluxOperator.subscribe(InternalFluxOperator.java:55)
>         at 
> reactor.core.publisher.FluxSubscribeOn$SubscribeOnSubscriber.run(FluxSubscribeOn.java:194)
>         at reactor.core.scheduler.WorkerTask.call(WorkerTask.java:84)
>         at reactor.core.scheduler.WorkerTask.call(WorkerTask.java:37)
>         at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
>         at 
> java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown
>  Source)
>         at 
> java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
>         at 
> java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
>         at java.base/java.lang.Thread.run(Unknown Source)
> Wrapped by: reactor.core.Exceptions$ErrorCallbackNotImplemented: 
> org.apache.james.queue.api.MailQueue$MailQueueException: Unable to dequeue 
> next message;
>   nested exception is:
>         java.lang.NullPointerException: Cannot read the array length because 
> "<parameter1>" is null{code}



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to