(geronimo-mail) branch main updated: GERONIMO-6891 Fix IMAPFolder.renameTo reporting failure after a successful rename
[email protected] Sat, 18 Jul 2026 08:53:48 +0000
| Newsgroups | gmane.comp.java.geronimo.cvs |
|---|---|
| Message-ID | <178436482805.1665753.2283580097426125762@gitbox3-he-fi.apache.org> |
This is an automated email from the ASF dual-hosted git repository.
rzo1 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/geronimo-mail.git
The following commit(s) were added to refs/heads/main by this push:
new 7b72cd3 GERONIMO-6891 Fix IMAPFolder.renameTo reporting failure after a successful rename
7b72cd3 is described below
commit 7b72cd3b6463b3d4b30fa684abcd84fdd6b7e126
Author: Richard Zowalla <[email protected]>
AuthorDate: Sat Jul 18 10:53:27 2026 +0200
GERONIMO-6891
Fix IMAPFolder.renameTo reporting failure after a successful rename
---
.../geronimo/mail/store/imap/IMAPFolder.java | 11 +-
.../mail/store/imap/IMAPFolderRenameTest.java | 128 +++++++++++++++++++++
.../geronimo/mail/testserver/MailServer.java | 21 ++++
geronimo-mail_2.1_tck/src/tck/geronimo.jtx | 102 +---------------
4 files changed, 161 insertions(+), 101 deletions(-)
diff --git a/geronimo-mail_2.1_impl/geronimo-mail_2.1_provider/src/main/java/org/apache/geronimo/mail/store/imap/IMAPFolder.java b/geronimo-mail_2.1_impl/geronimo-mail_2.1_provider/src/main/java/org/apache/geronimo/mail/store/imap/IMAPFolder.java
index 779ff85..f228d24 100644
--- a/geronimo-mail_2.1_impl/geronimo-mail_2.1_provider/src/main/java/org/apache/geronimo/mail/store/imap/IMAPFolder.java
+++ b/geronimo-mail_2.1_impl/geronimo-mail_2.1_provider/src/main/java/org/apache/geronimo/mail/store/imap/IMAPFolder.java
@@ -587,12 +587,15 @@ public class IMAPFolder extends Folder implements UIDFolder, IMAPUntaggedRespons
IMAPConnection connection = getConnection();
try {
- // delete this one now.
+ // rename this one now.
connection.renameMailbox(fullname, f.getFullName());
- // we renamed, so get a fresh set of status
- refreshStatus(false);
+ // a folder with our old name no longer exists on the server, so
+ // any cached state is stale now. Do NOT query the server using the
+ // old name (e.g. via refreshStatus()) -- that would fail.
+ cachedStatus = null;
+ listInfo = null;
- // notify interested parties about the deletion.
+ // notify interested parties about the rename.
notifyFolderRenamedListeners(f);
return true;
} catch (MessagingException e) {
diff --git a/geronimo-mail_2.1_impl/geronimo-mail_2.1_provider/src/test/java/org/apache/geronimo/mail/store/imap/IMAPFolderRenameTest.java b/geronimo-mail_2.1_impl/geronimo-mail_2.1_provider/src/test/java/org/apache/geronimo/mail/store/imap/IMAPFolderRenameTest.java
new file mode 100644
index 0000000..bd7ba08
--- /dev/null
+++ b/geronimo-mail_2.1_impl/geronimo-mail_2.1_provider/src/test/java/org/apache/geronimo/mail/store/imap/IMAPFolderRenameTest.java
@@ -0,0 +1,128 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.geronimo.mail.store.imap;
+
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.Properties;
+
+import jakarta.mail.Folder;
+import jakarta.mail.Session;
+import jakarta.mail.Store;
+
+import org.apache.geronimo.mail.testserver.AbstractProtocolTest;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Regression test for IMAPFolder.renameTo against Apache James.
+ *
+ * renameTo used to refresh the folder status with a STATUS command issued
+ * under the OLD mailbox name right after a successful server-side RENAME.
+ * James answers that STATUS with a tagged NO ("Mailbox not found"), the
+ * resulting CommandFailedException was swallowed and renameTo returned
+ * false even though the mailbox had really been renamed. In the Jakarta
+ * Mail TCK this left the shared "test1" mailbox renamed for the remainder
+ * of the run, making ~90 subsequent tests fail with CommandFailedException
+ * when opening "test1" (SELECT/EXAMINE answered with "NO ... No such
+ * mailbox.").
+ */
+public class IMAPFolderRenameTest extends AbstractProtocolTest {
+
+ private Store connect() throws Exception {
+ final Properties props = new Properties();
+ props.setProperty("mail.imap.port", String.valueOf(imapConf.getListenerPort()));
+ props.setProperty("mail.debug", "true");
+ final Session session = Session.getInstance(props);
+ final Store store = session.getStore("imap");
+ store.connect("127.0.0.1", "serveruser", "serverpass");
+ return store;
+ }
+
+ private void createMailboxWithMessage(final String name) throws Exception {
+ server.createUserMailbox(name);
+ final ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ try (InputStream in = IMAPFolderRenameTest.class.getResourceAsStream("/messages/simple.msg")) {
+ final byte[] buf = new byte[4096];
+ int n;
+ while ((n = in.read(buf)) != -1) {
+ bout.write(buf, 0, n);
+ }
+ }
+ server.appendToUserMailbox(name, bout.toByteArray());
+ }
+
+ /**
+ * A successful server-side RENAME must be reported as success by
+ * renameTo, and the folder must remain usable under the new name.
+ */
+ @Test
+ public void testRenameToReportsSuccess() throws Exception {
+ start();
+ createMailboxWithMessage("test1");
+
+ final Store store = connect();
+ try {
+ final Folder test1 = store.getDefaultFolder().getFolder("test1");
+ final Folder test2 = store.getDefaultFolder().getFolder("test2");
+
+ assertTrue(test1.renameTo(test2), "renameTo must return true for a successful server-side RENAME");
+ assertTrue(test2.exists(), "renamed mailbox must exist under the new name");
+ assertFalse(test1.exists(), "renamed mailbox must no longer exist under the old name");
+ } finally {
+ store.close();
+ }
+ }
+
+ /**
+ * The TCK pattern (Folder/renameTo_Test): rename away, then rename back,
+ * then open the folder again. Before the fix the rename-back never
+ * happened (renameTo wrongly returned false) and every subsequent open
+ * of the folder failed with CommandFailedException.
+ */
+ @Test
+ public void testOpenAfterRenameAndRenameBack() throws Exception {
+ start();
+ createMailboxWithMessage("test1");
+
+ final Store store = connect();
+ try {
+ final Folder test1 = store.getDefaultFolder().getFolder("test1");
+ final Folder test2 = store.getDefaultFolder().getFolder("test2");
+
+ assertTrue(test1.renameTo(test2), "rename test1 -> test2 must succeed");
+ assertTrue(store.getDefaultFolder().getFolder("test2").renameTo(test1),
+ "rename test2 -> test1 (rename back) must succeed");
+
+ // a later session opens the folder, as the next TCK test would
+ final Store store2 = connect();
+ try {
+ final Folder reopened = store2.getDefaultFolder().getFolder("test1");
+ reopened.open(Folder.READ_ONLY);
+ assertEquals(1, reopened.getMessageCount());
+ reopened.close(false);
+ } finally {
+ store2.close();
+ }
+ } finally {
+ store.close();
+ }
+ }
+}
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 1a1d194..adfd6be 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
@@ -313,6 +313,27 @@ public class MailServer {
}
+ /**
+ * Creates (if necessary) a top-level mailbox with the given name for the test user
+ * (i.e. a sibling of INBOX, like the "test1" folder used by the Jakarta Mail TCK).
+ */
+ public void createUserMailbox(final String name) throws Exception {
+ final MailboxSession session = mailboxManager.createSystemSession(Username.of(USER));
+ final MailboxPath path = MailboxPath.forUser(Username.of(USER), name);
+ if (!Mono.from(mailboxManager.mailboxExists(path, session)).block()) {
+ mailboxManager.createMailbox(path, session);
+ }
+ }
+
+ /**
+ * Appends a raw rfc822 message to the given top-level mailbox of the test user.
+ */
+ public void appendToUserMailbox(final String name, final byte[] content) throws Exception {
+ final MailboxSession session = mailboxManager.createSystemSession(Username.of(USER));
+ final MessageManager mb = mailboxManager.getMailbox(MailboxPath.forUser(Username.of(USER), name), session);
+ mb.appendMessage(MessageManager.AppendCommand.builder().recent().build(content), session);
+ }
+
/**
* @return the queue
*/
diff --git a/geronimo-mail_2.1_tck/src/tck/geronimo.jtx b/geronimo-mail_2.1_tck/src/tck/geronimo.jtx
index 2186494..b9c46cd 100644
--- a/geronimo-mail_2.1_tck/src/tck/geronimo.jtx
+++ b/geronimo-mail_2.1_tck/src/tck/geronimo.jtx
@@ -37,11 +37,11 @@ javasoft/sqe/tests/jakarta/mail/UIDFolder/testlist.html#getUIDNext_Test
# should be reviewed separately.
SignatureTest.html
-# Remaining baseline failures from the first full run (191 passed / 125 failed).
-# Large blocks share single root causes:
-# - Message/Multipart/Folder blocks: IMAPFolder.open (SELECT) rejected by
-# James 3.9 (CommandFailedException), plus folder create/rename defects
-javasoft/sqe/tests/jakarta/mail/event/FolderEvent/testlist.html#addFolderListener_Test
+
+# Remaining baseline failures (284 passed / 31 failed after the
+# IMAPFolder.renameTo fix removed a ~90-test cascade). Distinct defects:
+# folder create/delete (topdog), permanent flags, list/listSubscribed,
+# several MIME encoding/decoding and unicode behaviours.
javasoft/sqe/tests/jakarta/mail/event/FolderEvent/testlist.html#addMsgChangeList_Test
javasoft/sqe/tests/jakarta/mail/exception/testlist.html#folderNotFoundExp_Test
javasoft/sqe/tests/jakarta/mail/exception/testlist.html#msgRemoveExp_Test
@@ -55,113 +55,21 @@ javasoft/sqe/tests/jakarta/mail/Folder/testlist.html#getPermanentFlags_Test
javasoft/sqe/tests/jakarta/mail/Folder/testlist.html#getType_Test
javasoft/sqe/tests/jakarta/mail/Folder/testlist.html#list_Test
javasoft/sqe/tests/jakarta/mail/Folder/testlist.html#listSubscribed_Test
-javasoft/sqe/tests/jakarta/mail/Folder/testlist.html#renameTo_Test
-javasoft/sqe/tests/jakarta/mail/Folder/testlist.html#search_Test
-javasoft/sqe/tests/jakarta/mail/internet/InternetAddress/testlist.html#getType_Test
-javasoft/sqe/tests/jakarta/mail/internet/InternetAddress/testlist.html#internetAddress_Test
-javasoft/sqe/tests/jakarta/mail/internet/InternetAddress/testlist.html#setAddress_Test
javasoft/sqe/tests/jakarta/mail/internet/InternetAddress/testlist.html#unicode_Test
-javasoft/sqe/tests/jakarta/mail/internet/InternetHeaders/testlist.html#getAllHeaderLines_Test
-javasoft/sqe/tests/jakarta/mail/internet/InternetHeaders/testlist.html#getAllHeaders_Test
-javasoft/sqe/tests/jakarta/mail/internet/InternetHeaders/testlist.html#getMatchHeadLines_Test
-javasoft/sqe/tests/jakarta/mail/internet/InternetHeaders/testlist.html#getMatchingHeaders_Test
-javasoft/sqe/tests/jakarta/mail/internet/InternetHeaders/testlist.html#getNonMatchHead_Test
-javasoft/sqe/tests/jakarta/mail/internet/InternetHeaders/testlist.html#getNonMatchHeadLines_Test
-javasoft/sqe/tests/jakarta/mail/internet/InternetHeaders/testlist.html#InternetHeaders_Test
-javasoft/sqe/tests/jakarta/mail/internet/InternetHeaders/testlist.html#load_Test
javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#attachFile_saveFile_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#getAllHeaderLines_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#getAllHeaders_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#getContent_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#getContentID_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#getContentLanguage_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#getContentMD5_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#getContentType_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#getDataHandler_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#getDescription_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#getDisposition_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#getEncoding_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#getFileName_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#getHeader_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#getLineCount_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#getMatchHeadLines_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#getMatchingHeaders_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#getNonMatchHead_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#getNonMatchHeadLines_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#getSize_Test
javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#isMimeType_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#mimeBodyPart_Test
javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#setContentLanguage_Test
javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#setFileNameEncoded_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimeBodyPart/testlist.html#writeTo_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimeMessage/testlist.html#addRecipients_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimeMessage/testlist.html#getAllHeaderLines_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimeMessage/testlist.html#getContentID_Test
javasoft/sqe/tests/jakarta/mail/internet/MimeMessage/testlist.html#getContentLanguage_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimeMessage/testlist.html#getContentMD5_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimeMessage/testlist.html#getEncoding_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimeMessage/testlist.html#getHeader_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimeMessage/testlist.html#getInputStream_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimeMessage/testlist.html#getMatchHeadLines_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimeMessage/testlist.html#getNonMatchHeadLines_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimeMessage/testlist.html#getSentDate_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimeMessage/testlist.html#MimeMessage_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimeMessage/testlist.html#setDataHandler_Test
javasoft/sqe/tests/jakarta/mail/internet/MimeMessage/testlist.html#setFileNameEncoded_Test
javasoft/sqe/tests/jakarta/mail/internet/MimeMessage/testlist.html#setSentDate_Test
javasoft/sqe/tests/jakarta/mail/internet/MimeMessage/testlist.html#unicode_Test
javasoft/sqe/tests/jakarta/mail/internet/MimeMessage/testlist.html#updateHeaders_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimeMessage/testlist.html#writeTo_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimeMultipart/testlist.html#getBodyPart_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimeMultipart/testlist.html#getCount_Test
javasoft/sqe/tests/jakarta/mail/internet/MimeMultipart/testlist.html#getsetPreamble_Test
javasoft/sqe/tests/jakarta/mail/internet/MimeMultipart/testlist.html#writeTo_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimePartDataSource/testlist.html#getContentType_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimePartDataSource/testlist.html#getInputStream_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimePartDataSource/testlist.html#getName_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimePartDataSource/testlist.html#getOutputStream_Test
-javasoft/sqe/tests/jakarta/mail/internet/MimePartDataSource/testlist.html#mimePartDataSource_Test
javasoft/sqe/tests/jakarta/mail/internet/MimeUtility/testlist.html#decodeText_Test
javasoft/sqe/tests/jakarta/mail/internet/MimeUtility/testlist.html#foldUnfold_Test
javasoft/sqe/tests/jakarta/mail/internet/ParameterList/testlist.html#set_withDecodeStrict_Test
-javasoft/sqe/tests/jakarta/mail/Message/testlist.html#getAllHeaders_Test
-javasoft/sqe/tests/jakarta/mail/Message/testlist.html#getContent_Test
-javasoft/sqe/tests/jakarta/mail/Message/testlist.html#getContentType_Test
-javasoft/sqe/tests/jakarta/mail/Message/testlist.html#getDataHandler_Test
-javasoft/sqe/tests/jakarta/mail/Message/testlist.html#getDescription_Test
-javasoft/sqe/tests/jakarta/mail/Message/testlist.html#getDisposition_Test
-javasoft/sqe/tests/jakarta/mail/Message/testlist.html#getFileName_Test
-javasoft/sqe/tests/jakarta/mail/Message/testlist.html#getFlags_Test
-javasoft/sqe/tests/jakarta/mail/Message/testlist.html#getFolder_Test
-javasoft/sqe/tests/jakarta/mail/Message/testlist.html#getFrom_Test
-javasoft/sqe/tests/jakarta/mail/Message/testlist.html#getHeader_Test
-javasoft/sqe/tests/jakarta/mail/Message/testlist.html#getInputStream_Test
-javasoft/sqe/tests/jakarta/mail/Message/testlist.html#getMatchingHeaders_Test
-javasoft/sqe/tests/jakarta/mail/Message/testlist.html#getMessageNumber_Test
-javasoft/sqe/tests/jakarta/mail/Message/testlist.html#getNonMatchingHeaders_Test
-javasoft/sqe/tests/jakarta/mail/Message/testlist.html#getReceivedDate_Test
-javasoft/sqe/tests/jakarta/mail/Message/testlist.html#getReplyTo_Test
-javasoft/sqe/tests/jakarta/mail/Message/testlist.html#getSize_Test
-javasoft/sqe/tests/jakarta/mail/Message/testlist.html#getSubject_Test
-javasoft/sqe/tests/jakarta/mail/Message/testlist.html#isExpunged_Test
-javasoft/sqe/tests/jakarta/mail/Message/testlist.html#isSet_Test
-javasoft/sqe/tests/jakarta/mail/Message/testlist.html#match_Test
javasoft/sqe/tests/jakarta/mail/Message/testlist.html#setFileName_Test
javasoft/sqe/tests/jakarta/mail/Message/testlist.html#setFileNameTest_encodeFalse_decodeTrue
-javasoft/sqe/tests/jakarta/mail/Multipart/testlist.html#getBodyPart_Test
-javasoft/sqe/tests/jakarta/mail/Multipart/testlist.html#getContentType_Test
-javasoft/sqe/tests/jakarta/mail/Multipart/testlist.html#getCount_Test
javasoft/sqe/tests/jakarta/mail/Multipart/testlist.html#writeTo_Test
-javasoft/sqe/tests/jakarta/mail/search/AndTerm/testlist.html#andterm_Test
-javasoft/sqe/tests/jakarta/mail/search/BodyTerm/testlist.html#bodyterm_Test
-javasoft/sqe/tests/jakarta/mail/search/FlagTerm/testlist.html#flagterm_Test
-javasoft/sqe/tests/jakarta/mail/search/FromTerm/testlist.html#fromterm_Test
-javasoft/sqe/tests/jakarta/mail/search/HeaderTerm/testlist.html#headerterm_Test
-javasoft/sqe/tests/jakarta/mail/search/MessageIDTerm/testlist.html#messageidterm_Test
-javasoft/sqe/tests/jakarta/mail/search/MessageNumberTerm/testlist.html#messagenumberterm_Test
-javasoft/sqe/tests/jakarta/mail/search/NotTerm/testlist.html#notterm_Test
-javasoft/sqe/tests/jakarta/mail/search/OrTerm/testlist.html#orterm_Test
-javasoft/sqe/tests/jakarta/mail/search/ReceivedDateTerm/testlist.html#receiveddateterm_Test
-javasoft/sqe/tests/jakarta/mail/search/SentDateTerm/testlist.html#sentdateterm_Test
-javasoft/sqe/tests/jakarta/mail/search/SizeTerm/testlist.html#sizeterm_Test
-javasoft/sqe/tests/jakarta/mail/search/SubjectTerm/testlist.html#subjectterm_Test