Project: javamail
Repository: mercurial
Revision: 630
Author: shannon
Date: 2014-01-25 00:33:06 UTC
Link:
Log Message:
------------
Update link and fix javadocs.
Catch more exceptions while in IDLE and log if we get one.
handle IMAP failures during close properly - bug 6260
send IMAP responses as events to Store's ConnectionListener - bug 6261
Revisions:
----------
627
628
629
630
Modified Paths:
---------------
mail/src/main/java/javax/mail/event/MessageCountEvent.java
mail/src/main/java/com/sun/mail/imap/protocol/IMAPProtocol.java
doc/release/CHANGES.txt
mail/src/main/java/com/sun/mail/imap/IMAPFolder.java
mail/src/main/java/com/sun/mail/imap/IMAPStore.java
mail/src/main/java/com/sun/mail/imap/package.html
Added Paths:
------------
mail/src/test/java/com/sun/mail/imap/IMAPCloseFailureTest.java
Diffs:
------
diff -r 7f8091908b18 -r f5b4fa3221bb mail/src/main/java/javax/mail/event/MessageCountEvent.java
--- a/mail/src/main/java/javax/mail/event/MessageCountEvent.java Fri Jan 03 14:58:42 2014 -0800
+++ b/mail/src/main/java/javax/mail/event/MessageCountEvent.java Fri Jan 24 11:31:04 2014 -0800
@@ -1,7 +1,7 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
- * Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997-2014 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
@@ -49,11 +49,12 @@
* Note that some folder types may only deliver MessageCountEvents at
* certain times or after certain operations. IMAP in particular will
* only notify the client of MessageCountEvents when a client issues a
- * new command.
- * Refer to RFC 2060 <A HREF="
http://www.ietf.org/rfc/rfc2060.txt">
- *
http://www.ietf.org/rfc/rfc2060.txt</A> for details.
- * A client may want "poll" the folder by occasionally calling the
- * <code>getMessageCount</code> or <code>isConnected</code> methods
+ * new command. Refer to
+ * <A HREF="
http://www.ietf.org/rfc/rfc3501.txt" TARGET="_top">RFC 3501</A>
+ * for details.
+ * A client may want to "poll" the folder by occasionally calling the
+ * {_at_link javax.mail.Folder#getMessageCount getMessageCount} or
+ * {_at_link javax.mail.Folder#isOpen isOpen} methods
* to solicit any such notifications.
*
* @author John Mani
diff -r f5b4fa3221bb -r c88d051bc82f mail/src/main/java/com/sun/mail/imap/protocol/IMAPProtocol.java
--- a/mail/src/main/java/com/sun/mail/imap/protocol/IMAPProtocol.java Fri Jan 24 11:31:04 2014 -0800
+++ b/mail/src/main/java/com/sun/mail/imap/protocol/IMAPProtocol.java Fri Jan 24 13:49:50 2014 -0800
@@ -2680,8 +2680,9 @@
try {
os.write(DONE);
os.flush();
- } catch (IOException ex) {
+ } catch (Exception ex) {
// nothing to do, hope to detect it again later
+ logger.log(Level.FINEST, "Exception aborting IDLE", ex);
}
}
diff -r c88d051bc82f -r f1e6cb4e3b04 doc/release/CHANGES.txt
--- a/doc/release/CHANGES.txt Fri Jan 24 13:49:50 2014 -0800
+++ b/doc/release/CHANGES.txt Fri Jan 24 16:26:09 2014 -0800
@@ -25,6 +25,7 @@
K 6207 SMTP SASL support doesn't handle authentication failure properly
K 6208 SASL authentication failures should not try other methods
K 6238 add OAuth2 support to JavaMail
+K 6260 IMAP failures during close can leave connection unusable
CHANGES IN THE 1.5.1 RELEASE
diff -r c88d051bc82f -r f1e6cb4e3b04 mail/src/main/java/com/sun/mail/imap/IMAPFolder.java
--- a/mail/src/main/java/com/sun/mail/imap/IMAPFolder.java Fri Jan 24 13:49:50 2014 -0800
+++ b/mail/src/main/java/com/sun/mail/imap/IMAPFolder.java Fri Jan 24 16:26:09 2014 -0800
@@ -1384,6 +1384,7 @@
if (!opened)
return;
+ boolean reuseProtocol = true;
try {
waitIfIdle();
if (force) {
@@ -1412,15 +1413,30 @@
protocol.hasCapability("UNSELECT"))
protocol.unselect();
else {
+ // Unselect isn't supported so we need to
+ // select a folder to cause this one to be
+ // deselected without expunging messages.
+ // We try to do that by reopening the current
+ // folder read-only. If the current folder
+ // was renamed out from under us, the EXAMINE
+ // might fail, but that's ok because it still
+ // leaves us with the folder deselected.
if (protocol != null) {
- protocol.examine(fullName);
- if (protocol != null) // XXX - unnecessary?
+ boolean selected = true;
+ try {
+ protocol.examine(fullName);
+ // success, folder still selected
+ } catch (CommandFailedException ex) {
+ // EXAMINE failed, folder is no
+ // longer selected
+ selected = false;
+ }
+ if (selected && protocol != null)
protocol.close();
}
}
} catch (ProtocolException pex2) {
- if (protocol != null)
- protocol.disconnect();
+ reuseProtocol = false; // something went wrong
}
} else {
if (protocol != null)
@@ -1432,7 +1448,7 @@
} finally {
// cleanup if we haven't already
if (opened)
- cleanup(true);
+ cleanup(reuseProtocol);
}
}
}
diff -r c88d051bc82f -r f1e6cb4e3b04 mail/src/test/java/com/sun/mail/imap/IMAPCloseFailureTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mail/src/test/java/com/sun/mail/imap/IMAPCloseFailureTest.java Fri Jan 24 16:26:09 2014 -0800
@@ -0,0 +1,136 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2009-2014 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ *
https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package com.sun.mail.imap;
+
+import java.io.*;
+import java.util.Properties;
+
+import javax.mail.Session;
+import javax.mail.Store;
+import javax.mail.Folder;
+
+import org.junit.Test;
+import static org.junit.Assert.fail;
+
+/**
+ * Test that failures while closing a folder are handled properly.
+ */
+public final class IMAPCloseFailureTest {
+
+ private static final String HOST = "localhost";
+ private static final int PORT = 26422;
+
+ static class NoIMAPHandler extends IMAPHandler {
+ static boolean first = true;
+
+ public void examine() throws IOException {
+ if (first)
+ no("mailbox gone");
+ else
+ super.examine();
+ first = false;
+ }
+ }
+
+ static class BadIMAPHandler extends IMAPHandler {
+ static boolean first = true;
+
+ public void examine() throws IOException {
+ if (first)
+ bad("mailbox gone");
+ else
+ super.examine();
+ first = false;
+ }
+ }
+
+ @Test
+ public void testCloseNo() {
+ testClose(new NoIMAPHandler());
+ }
+
+ @Test
+ public void testCloseBad() {
+ testClose(new BadIMAPHandler());
+ }
+
+ public void testClose(IMAPHandler handler) {
+ IMAPServer server = null;
+ try {
+ server = new IMAPServer(handler, PORT);
+ server.start();
+ Thread.sleep(1000);
+
+ Properties properties = new Properties();
+ properties.setProperty("mail.imap.host", HOST);
+ properties.setProperty("mail.imap.port", "" + PORT);
+ Session session = Session.getInstance(properties);
+ //session.setDebug(true);
+
+ Store store = session.getStore("imap");
+ try {
+ store.connect("test", "test");
+ Folder f = store.getFolder("INBOX");
+ f.open(Folder.READ_WRITE);
+ f.close(false);
+ // Make sure that failure while closing doesn't leave us
+ // with a connection that can't be used to open a folder.
+ f.open(Folder.READ_WRITE);
+ f.close(false);
+ } catch (Exception ex) {
+ System.out.println(ex);
+ //ex.printStackTrace();
+ fail(ex.toString());
+ } finally {
+ if (store.isConnected())
+ store.close();
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ } finally {
+ if (server != null) {
+ server.quit();
+ }
+ }
+ }
+}
diff -r f1e6cb4e3b04 -r 54e359ea2c07 doc/release/CHANGES.txt
--- a/doc/release/CHANGES.txt Fri Jan 24 16:26:09 2014 -0800
+++ b/doc/release/CHANGES.txt Fri Jan 24 16:33:06 2014 -0800
@@ -26,6 +26,7 @@
K 6208 SASL authentication failures should not try other methods
K 6238 add OAuth2 support to JavaMail
K 6260 IMAP failures during close can leave connection unusable
+K 6261 need way to monitor IMAP responses
CHANGES IN THE 1.5.1 RELEASE
diff -r f1e6cb4e3b04 -r 54e359ea2c07 mail/src/main/java/com/sun/mail/imap/IMAPStore.java
--- a/mail/src/main/java/com/sun/mail/imap/IMAPStore.java Fri Jan 24 16:26:09 2014 -0800
+++ b/mail/src/main/java/com/sun/mail/imap/IMAPStore.java Fri Jan 24 16:33:06 2014 -0800
@@ -1,7 +1,7 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
- * Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997-2014 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
@@ -219,6 +219,8 @@
private String[] saslMechanisms;
private boolean forcePasswordRefresh = false;
// enable notification of IMAP responses
+ private boolean enableResponseEvents = false;
+ // enable notification of IMAP responses during IDLE
private boolean enableImapEvents = false;
private String guid; // for Yahoo! Mail IMAP
private boolean throwSearchException = false;
@@ -569,10 +571,16 @@
logger.config("enable forcePasswordRefresh");
// check if enableimapevents is enabled
+ enableResponseEvents = PropUtil.getBooleanSessionProperty(session,
+ "mail." + name + ".enableresponseevents", false);
+ if (enableResponseEvents)
+ logger.config("enable IMAP response events");
+
+ // check if enableresponseevents is enabled
enableImapEvents = PropUtil.getBooleanSessionProperty(session,
"mail." + name + ".enableimapevents", false);
if (enableImapEvents)
- logger.config("enable IMAP events");
+ logger.config("enable IMAP IDLE events");
// check if message cache debugging set
messageCacheDebug = PropUtil.getBooleanSessionProperty(session,
@@ -2079,6 +2087,8 @@
* Response must be an OK, NO, BAD, or BYE response.
*/
void handleResponseCode(Response r) {
+ if (enableResponseEvents)
+ notifyStoreListeners(IMAPStore.RESPONSE, r.toString());
String s = r.getRest(); // get the text after the response
boolean isAlert = false;
if (s.startsWith("[")) { // a response code
diff -r f1e6cb4e3b04 -r 54e359ea2c07 mail/src/main/java/com/sun/mail/imap/package.html
--- a/mail/src/main/java/com/sun/mail/imap/package.html Fri Jan 24 16:26:09 2014 -0800
+++ b/mail/src/main/java/com/sun/mail/imap/package.html Fri Jan 24 16:33:06 2014 -0800
@@ -653,6 +653,21 @@
</TR>
<TR>
+<TD>mail.imap.enableresponseevents</TD>
+<TD>boolean</TD>
+<TD>
+Enable special IMAP-specific events to be delivered to the Store's
+<code>ConnectionListener</code>. If true, IMAP OK, NO, BAD, or BYE responses
+will be sent as <code>ConnectionEvent</code>s with a type of
+<code>IMAPStore.RESPONSE</code>. The event's message will be the
+raw IMAP response string.
+By default, these events are not sent.
+NOTE: This capability is highly experimental and likely will change
+in future releases.
+</TD>
+</TR>
+
+<TR>
<TD>mail.imap.enableimapevents</TD>
<TD>boolean</TD>
<TD>