(geronimo-mail) 01/04: Dispose dequeued mails in the James test harness

[email protected] Sat, 18 Jul 2026 08:27:59 +0000
Newsgroups gmane.comp.java.geronimo.cvs
Message-ID <[email protected]>
This is an automated email from the ASF dual-hosted git repository.

rzo1 pushed a commit to branch mail-tck
in repository https://gitbox.apache.org/repos/asf/geronimo-mail.git

commit a2a1e8a31badde29f7f0932f7a8e6421cb67a070
Author: Richard Zowalla <[email protected]>
AuthorDate: Sat Jul 18 09:03:55 2026 +0200

    Dispose dequeued mails in the James test harness
    
    The mail returned by MailQueueItem.getMail() is a queue-side copy backed by
    a MimeMessageInputStreamSource; per the MailQueue contract the consumer owns
    it and must dispose it (see JamesMailSpooler). The harness never did, so
    James logged 'Leak detected' errors when the GC finalizer reclaimed the
    resources. Dispose the mail after done(), reject instead of retry on
    delivery failure, and close the queue on shutdown.
---
 .../org/apache/geronimo/mail/testserver/MailServer.java  | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/geronimo-mail_2.1_impl/geronimo-mail_2.1_provider/src/test/java/org/apache/geronimo/mail/testserver/MailServer.java b/geronimo-mail_2.1_impl/geronimo-mail_2.1_provider/src/test/java/org/apache/geronimo/mail/testserver/MailServer.java
index 6ee5d62..1a1d194 100644
--- a/geronimo-mail_2.1_impl/geronimo-mail_2.1_provider/src/test/java/org/apache/geronimo/mail/testserver/MailServer.java
+++ b/geronimo-mail_2.1_impl/geronimo-mail_2.1_provider/src/test/java/org/apache/geronimo/mail/testserver/MailServer.java
@@ -52,6 +52,7 @@ import org.apache.james.imap.processor.fetch.FetchProcessor;
 import org.apache.james.imap.processor.main.DefaultImapProcessorFactory;
 import org.apache.james.imapserver.netty.IMAPServer;
 import org.apache.james.imapserver.netty.ImapMetrics;
+import org.apache.james.lifecycle.api.LifecycleUtil;
 import org.apache.james.mailbox.Authorizator;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxSession;
@@ -91,6 +92,7 @@ import org.apache.james.smtpserver.netty.SmtpMetricsImpl;
 import org.apache.james.user.api.UsersRepository;
 import org.apache.james.user.api.UsersRepositoryException;
 import org.apache.james.user.memory.MemoryUsersRepository;
+import org.apache.mailet.Mail;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
@@ -191,8 +193,12 @@ public class MailServer {
     }
 
     private void deliver(final MailQueue.MailQueueItem item, final MessageManager mailbox, final MailboxSession session) {
+        // the dequeued mail (a queue-side copy backed by a MimeMessageInputStreamSource)
+        // is owned by the consumer and must be disposed, see the MailQueue contract and
+        // JamesMailSpooler for the canonical pattern
+        final Mail mail = item.getMail();
         try {
-            final MimeMessage msg = item.getMail().getMessage();
+            final MimeMessage msg = mail.getMessage();
             final ByteArrayOutputStream bout = new ByteArrayOutputStream();
             msg.writeTo(bout);
             mailbox.appendMessage(MessageManager.AppendCommand.builder().recent().build(bout.toByteArray()), session);
@@ -201,10 +207,12 @@ public class MailServer {
         } catch (final Exception e) {
             e.printStackTrace();
             try {
-                item.done(MailQueue.MailQueueItem.CompletionStatus.RETRY);
+                item.done(MailQueue.MailQueueItem.CompletionStatus.REJECT);
             } catch (final Exception ignored) {
                 // nothing left to do
             }
+        } finally {
+            LifecycleUtil.dispose(mail);
         }
     }
 
@@ -214,6 +222,10 @@ public class MailServer {
             fetcher.dispose();
         }
 
+        if (queue != null) {
+            queue.close();
+        }
+
         if (protocolHandlerChain != null) {
             protocolHandlerChain.dispose();
         }