commits@javamail.java.net

[javamail~mercurial:479] Update docs and assembly.xml for gimap provider.

From: <shannon_at_kenai.com>
Date: Wed, 19 Dec 2012 19:21:10 +0000

Project: javamail
Repository: mercurial
Revision: 479
Author: shannon
Date: 2012-12-04 22:56:31 UTC
Link:

Log Message:
------------
Optimize all variants of the setFlags method.
Update version to 1.4.6-rc1.
Added tag JAVAMAIL-1_4_6-RC1 for changeset da6e25608ec1
MailHandler set CCL during close so LogManager$Cleaner can load JAF classes.
MailHandlerTest added close context class loader tests.
MailHandlerTest formatting fixes.

(Updates from Jason)
Update docs and assembly.xml for gimap provider.


Revisions:
----------
475
476
477
478
479


Modified Paths:
---------------
mail/src/main/java/com/sun/mail/imap/IMAPFolder.java
client/pom.xml
demo/pom.xml
dsn/pom.xml
gimap/pom.xml
imap/pom.xml
javadoc/pom.xml
logging/pom.xml
mail/pom.xml
mailapi/pom.xml
mailapijar/pom.xml
mbox/dist/pom.xml
mbox/native/pom.xml
mbox/pom.xml
oldmail/pom.xml
outlook/pom.xml
parent-distrib/pom.xml
pom.xml
pop3/pom.xml
servlet/pom.xml
smtp/pom.xml
taglib/pom.xml
webapp/pom.xml
.hgtags
mail/src/main/java/com/sun/mail/util/logging/MailHandler.java
mail/src/test/java/com/sun/mail/util/logging/MailHandlerTest.java
assembly.xml
doc/release/NOTES.txt
doc/release/README.txt


Diffs:
------
diff -r d72dfc286bdc -r f9d6181c9860 mail/src/main/java/com/sun/mail/imap/IMAPFolder.java
--- a/mail/src/main/java/com/sun/mail/imap/IMAPFolder.java Fri Nov 09 17:24:48 2012 -0800
+++ b/mail/src/main/java/com/sun/mail/imap/IMAPFolder.java Wed Nov 14 22:37:45 2012 -0800
@@ -1227,6 +1227,31 @@
     }
 
     /**
+ * Set the specified flags for the given range of message numbers.
+ */
+ public synchronized void setFlags(int start, int end,
+ Flags flag, boolean value) throws MessagingException {
+ checkOpened();
+ Message[] msgs = new Message[end - start + 1];
+ int i = 0;
+ for (int n = start; n <= end; n++)
+ msgs[i++] = getMessage(n);
+ setFlags(msgs, flag, value);
+ }
+
+ /**
+ * Set the specified flags for the given array of message numbers.
+ */
+ public synchronized void setFlags(int[] msgnums, Flags flag, boolean value)
+ throws MessagingException {
+ checkOpened();
+ Message[] msgs = new Message[msgnums.length];
+ for (int i = 0; i < msgnums.length; i++)
+ msgs[i] = getMessage(msgnums[i]);
+ setFlags(msgs, flag, value);
+ }
+
+ /**
      * Close this folder.
      */
     public synchronized void close(boolean expunge) throws MessagingException {


diff -r f9d6181c9860 -r da6e25608ec1 client/pom.xml
--- a/client/pom.xml Wed Nov 14 22:37:45 2012 -0800
+++ b/client/pom.xml Fri Nov 16 16:29:03 2012 -0800
@@ -48,7 +48,7 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>all</artifactId>
- <version>1.4.6-SNAPSHOT</version>
+ <version>1.4.6-rc1</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.sun.mail</groupId>

diff -r f9d6181c9860 -r da6e25608ec1 demo/pom.xml
--- a/demo/pom.xml Wed Nov 14 22:37:45 2012 -0800
+++ b/demo/pom.xml Fri Nov 16 16:29:03 2012 -0800
@@ -48,7 +48,7 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>all</artifactId>
- <version>1.4.6-SNAPSHOT</version>
+ <version>1.4.6-rc1</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.sun.mail</groupId>

diff -r f9d6181c9860 -r da6e25608ec1 dsn/pom.xml
--- a/dsn/pom.xml Wed Nov 14 22:37:45 2012 -0800
+++ b/dsn/pom.xml Fri Nov 16 16:29:03 2012 -0800
@@ -48,7 +48,7 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>all</artifactId>
- <version>1.4.6-SNAPSHOT</version>
+ <version>1.4.6-rc1</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.sun.mail</groupId>

diff -r f9d6181c9860 -r da6e25608ec1 gimap/pom.xml
--- a/gimap/pom.xml Wed Nov 14 22:37:45 2012 -0800
+++ b/gimap/pom.xml Fri Nov 16 16:29:03 2012 -0800
@@ -48,7 +48,7 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>all</artifactId>
- <version>1.4.6-SNAPSHOT</version>
+ <version>1.4.6-rc1</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.sun.mail</groupId>

diff -r f9d6181c9860 -r da6e25608ec1 imap/pom.xml
--- a/imap/pom.xml Wed Nov 14 22:37:45 2012 -0800
+++ b/imap/pom.xml Fri Nov 16 16:29:03 2012 -0800
@@ -48,7 +48,7 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>parent-distrib</artifactId>
- <version>1.4.6-SNAPSHOT</version>
+ <version>1.4.6-rc1</version>
         <relativePath>../parent-distrib/pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>

diff -r f9d6181c9860 -r da6e25608ec1 javadoc/pom.xml
--- a/javadoc/pom.xml Wed Nov 14 22:37:45 2012 -0800
+++ b/javadoc/pom.xml Fri Nov 16 16:29:03 2012 -0800
@@ -48,13 +48,13 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>all</artifactId>
- <version>1.4.6-SNAPSHOT</version>
+ <version>1.4.6-rc1</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.sun.mail</groupId>
     <artifactId>javadoc</artifactId>
     <packaging>pom</packaging>
- <version>1.4.6-SNAPSHOT</version>
+ <version>1.4.6-rc1</version>
     <name>JavaMail API javadocs</name>
     <description>${project.name}</description>
 

diff -r f9d6181c9860 -r da6e25608ec1 logging/pom.xml
--- a/logging/pom.xml Wed Nov 14 22:37:45 2012 -0800
+++ b/logging/pom.xml Fri Nov 16 16:29:03 2012 -0800
@@ -48,7 +48,7 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>all</artifactId>
- <version>1.4.6-SNAPSHOT</version>
+ <version>1.4.6-rc1</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.sun.mail</groupId>

diff -r f9d6181c9860 -r da6e25608ec1 mail/pom.xml
--- a/mail/pom.xml Wed Nov 14 22:37:45 2012 -0800
+++ b/mail/pom.xml Fri Nov 16 16:29:03 2012 -0800
@@ -48,7 +48,7 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>all</artifactId>
- <version>1.4.6-SNAPSHOT</version>
+ <version>1.4.6-rc1</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.sun.mail</groupId>

diff -r f9d6181c9860 -r da6e25608ec1 mailapi/pom.xml
--- a/mailapi/pom.xml Wed Nov 14 22:37:45 2012 -0800
+++ b/mailapi/pom.xml Fri Nov 16 16:29:03 2012 -0800
@@ -56,7 +56,7 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>all</artifactId>
- <version>1.4.6-SNAPSHOT</version>
+ <version>1.4.6-rc1</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.sun.mail</groupId>

diff -r f9d6181c9860 -r da6e25608ec1 mailapijar/pom.xml
--- a/mailapijar/pom.xml Wed Nov 14 22:37:45 2012 -0800
+++ b/mailapijar/pom.xml Fri Nov 16 16:29:03 2012 -0800
@@ -55,7 +55,7 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>all</artifactId>
- <version>1.4.6-SNAPSHOT</version>
+ <version>1.4.6-rc1</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <groupId>javax.mail</groupId>

diff -r f9d6181c9860 -r da6e25608ec1 mbox/dist/pom.xml
--- a/mbox/dist/pom.xml Wed Nov 14 22:37:45 2012 -0800
+++ b/mbox/dist/pom.xml Fri Nov 16 16:29:03 2012 -0800
@@ -48,7 +48,7 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>all</artifactId>
- <version>1.4.6-SNAPSHOT</version>
+ <version>1.4.6-rc1</version>
         <relativePath>../../pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>

diff -r f9d6181c9860 -r da6e25608ec1 mbox/native/pom.xml
--- a/mbox/native/pom.xml Wed Nov 14 22:37:45 2012 -0800
+++ b/mbox/native/pom.xml Fri Nov 16 16:29:03 2012 -0800
@@ -48,7 +48,7 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>all</artifactId>
- <version>1.4.6-SNAPSHOT</version>
+ <version>1.4.6-rc1</version>
         <relativePath>../../pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>

diff -r f9d6181c9860 -r da6e25608ec1 mbox/pom.xml
--- a/mbox/pom.xml Wed Nov 14 22:37:45 2012 -0800
+++ b/mbox/pom.xml Fri Nov 16 16:29:03 2012 -0800
@@ -48,7 +48,7 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>all</artifactId>
- <version>1.4.6-SNAPSHOT</version>
+ <version>1.4.6-rc1</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.sun.mail</groupId>

diff -r f9d6181c9860 -r da6e25608ec1 oldmail/pom.xml
--- a/oldmail/pom.xml Wed Nov 14 22:37:45 2012 -0800
+++ b/oldmail/pom.xml Fri Nov 16 16:29:03 2012 -0800
@@ -53,7 +53,7 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>all</artifactId>
- <version>1.4.6-SNAPSHOT</version>
+ <version>1.4.6-rc1</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <groupId>javax.mail</groupId>

diff -r f9d6181c9860 -r da6e25608ec1 outlook/pom.xml
--- a/outlook/pom.xml Wed Nov 14 22:37:45 2012 -0800
+++ b/outlook/pom.xml Fri Nov 16 16:29:03 2012 -0800
@@ -48,7 +48,7 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>all</artifactId>
- <version>1.4.6-SNAPSHOT</version>
+ <version>1.4.6-rc1</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.sun.mail</groupId>

diff -r f9d6181c9860 -r da6e25608ec1 parent-distrib/pom.xml
--- a/parent-distrib/pom.xml Wed Nov 14 22:37:45 2012 -0800
+++ b/parent-distrib/pom.xml Fri Nov 16 16:29:03 2012 -0800
@@ -48,7 +48,7 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>all</artifactId>
- <version>1.4.6-SNAPSHOT</version>
+ <version>1.4.6-rc1</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.sun.mail</groupId>

diff -r f9d6181c9860 -r da6e25608ec1 pom.xml
--- a/pom.xml Wed Nov 14 22:37:45 2012 -0800
+++ b/pom.xml Fri Nov 16 16:29:03 2012 -0800
@@ -54,7 +54,7 @@
     <groupId>com.sun.mail</groupId>
     <artifactId>all</artifactId>
     <packaging>pom</packaging>
- <version>1.4.6-SNAPSHOT</version>
+ <version>1.4.6-rc1</version>
     <name>JavaMail API distribution</name>
     <description>${project.name}</description>
     <url>http://kenai.com/projects/javamail</url>
@@ -91,9 +91,9 @@
     </organization>
 
     <properties>
- <mail.version>1.4.6-SNAPSHOT</mail.version>
+ <mail.version>1.4.6-rc1</mail.version>
         <!-- like mail.version, but with underscores instead of dots -->
- <mail.zipversion>1_4_6-SNAPSHOT</mail.zipversion>
+ <mail.zipversion>1_4_6-rc1</mail.zipversion>
         <mail.spec.version>1.4</mail.spec.version>
         <activation-api.version>1.1</activation-api.version>
         <!-- defaults that are overridden in mail module -->

diff -r f9d6181c9860 -r da6e25608ec1 pop3/pom.xml
--- a/pop3/pom.xml Wed Nov 14 22:37:45 2012 -0800
+++ b/pop3/pom.xml Fri Nov 16 16:29:03 2012 -0800
@@ -48,7 +48,7 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>parent-distrib</artifactId>
- <version>1.4.6-SNAPSHOT</version>
+ <version>1.4.6-rc1</version>
         <relativePath>../parent-distrib/pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>

diff -r f9d6181c9860 -r da6e25608ec1 servlet/pom.xml
--- a/servlet/pom.xml Wed Nov 14 22:37:45 2012 -0800
+++ b/servlet/pom.xml Fri Nov 16 16:29:03 2012 -0800
@@ -48,7 +48,7 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>all</artifactId>
- <version>1.4.6-SNAPSHOT</version>
+ <version>1.4.6-rc1</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.sun.mail</groupId>

diff -r f9d6181c9860 -r da6e25608ec1 smtp/pom.xml
--- a/smtp/pom.xml Wed Nov 14 22:37:45 2012 -0800
+++ b/smtp/pom.xml Fri Nov 16 16:29:03 2012 -0800
@@ -48,7 +48,7 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>parent-distrib</artifactId>
- <version>1.4.6-SNAPSHOT</version>
+ <version>1.4.6-rc1</version>
         <relativePath>../parent-distrib/pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>

diff -r f9d6181c9860 -r da6e25608ec1 taglib/pom.xml
--- a/taglib/pom.xml Wed Nov 14 22:37:45 2012 -0800
+++ b/taglib/pom.xml Fri Nov 16 16:29:03 2012 -0800
@@ -48,7 +48,7 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>all</artifactId>
- <version>1.4.6-SNAPSHOT</version>
+ <version>1.4.6-rc1</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.sun.mail</groupId>

diff -r f9d6181c9860 -r da6e25608ec1 webapp/pom.xml
--- a/webapp/pom.xml Wed Nov 14 22:37:45 2012 -0800
+++ b/webapp/pom.xml Fri Nov 16 16:29:03 2012 -0800
@@ -48,7 +48,7 @@
     <parent>
         <groupId>com.sun.mail</groupId>
         <artifactId>all</artifactId>
- <version>1.4.6-SNAPSHOT</version>
+ <version>1.4.6-rc1</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.sun.mail</groupId>


diff -r da6e25608ec1 -r e0f6de12aeb3 .hgtags
--- a/.hgtags Fri Nov 16 16:29:03 2012 -0800
+++ b/.hgtags Fri Nov 16 16:29:19 2012 -0800
@@ -9,3 +9,4 @@
 9cff25c6d73c8f86ff27f4cb39f7c3c092c34dd7 JAVAMAIL-1_4_4
 ce00d5900757397cbc7943b686035e8b27aa9449 JAVAMAIL-1_4_5-RC1
 e0ece38db9a0a6b46fe03575bffba6605603761d JAVAMAIL-1_4_5
+da6e25608ec175cf0556c6b7b7d1fee40cbe09c5 JAVAMAIL-1_4_6-RC1


diff -r e0f6de12aeb3 -r 92b82be5a724 mail/src/main/java/com/sun/mail/util/logging/MailHandler.java
--- a/mail/src/main/java/com/sun/mail/util/logging/MailHandler.java Fri Nov 16 16:29:19 2012 -0800
+++ b/mail/src/main/java/com/sun/mail/util/logging/MailHandler.java Mon Dec 03 14:01:59 2012 -0800
@@ -48,6 +48,8 @@
 import java.net.UnknownHostException;
 import java.net.URLConnection;
 import java.nio.charset.Charset;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.Arrays;
 import java.util.Comparator;
 import java.util.Locale;
@@ -327,6 +329,12 @@
      */
     private static final int offValue = Level.OFF.intValue();
     /**
+ * The action to get and set the context class loader.
+ * Load this before it is loaded in the close method.
+ */
+ private static final GetAndSetContext GET_AND_SET_CCL =
+ new GetAndSetContext(MailHandler.class);
+ /**
      * A thread local mutex used to prevent logging loops.
      * The MUTEX has 3 states:
      * 1. MUTEX_RESET which is the null state.
@@ -681,29 +689,37 @@
      * @see #flush()
      */
     public void close() {
- MessageContext ctx = null;
- synchronized (this) {
- super.setLevel(Level.OFF); //Security check first.
- try {
- ctx = writeLogRecords(ErrorManager.CLOSE_FAILURE);
- } finally {
- /**
- * The sign bit of the capacity is set to ensure that records
- * that have passed isLoggable, but have yet to be added to the
- * internal buffer, are immediately pushed as an email.
- */
- if (this.capacity > 0) {
- this.capacity = -this.capacity;
- }
+ //The LogManager$Cleaner has a context class loader set to null.
+ //Set the CCL to this class loader for loading content handlers.
+ final Object ccl = getAndSetContextClassLoader();
+ try {
+ MessageContext ctx = null;
+ synchronized (this) {
+ super.setLevel(Level.OFF); //Security check first.
+ try {
+ ctx = writeLogRecords(ErrorManager.CLOSE_FAILURE);
+ } finally {
+ /**
+ * The sign bit of the capacity is set to ensure that records
+ * that have passed isLoggable, but have yet to be added to
+ * the internal buffer, are immediately pushed as an email.
+ */
+ if (this.capacity > 0) {
+ this.capacity = -this.capacity;
+ }
 
- if (size == 0 && data.length != 1) { //Ensure not inside a push.
- this.data = new LogRecord[1];
+ //Ensure not inside a push.
+ if (size == 0 && data.length != 1) {
+ this.data = new LogRecord[1];
+ }
                 }
             }
- }
 
- if (ctx != null) {
- send(ctx, false, ErrorManager.CLOSE_FAILURE);
+ if (ctx != null) {
+ send(ctx, false, ErrorManager.CLOSE_FAILURE);
+ }
+ } finally {
+ setContextClassLoader(ccl);
         }
     }
 
@@ -2994,6 +3010,33 @@
         }
     }
 
+ /**
+ * Replaces the current context class loader with our class loader.
+ * @return null for the boot class loader, a class loader, or a marker
+ * object to signal that no modification was required.
+ * @since JavaMail 1.4.6
+ */
+ private Object getAndSetContextClassLoader() {
+ try {
+ return AccessController.doPrivileged(GET_AND_SET_CCL);
+ } catch (final SecurityException ignore) {
+ return GET_AND_SET_CCL; //return not modified.
+ }
+ }
+
+ /**
+ * Restores the original context class loader.
+ * @param ccl null for the boot class loader, a class loader, or a
+ * marker object to signal that no modification is required.
+ * @since JavaMail 1.4.6
+ */
+ private void setContextClassLoader(final Object ccl) {
+ //Boot class loader or a new context class loader.
+ if (ccl == null || ccl instanceof ClassLoader) {
+ AccessController.doPrivileged(new GetAndSetContext(ccl));
+ }
+ }
+
     private static RuntimeException attachmentMismatch(final String msg) {
         return new IndexOutOfBoundsException(msg);
     }
@@ -3039,6 +3082,55 @@
     }
 
     /**
+ * Performs a get and set of the context class loader with privileges
+ * enabled.
+ * @since JavaMail 1.4.6
+ */
+ private static final class GetAndSetContext implements PrivilegedAction {
+ /**
+ * The source containing the class loader.
+ */
+ private final Object source;
+ /**
+ * Create the action.
+ * @param source null for boot class loader, a class loader, a class
+ * used to get the class loader, or a source object to get the class
+ * loader.
+ */
+ GetAndSetContext(final Object source) {
+ this.source = source;
+ }
+
+ /**
+ * Gets the class loader from the source and sets the CCL only if
+ * the source and CCL are not the same.
+ * @return the replaced context class loader which can be null or this
+ * to indicate that nothing was modified.
+ */
+ public final Object run() {
+ final Thread current = Thread.currentThread();
+ final ClassLoader ccl = current.getContextClassLoader();
+ final ClassLoader loader;
+ if (source == null) {
+ loader = null; //boot class loader
+ } else if (source instanceof ClassLoader) {
+ loader = (ClassLoader) source;
+ } else if (source instanceof Class) {
+ loader = ((Class) source).getClassLoader();
+ } else {
+ loader = source.getClass().getClassLoader();
+ }
+
+ if (ccl != loader) {
+ current.setContextClassLoader(loader);
+ return ccl;
+ } else {
+ return this; //Unchanged, return non null and non classloader.
+ }
+ }
+ }
+
+ /**
      * Used for naming attachment file names and the main subject line.
      */
     private static final class TailNameFormatter extends Formatter {

diff -r e0f6de12aeb3 -r 92b82be5a724 mail/src/test/java/com/sun/mail/util/logging/MailHandlerTest.java
--- a/mail/src/test/java/com/sun/mail/util/logging/MailHandlerTest.java Fri Nov 16 16:29:19 2012 -0800
+++ b/mail/src/test/java/com/sun/mail/util/logging/MailHandlerTest.java Mon Dec 03 14:01:59 2012 -0800
@@ -59,6 +59,7 @@
 
 /**
  * Test case for the MailHandler spec.
+ *
  * @author Jason Mehrens
  */
 public class MailHandlerTest {
@@ -80,8 +81,8 @@
      */
     private static final String UNKNOWN_HOST = "bad-host-name";
     /**
- * Stores a writable directory that is in the class path and visible
- * to the context class loader.
+ * Stores a writable directory that is in the class path and visible to the
+ * context class loader.
      */
     private static volatile File anyClassPathDir = null;
     /**
@@ -171,6 +172,25 @@
         }
     }
 
+ static boolean isSecurityDebug() {
+ boolean debug;
+ final String value = System.getProperty("java.security.debug");
+ if (value != null) {
+ debug = value.indexOf("all") > -1
+ || value.indexOf("access") > -1
+ || value.indexOf("stack") > -1;
+ } else {
+ debug = false;
+ }
+ return debug;
+ }
+
+ static void securityDebugPrint(Throwable se) {
+ final PrintStream err = System.err;
+ err.println("Suppressed security exception to allow access:");
+ se.printStackTrace(err);
+ }
+
     @Test
     public void testIsLoggable() {
         Level[] lvls = getAllLevels();
@@ -443,7 +463,7 @@
         boolean normal = false;
         try {
             try {
- for (int i=0; i<records; ++i) {
+ for (int i = 0; i < records; ++i) {
                     instance.publish(new LogRecord(Level.SEVERE, ""));
                 }
             } finally {
@@ -463,7 +483,7 @@
         }
 
         if (normal) {
- assertTrue(records == 0);
+ assertTrue(records == 0);
         }
     }
 
@@ -607,7 +627,7 @@
         instance.setComparator(new ThrowComparator());
         instance.setErrorManager(new InternalErrorManager());
         try {
- for (int i=0; i<records; ++i) {
+ for (int i = 0; i < records; ++i) {
                 instance.publish(new LogRecord(Level.SEVERE, ""));
             }
         } finally {
@@ -1355,6 +1375,62 @@
     }
 
     @Test
+ public void testCloseContextClassLoader() {
+ assertNull(System.getSecurityManager());
+ final Thread thread = Thread.currentThread();
+ final ClassLoader ccl = thread.getContextClassLoader();
+ try {
+ testCloseContextClassLoader((CloseClassLoaderSecurityManager) null);
+ thread.setContextClassLoader(ccl);
+ testCloseContextClassLoader(new CloseClassLoaderSecurityManager());
+ } finally {
+ thread.setContextClassLoader(ccl);
+ }
+ }
+
+ private void testCloseContextClassLoader(CloseClassLoaderSecurityManager sm) {
+ InternalErrorManager em = null;
+ try {
+ MailHandler instance = createHandlerWithRecords();
+ try {
+ em = internalErrorManagerFrom(instance);
+ ClassLoader expect = instance.getClass().getClassLoader();
+ assertNotNull("Unexpected class loader.", expect);
+ /**
+ * java.util.logging.LogManager$Cleaner has a null CCL.
+ */
+ Thread.currentThread().setContextClassLoader(null);
+ if (sm != null) {
+ instance.setFormatter(new CloseClassLoaderFormatter(null));
+ System.setSecurityManager(sm);
+ sm.secure = true;
+ } else {
+ instance.setFormatter(new CloseClassLoaderFormatter(expect));
+ }
+ } finally {
+ instance.close();
+ }
+
+ assertEquals(CloseClassLoaderFormatter.class,
+ instance.getFormatter().getClass());
+ } finally {
+ if (sm != null) {
+ sm.secure = false;
+ System.setSecurityManager((SecurityManager) null);
+ }
+ }
+
+ for (int i = 0; i < em.exceptions.size(); i++) {
+ Throwable t = em.exceptions.get(i);
+ if (t instanceof MessagingException == false) {
+ dump(t);
+ fail(t.toString());
+ }
+ }
+ assertFalse(em.exceptions.isEmpty());
+ }
+
+ @Test
     public void testLevel() {
         MailHandler instance = new MailHandler();
         InternalErrorManager em = new InternalErrorManager();
@@ -1490,6 +1566,7 @@
 
     /**
      * Setup and load the standard properties.
+ *
      * @param verify the value of verify enum.
      * @return a MailHandler
      * @throws IOException if there is a problem.
@@ -2223,6 +2300,7 @@
 
     /**
      * Find a writable directory that is in the class path.
+ *
      * @return a File directory.
      * @throws IOException if there is a problem.
      * @throws FileNotFoundException if there are no directories in class path.
@@ -2392,6 +2470,7 @@
 
     /**
      * Test all numbers between 1 and low capacity.
+ *
      * @param capacity
      * @return
      */
@@ -3221,7 +3300,7 @@
         hardRef = root;
         try {
             final Handler[] handlers = root.getHandlers();
- for(Handler h : handlers) {
+ for (Handler h : handlers) {
                 root.removeHandler(h);
             }
             try {
@@ -3253,7 +3332,7 @@
                 System.setErr(new PrintStream(baos, true, "ISO-8859-1"));
                 instance.setMailProperties(props);
 
- if(records > 0) {
+ if (records > 0) {
                     for (int i = 0; i < records; i++) {
                         baos.reset();
                         instance.publish(new LogRecord(Level.SEVERE, ""));
@@ -3266,7 +3345,7 @@
                     }
 
                     if (records == 1) {
- instance.close();
+ instance.close();
                     } else if (records == 2) {
                         instance.flush();
                     } else if (records == 3) {
@@ -3326,9 +3405,9 @@
     }
 
     /**
- * Test logging permissions of the MailHandler.
- * Must run by itself or run in isolated VM.
- * Use system property java.security.debug=all to troubleshoot failures.
+ * Test logging permissions of the MailHandler. Must run by itself or run in
+ * isolated VM. Use system property java.security.debug=all to troubleshoot
+ * failures.
      */
     @Test
     public void testSecurityManager() {
@@ -5059,9 +5138,10 @@
         System.setErr(new PrintStream(oldErrors, false, encoding));
         try {
             /**
- * Bad level value for property: com.sun.mail.util.logging.MailHandler.level
- * The LogManager.setLevelsOnExistingLoggers triggers an error.
- * This code swallows that error message.
+ * Bad level value for property:
+ * com.sun.mail.util.logging.MailHandler.level The
+ * LogManager.setLevelsOnExistingLoggers triggers an error. This
+ * code swallows that error message.
              */
             LogManager.getLogManager().readConfiguration();
             System.err.print(""); //flushBuffer.
@@ -5077,9 +5157,9 @@
             }
 
             /**
- * The default error manager writes to System.err.
- * Since this test is trying to install an invalid ErrorManager
- * we can only capture the error by capturing System.err.
+ * The default error manager writes to System.err. Since this test
+ * is trying to install an invalid ErrorManager we can only capture
+ * the error by capturing System.err.
              */
             h = type.getConstructor(types).newInstance(params);
             System.err.flush();
@@ -5159,6 +5239,7 @@
 
     /**
      * http://www.iana.org/assignments/port-numbers
+ *
      * @return a open dynamic port.
      */
     private static int findOpenPort() {
@@ -5507,14 +5588,7 @@
         private final boolean debug;
 
         public ThrowSecurityManager() {
- final String value = System.getProperty("java.security.debug");
- if (value != null) {
- debug = value.indexOf("all") > -1
- || value.indexOf("access") > -1
- || value.indexOf("stack") > -1;
- } else {
- debug = false;
- }
+ debug = isSecurityDebug();
         }
 
         @Override
@@ -5542,9 +5616,7 @@
                 throw se;
             } else {
                 if (debug) {
- final PrintStream err = System.err;
- err.println("Suppressed security exception to allow access:");
- se.printStackTrace(err);
+ securityDebugPrint(se);
                 }
             }
         }
@@ -5901,7 +5973,6 @@
                 super.error(msg, e, code);
             }
         }
-
     }
 
     public final static class MailHandlerExt extends MailHandler {
@@ -5919,6 +5990,67 @@
         }
     }
 
+ private final static class CloseClassLoaderSecurityManager extends SecurityManager {
+
+ boolean secure = false;
+ private final boolean debug;
+
+ public CloseClassLoaderSecurityManager() {
+ debug = isSecurityDebug();
+ }
+
+ @Override
+ public void checkPermission(java.security.Permission perm) {
+ try { //Call super class always for java.security.debug tracing.
+ super.checkPermission(perm);
+ checkPermission(perm, new SecurityException(perm.toString()));
+ } catch (SecurityException se) {
+ checkPermission(perm, se);
+ }
+ }
+
+ @Override
+ public void checkPermission(java.security.Permission perm, Object context) {
+ try { //Call super class always for java.security.debug tracing.
+ super.checkPermission(perm, context);
+ checkPermission(perm, new SecurityException(perm.toString()));
+ } catch (SecurityException se) {
+ checkPermission(perm, se);
+ }
+ }
+
+ private void checkPermission(java.security.Permission perm, SecurityException se) {
+ //Check for set and get context class loader.
+ if (secure && perm.getName().contains("ContextClassLoader")) {
+ throw se;
+ } else {
+ if (debug) {
+ securityDebugPrint(se);
+ }
+ }
+ }
+ }
+
+ private final static class CloseClassLoaderFormatter extends Formatter {
+
+ private final ClassLoader expect;
+
+ CloseClassLoaderFormatter(final ClassLoader expect) {
+ this.expect = expect;
+ }
+
+ @Override
+ public String format(final LogRecord lr) {
+ Object ccl = Thread.currentThread().getContextClassLoader();
+ if (expect != ccl) {
+ AssertionError ae = new AssertionError(expect + " != " + ccl);
+ dump(ae);
+ throw ae;
+ }
+ return "";
+ }
+ }
+
     private final static class CloseLogRecord extends LogRecord {
 
         private static final long serialVersionUID = 1L;


diff -r 92b82be5a724 -r 1b4bafe49b74 assembly.xml
--- a/assembly.xml Mon Dec 03 14:01:59 2012 -0800
+++ b/assembly.xml Tue Dec 04 14:56:31 2012 -0800
@@ -3,7 +3,7 @@
 
     DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 
- Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 1997-2012 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
@@ -69,6 +69,7 @@
                 <include>com.sun.mail:imap</include>
                 <include>com.sun.mail:pop3</include>
                 <include>com.sun.mail:dsn</include>
+ <include>com.sun.mail:gimap</include>
             </includes>
             <binaries>
                 <includeDependencies>false</includeDependencies>

diff -r 92b82be5a724 -r 1b4bafe49b74 doc/release/NOTES.txt
--- a/doc/release/NOTES.txt Mon Dec 03 14:01:59 2012 -0800
+++ b/doc/release/NOTES.txt Tue Dec 04 14:56:31 2012 -0800
@@ -15,7 +15,7 @@
 ------------------
 
 The JavaMail API jar file "mail.jar" includes the full JavaMail API
-implementation and *all* the Sun protocol providers - IMAP, SMTP, and
+implementation and the Sun protocol providers - IMAP, SMTP, and
 POP3. The simplest way to use the JavaMail API is to just use the
 mail.jar file and ignore the other jar files in this package.
 
@@ -35,15 +35,25 @@
    should work fine.)
 
 
-NOTE: The Sun protocol provider documentation that was previously
- included in this file is now available in javadoc format, see
- docs/javadocs/index.html in the directory where you extracted
+NOTE: The Sun protocol provider documentation is available in javadoc format,
+ see docs/javadocs/index.html in the directory where you extracted
       the JavaMail API zip file. This documentation describes how to
       use features of the Sun protocol providers to directly access
       some features of the SMTP, IMAP, and POP3 protocols that are
       not otherwise supported by the standard JavaMail API.
 
 
+Gmail IMAP Provider
+-------------------
+
+This release includes an EXPERIMENTAL Gmail IMAP provider.
+Normal use of Gmail is handled by the standard "imap" protocol
+provider, but the new "gimap" protocol provider supports additional
+Gmail-specific non-standard features. See the javadocs for the
+com.sun.mail.gimap package for details. Note that the gimap.jar file
+needs to be added to your CLASSPATH to use this new provider.
+
+
 SASL Support
 ------------
 

diff -r 92b82be5a724 -r 1b4bafe49b74 doc/release/README.txt
--- a/doc/release/README.txt Mon Dec 03 14:01:59 2012 -0800
+++ b/doc/release/README.txt Tue Dec 04 14:56:31 2012 -0800
@@ -40,6 +40,7 @@
         -------------------------------------------------
         imap Store No Yes
         imaps Store Yes N/A
+ gimap Store Yes N/A
         pop3 Store No Yes
         pop3s Store Yes N/A
         smtp Transport No Yes
@@ -67,6 +68,7 @@
     lib/smtp.jar The SMTP service provider
     lib/pop3.jar The POP3 service provider
     lib/dsn.jar multipart/report DSN message support
+ lib/gimap.jar Gmail IMAP provider
 
     docs/JavaMail-1.1-changes.txt
                         Description of the new APIs that were added in