commits@javamail.java.net

[javamail~mercurial:875] MailHandler should support 'login' verify type. - Bug K8492

From: <shannon_at_java.net>
Date: Fri, 21 Oct 2016 21:32:29 +0000

Project: javamail
Repository: mercurial
Revision: 875
Author: shannon
Date: 2016-10-21 19:32:57 UTC
Link:

Log Message:
------------
Add entry for bug 7011; which was included in JavaMail 1.5.5.
MailHandler should support 'login' verify type. - Bug K8492
Add test for 'login' verify type.
MailHandler support for GNU JavaMail.
Add test support for unoffical JavaMail implementations.

(From Jason)


Revisions:
----------
874
875


Modified Paths:
---------------
doc/release/CHANGES.txt
mail/src/main/java/com/sun/mail/util/logging/MailHandler.java
mail/src/test/java/com/sun/mail/util/logging/AbstractLogging.java
mail/src/test/java/com/sun/mail/util/logging/LogManagerPropertiesTest.java
mail/src/test/java/com/sun/mail/util/logging/MailHandlerTest.java


Diffs:
------
diff -r 21e84c3c1f53 -r d802403c6f62 doc/release/CHANGES.txt
--- a/doc/release/CHANGES.txt Fri Oct 14 13:30:45 2016 -0700
+++ b/doc/release/CHANGES.txt Mon Oct 17 13:46:00 2016 -0700
@@ -79,6 +79,7 @@
 K 6989 MailHandler needs better support for stateful filters.
 K 6997 add support for IMAP login referrals (RFC 2221)
 K 7009 whitespace line at beginning confuses InternetHeaders
+K 7011 Eliminate legacy classes
 K 7014 IndexOutOfBoundsException reading IMAP literal when connection fails
 K 7019 IdleManager dies with CancelledKeyException
 K 7026 IdleManager can deadlock when not busy


diff -r d802403c6f62 -r 8ae6606d365b doc/release/CHANGES.txt
--- a/doc/release/CHANGES.txt Mon Oct 17 13:46:00 2016 -0700
+++ b/doc/release/CHANGES.txt Fri Oct 21 12:32:57 2016 -0700
@@ -36,6 +36,7 @@
 K 8422 RFC822.SIZE > 2GB isn't handled
 K 8486 Protocol#command method call readResponse after IOException is thrown
 K 8487 Possible NPE in Status.<init> line 96
+K 8492 MailHandler should support 'login' verify type.
 
 
                   CHANGES IN THE 1.5.6 RELEASE

diff -r d802403c6f62 -r 8ae6606d365b mail/src/main/java/com/sun/mail/util/logging/MailHandler.java
--- a/mail/src/main/java/com/sun/mail/util/logging/MailHandler.java Mon Oct 17 13:46:00 2016 -0700
+++ b/mail/src/main/java/com/sun/mail/util/logging/MailHandler.java Fri Oct 21 12:32:57 2016 -0700
@@ -43,7 +43,6 @@
 
 import static com.sun.mail.util.logging.LogManagerProperties.fromLogManager;
 import java.io.*;
-import java.lang.reflect.Array;
 import java.lang.reflect.InvocationTargetException;
 import java.net.InetAddress;
 import java.net.URLConnection;
@@ -239,9 +238,12 @@
  * <li>If set to a value of <tt>resolve</tt>, the <tt>Handler</tt> will
  * verify all local settings and try to resolve the remote host name with
  * the domain name server.
+ * <li>If set to a value of <tt>login</tt>, the <tt>Handler</tt> will
+ * verify all local settings and try to establish a connection with
+ * the email server.
  * <li>If set to a value of <tt>remote</tt>, the <tt>Handler</tt> will
- * verify all local settings and try to establish a connection with the
- * email server.
+ * verify all local settings, try to establish a connection with the
+ * email server, and try to verify the envelope of the email message.
  * </ul>
  * If this <tt>Handler</tt> is only implicitly closed by the
  * <tt>LogManager</tt>, then verification should be turned on.
@@ -428,7 +430,7 @@
     /**
      * Holds the session object used to generate emails.
      * Sessions can be shared by multiple threads.
- * See BUGID 6228391 and K 6278.
+ * See JDK-6228391 and K 6278.
      */
     private Session session;
     /**
@@ -971,8 +973,7 @@
                this.errorManager = em;
                super.setErrorManager(em); //Try to free super error manager.
             }
- } catch (final RuntimeException ignore) {
- } catch (final LinkageError ignore) {
+ } catch (RuntimeException | LinkageError ignore) {
         }
     }
 
@@ -1325,7 +1326,7 @@
         if (filters.length == 0) {
             filters = emptyFilterArray();
         } else {
- filters = copyOf(filters, filters.length, Filter[].class);
+ filters = Arrays.copyOf(filters, filters.length, Filter[].class);
         }
         synchronized (this) {
             if (this.attachmentFormatters.length != filters.length) {
@@ -1378,7 +1379,7 @@
         if (formatters.length == 0) { //Null check and length check.
             formatters = emptyFormatterArray();
         } else {
- formatters = copyOf(formatters,
+ formatters = Arrays.copyOf(formatters,
                     formatters.length, Formatter[].class);
             for (int i = 0; i < formatters.length; ++i) {
                 if (formatters[i] == null) {
@@ -1490,7 +1491,8 @@
         if (formatters.length == 0) {
             formatters = emptyFormatterArray();
         } else {
- formatters = copyOf(formatters, formatters.length, Formatter[].class);
+ formatters = Arrays.copyOf(formatters, formatters.length,
+ Formatter[].class);
         }
 
         for (int i = 0; i < formatters.length; ++i) {
@@ -1501,7 +1503,8 @@
 
         synchronized (this) {
             if (this.attachmentFormatters.length != formatters.length) {
- throw attachmentMismatch(this.attachmentFormatters.length, formatters.length);
+ throw attachmentMismatch(this.attachmentFormatters.length,
+ formatters.length);
             }
 
             if (isWriting) {
@@ -1594,9 +1597,7 @@
             } else {
                 errorManager.error(null, ex, code);
             }
- } catch (final RuntimeException GLASSFISH_21258) {
- reportLinkageError(GLASSFISH_21258, code);
- } catch (final LinkageError GLASSFISH_21258) {
+ } catch (RuntimeException | LinkageError GLASSFISH_21258) {
             reportLinkageError(GLASSFISH_21258, code);
         }
     }
@@ -1705,11 +1706,26 @@
         } catch (final Exception noContent) {
             final String txt = noContent.getMessage();
             if (!isEmpty(txt)) {
- for (; t != null; t = t.getCause()) {
+ int limit = 0;
+ while (t != null) {
                     if (noContent.getClass() == t.getClass()
                             && txt.equals(t.getMessage())) {
                        return true;
                     }
+
+ //Not all JavaMail implementations support JDK 1.4 exception
+ //chaining.
+ final Throwable cause = t.getCause();
+ if (cause == null && t instanceof MessagingException) {
+ t = ((MessagingException) t).getNextException();
+ } else {
+ t = cause;
+ }
+
+ //Deal with excessive cause chains and cyclic throwables.
+ if (++limit == (1 << 16)) {
+ break; //Give up.
+ }
                 }
             }
         } finally {
@@ -1763,8 +1779,7 @@
             try {
                 Thread.currentThread().getUncaughtExceptionHandler()
                         .uncaughtException(Thread.currentThread(), le);
- } catch (final RuntimeException ignore) {
- } catch (final LinkageError ignore) {
+ } catch (RuntimeException | LinkageError ignore) {
             } finally {
                 if (idx != null) {
                     MUTEX.set(idx);
@@ -1912,7 +1927,7 @@
         final int expect = this.attachmentFormatters.length;
         final int current = this.attachmentNames.length;
         if (current != expect) {
- this.attachmentNames = copyOf(attachmentNames, expect,
+ this.attachmentNames = Arrays.copyOf(attachmentNames, expect,
                     Formatter[].class);
             fixed = current != 0;
         }
@@ -1943,7 +1958,7 @@
         final int expect = this.attachmentFormatters.length;
         final int current = this.attachmentFilters.length;
         if (current != expect) {
- this.attachmentFilters = copyOf(attachmentFilters, expect,
+ this.attachmentFilters = Arrays.copyOf(attachmentFilters, expect,
                     Filter[].class);
             clearMatches(current);
             fixed = current != 0;
@@ -1967,36 +1982,6 @@
     }
 
     /**
- * Copies the given array. Can be removed when Java Mail requires Java 1.6.
- * @param a the original array.
- * @param len the new size.
- * @return new copy
- * @since JavaMail 1.5.5
- */
- private static int[] copyOf(final int[] a, final int len) {
- final int[] copy = new int[len];
- System.arraycopy(a, 0, copy, 0, Math.min(len, a.length));
- return copy;
- }
-
- /**
- * Copies the given array to a new array type.
- * Can be removed when Java Mail requires Java 1.6.
- * @param <U> the class of the objects in the original array
- * @param <T> the class of the objects in the returned array
- * @param a the original array.
- * @param len the new size.
- * @param type the array type.
- * @return new copy
- */
- @SuppressWarnings("unchecked")
- private static <T,U> T[] copyOf(U[] a, int len, Class<? extends T[]> type) {
- final T[] copy = (T[]) Array.newInstance(type.getComponentType(), len);
- System.arraycopy(a, 0, copy, 0, Math.min(len, a.length));
- return copy;
- }
-
- /**
      * Sets the size to zero and clears the current buffer.
      */
     private void reset() {
@@ -2020,8 +2005,8 @@
             newCapacity = capacity;
         }
         assert len != capacity : len;
- this.data = copyOf(data, newCapacity, LogRecord[].class);
- this.matched = copyOf(matched, newCapacity);
+ this.data = Arrays.copyOf(data, newCapacity, LogRecord[].class);
+ this.matched = Arrays.copyOf(matched, newCapacity);
     }
 
     /**
@@ -2354,9 +2339,8 @@
                     try {
                         try {
                             a[i] = LogManagerProperties.newFormatter(names[i]);
- } catch (final ClassNotFoundException literal) {
- a[i] = TailNameFormatter.of(names[i]);
- } catch (final ClassCastException literal) {
+ } catch (ClassNotFoundException
+ | ClassCastException literal) {
                             a[i] = TailNameFormatter.of(names[i]);
                         }
                     } catch (final SecurityException SE) {
@@ -2397,9 +2381,8 @@
                             .newObjectFrom(name, Authenticator.class);
                 } catch (final SecurityException SE) {
                     throw SE;
- } catch (final ClassNotFoundException literalAuth) {
- this.auth = DefaultAuthenticator.of(name);
- } catch (final ClassCastException literalAuth) {
+ } catch (final ClassNotFoundException
+ | ClassCastException literalAuth) {
                     this.auth = DefaultAuthenticator.of(name);
                 } catch (final Exception E) {
                     reportError(E.getMessage(), E, ErrorManager.OPEN_FAILURE);
@@ -2498,10 +2481,8 @@
             }
         } catch (final SecurityException SE) {
             throw SE; //Avoid catch all.
- } catch (final UnsupportedEncodingException UEE) {
+ } catch (UnsupportedEncodingException | RuntimeException UEE) {
             reportError(UEE.getMessage(), UEE, ErrorManager.OPEN_FAILURE);
- } catch (final RuntimeException RE) {
- reportError(RE.getMessage(), RE, ErrorManager.OPEN_FAILURE);
         }
     }
 
@@ -2514,9 +2495,7 @@
         ErrorManager em;
         try { //Try to share the super error manager.
             em = super.getErrorManager();
- } catch (final RuntimeException ignore) {
- em = null;
- } catch (final LinkageError ignore) {
+ } catch (RuntimeException | LinkageError ignore) {
             em = null;
         }
 
@@ -2667,9 +2646,8 @@
                 this.subjectFormatter = LogManagerProperties.newFormatter(name);
             } catch (final SecurityException SE) {
                 throw SE; //Avoid catch all.
- } catch (final ClassNotFoundException literalSubject) {
- this.subjectFormatter = TailNameFormatter.of(name);
- } catch (final ClassCastException literalSubject) {
+ } catch (ClassNotFoundException
+ | ClassCastException literalSubject) {
                 this.subjectFormatter = TailNameFormatter.of(name);
             } catch (final Exception E) {
                 this.subjectFormatter = TailNameFormatter.of(name);
@@ -2763,7 +2741,7 @@
         try {
             envelopeFor(msg, priority);
             final Object ccl = getAndSetContextClassLoader(MAILHANDLER_LOADER);
- try { //BUGID 8025251
+ try { //JDK-8025251
                 Transport.send(msg); //Calls save changes.
             } finally {
                 getAndSetContextClassLoader(ccl);
@@ -2996,7 +2974,7 @@
                         verifySettings0(session, value);
                     }
                 } else {
- if (check != null) { //This call will fail.
+ if (check != null) { //Pass some invalid string.
                         verifySettings0(session, check.getClass().toString());
                     }
                 }
@@ -3020,9 +2998,10 @@
     private void verifySettings0(Session session, String verify) {
         assert verify != null : (String) null;
         if (!"local".equals(verify) && !"remote".equals(verify)
- && !"limited".equals(verify) && !"resolve".equals(verify)) {
+ && !"limited".equals(verify) && !"resolve".equals(verify)
+ && !"login".equals(verify)) {
             reportError("Verify must be 'limited', local', "
- + "'resolve' or 'remote'.",
+ + "'resolve', 'login', or 'remote'.",
                     new IllegalArgumentException(verify),
                     ErrorManager.OPEN_FAILURE);
             return;
@@ -3064,12 +3043,7 @@
 
         setIncompleteCopy(abort); //Original body part is never added.
         envelopeFor(abort, true);
- try {
- abort.saveChanges();
- } catch (final MessagingException ME) {
- reportError(msg, ME, ErrorManager.FORMAT_FAILURE);
- }
-
+ saveChangesNoContent(abort, msg);
         try {
             //Ensure transport provider is installed.
             Address[] all = abort.getAllRecipients();
@@ -3101,7 +3075,7 @@
             }
 
             String local = null;
- if ("remote".equals(verify)) {
+ if ("remote".equals(verify) || "login".equals(verify)) {
                 MessagingException closed = null;
                 t.connect();
                 try {
@@ -3112,15 +3086,23 @@
                         //A message without content will fail at message writeTo
                         //when sendMessage is called. This allows the handler
                         //to capture all mail properties set in the LogManager.
- t.sendMessage(abort, all);
+ if ("remote".equals(verify)) {
+ t.sendMessage(abort, all);
+ }
                     } finally {
- try { //Close the transport before reporting errors.
+ try {
                             t.close();
                         } catch (final MessagingException ME) {
                             closed = ME;
                         }
                     }
- reportUnexpectedSend(abort, verify, null);
+ //Close the transport before reporting errors.
+ if ("remote".equals(verify)) {
+ reportUnexpectedSend(abort, verify, null);
+ } else {
+ final String protocol = t.getURLName().getProtocol();
+ verifyProperties(session, protocol);
+ }
                 } catch (final SendFailedException sfe) {
                     Address[] recip = sfe.getInvalidAddresses();
                     if (recip != null && recip.length != 0) {
@@ -3144,8 +3126,9 @@
                     reportError(abort, closed, ErrorManager.CLOSE_FAILURE);
                 }
             } else {
- //Force a property copy.
+ //Force a property copy, JDK-7092981.
                 final String protocol = t.getURLName().getProtocol();
+ verifyProperties(session, protocol);
                 String mailHost = session.getProperty("mail."
                         + protocol + ".host");
                 if (isEmpty(mailHost)) {
@@ -3153,10 +3136,7 @@
                 } else {
                     session.getProperty("mail.host");
                 }
- session.getProperty("mail." + protocol + ".port");
- session.getProperty("mail." + protocol + ".user");
- session.getProperty("mail.user");
- session.getProperty("mail." + protocol + ".localport");
+
                 local = session.getProperty("mail." + protocol + ".localhost");
                 if (isEmpty(local)) {
                     local = session.getProperty("mail."
@@ -3176,37 +3156,27 @@
                         } else {
                             verifyHost(mailHost);
                         }
- } catch (final IOException IOE) {
+ } catch (final RuntimeException | IOException IOE) {
                         MessagingException ME =
                                 new MessagingException(msg, IOE);
                         setErrorContent(abort, verify, ME);
                         reportError(abort, ME, ErrorManager.OPEN_FAILURE);
- } catch (final RuntimeException RE) {
- MessagingException ME =
- new MessagingException(msg, RE);
- setErrorContent(abort, verify, RE);
- reportError(abort, ME, ErrorManager.OPEN_FAILURE);
                     }
                 }
             }
 
             if (!"limited".equals(verify)) {
                 try { //Verify host name and hit the host name cache.
- if (!"remote".equals(verify)) {
+ if (!"remote".equals(verify) && !"login".equals(verify)) {
                         local = getLocalHost(t);
                     }
                     verifyHost(local);
- } catch (final IOException IOE) {
+ } catch (final RuntimeException | IOException IOE) {
                     MessagingException ME = new MessagingException(msg, IOE);
                     setErrorContent(abort, verify, ME);
                     reportError(abort, ME, ErrorManager.OPEN_FAILURE);
- } catch (final RuntimeException RE) {
- MessagingException ME = new MessagingException(msg, RE);
- setErrorContent(abort, verify, ME);
- reportError(abort, ME, ErrorManager.OPEN_FAILURE);
                 }
 
-
                 try { //Verify that the DataHandler can be loaded.
                     Object ccl = getAndSetContextClassLoader(MAILHANDLER_LOADER);
                     try {
@@ -3291,6 +3261,65 @@
     }
 
     /**
+ * Handles all exceptions thrown when save changes is called on a message
+ * that doesn't have any content.
+ *
+ * @param abort the message requiring save changes.
+ * @param msg the error description.
+ * @since JavaMail 1.6.0
+ */
+ private void saveChangesNoContent(final Message abort, final String msg) {
+ if (abort != null) {
+ try {
+ try {
+ abort.saveChanges();
+ } catch (final NullPointerException xferEncoding) {
+ //Workaround GNU JavaMail bug in MimeUtility.getEncoding
+ //when the mime message has no content.
+ try {
+ String cte = "Content-Transfer-Encoding";
+ if (abort.getHeader(cte) == null) {
+ abort.setHeader(cte, "base64");
+ abort.saveChanges();
+ } else {
+ throw xferEncoding;
+ }
+ } catch (RuntimeException | MessagingException e) {
+ if (e != xferEncoding) {
+ e.addSuppressed(xferEncoding);
+ }
+ throw e;
+ }
+ }
+ } catch (RuntimeException | MessagingException ME) {
+ reportError(msg, ME, ErrorManager.FORMAT_FAILURE);
+ }
+ }
+ }
+
+ /**
+ * Cache common session properties into the LogManagerProperties. This is
+ * a workaround for JDK-7092981.
+ *
+ * @param session the session.
+ * @param protocol the mail protocol.
+ * @throws NullPointerException if session is null.
+ * @since JavaMail 1.6.0
+ */
+ private static void verifyProperties(Session session, String protocol) {
+ session.getProperty("mail.from");
+ session.getProperty("mail." + protocol + ".from");
+ session.getProperty("mail.dsn.ret");
+ session.getProperty("mail." + protocol + ".dsn.ret");
+ session.getProperty("mail.dsn.notify");
+ session.getProperty("mail." + protocol + ".dsn.notify");
+ session.getProperty("mail." + protocol + ".port");
+ session.getProperty("mail.user");
+ session.getProperty("mail." + protocol + ".user");
+ session.getProperty("mail." + protocol + ".localport");
+ }
+
+ /**
      * Perform a lookup of the host address or FQDN.
      * @param host the host or null.
      * @return the address.
@@ -3377,10 +3406,8 @@
             msg.setDescription(msgDesc);
             setAcceptLang(msg);
             msg.saveChanges();
- } catch (final MessagingException ME) {
+ } catch (MessagingException | RuntimeException ME) {
             reportError("Unable to create body.", ME, ErrorManager.OPEN_FAILURE);
- } catch (final RuntimeException RE) {
- reportError("Unable to create body.", RE, ErrorManager.OPEN_FAILURE);
         }
     }
 
@@ -3947,12 +3974,9 @@
                     throw new MessagingException("No local address.");
                 }
             }
- } catch (final MessagingException ME) {
+ } catch (MessagingException | RuntimeException ME) {
             reportError("Unable to compute a default recipient.",
                     ME, ErrorManager.FORMAT_FAILURE);
- } catch (final RuntimeException RE) {
- reportError("Unable to compute a default recipient.",
- RE, ErrorManager.FORMAT_FAILURE);
         }
     }
 
@@ -4047,7 +4071,7 @@
     private String toRawString(final Message msg) throws MessagingException, IOException {
         if (msg != null) {
             Object ccl = getAndSetContextClassLoader(MAILHANDLER_LOADER);
- try { //BUGID 8025251
+ try { //JDK-8025251
                 int nbytes = Math.max(msg.getSize() + MIN_HEADER_SIZE, MIN_HEADER_SIZE);
                 ByteArrayOutputStream out = new ByteArrayOutputStream(nbytes);
                 msg.writeTo(out);
@@ -4076,12 +4100,12 @@
                     new ByteArrayOutputStream(MIN_HEADER_SIZE);
 
             //Create an output stream writer so streams are not double buffered.
- final PrintWriter pw =
- new PrintWriter(new OutputStreamWriter(out, charset));
- pw.println(t.getMessage());
- t.printStackTrace(pw);
- pw.flush();
- pw.close(); //BUG ID 6995537
+ try (OutputStreamWriter ows = new OutputStreamWriter(out, charset);
+ PrintWriter pw = new PrintWriter(ows)) {
+ pw.println(t.getMessage());
+ t.printStackTrace(pw);
+ pw.flush();
+ } //Close OSW before generating string. JDK-6995537
             return out.toString(charset);
         } catch (final RuntimeException unexpected) {
             return t.toString() + ' ' + unexpected.toString();
@@ -4150,6 +4174,10 @@
                     return head;
                 }
             }
+
+ if (optional != required) {
+ required.addSuppressed(optional);
+ }
         }
         return required;
     }
@@ -4163,9 +4191,8 @@
     private String getLocalHost(final Service s) {
         try {
             return LogManagerProperties.getLocalHost(s);
- } catch (final SecurityException ignore) {
- } catch (final NoSuchMethodException ignore) {
- } catch (final LinkageError ignore) {
+ } catch (SecurityException | NoSuchMethodException
+ | LinkageError ignore) {
         } catch (final Exception ex) {
             reportError(s.toString(), ex, ErrorManager.OPEN_FAILURE);
         }
@@ -4200,7 +4227,7 @@
     }
 
     /**
- * Outline the creation of the index error message. See BUG ID 6533165.
+ * Outline the creation of the index error message. See JDK-6533165.
      * @param i the index.
      * @return the error message.
      */

diff -r d802403c6f62 -r 8ae6606d365b mail/src/test/java/com/sun/mail/util/logging/AbstractLogging.java
--- a/mail/src/test/java/com/sun/mail/util/logging/AbstractLogging.java Mon Oct 17 13:46:00 2016 -0700
+++ b/mail/src/test/java/com/sun/mail/util/logging/AbstractLogging.java Fri Oct 21 12:32:57 2016 -0700
@@ -93,9 +93,7 @@
                     && Level.class.isAssignableFrom(field.getType())) {
                 try {
                     a.add((Level) field.get((Object) null));
- } catch (IllegalArgumentException ex) {
- fail(ex.toString());
- } catch (IllegalAccessException ex) {
+ } catch (IllegalArgumentException | IllegalAccessException ex) {
                     fail(ex.toString());
                 }
             }
@@ -104,6 +102,19 @@
     }
 
     /**
+ * Determines if the given class is from the JavaMail API Reference
+ * Implementation {_at_code com.sun.mail} package.
+ *
+ * @param k the type to test.
+ * @return true if this is part of reference implementation but not part of
+ * the official API spec.
+ * @throws Exception if there is a problem.
+ */
+ final boolean isPrivateSpec(final Class<?> k) throws Exception {
+ return isFromJavaMail(k, false);
+ }
+
+ /**
      * Reinitialize the logging properties using the given properties.
      *
      * @param manager the log manager.
@@ -163,8 +174,7 @@
             Class.forName("java.time.ZonedDateTime");
             Class.forName("java.time.ZoneId");
             return true;
- } catch (final ClassNotFoundException notSupported) {
- } catch (final LinkageError notSupported) {
+ } catch (final ClassNotFoundException | LinkageError notSupported) {
         }
         return false;
     }

diff -r d802403c6f62 -r 8ae6606d365b mail/src/test/java/com/sun/mail/util/logging/LogManagerPropertiesTest.java
--- a/mail/src/test/java/com/sun/mail/util/logging/LogManagerPropertiesTest.java Mon Oct 17 13:46:00 2016 -0700
+++ b/mail/src/test/java/com/sun/mail/util/logging/LogManagerPropertiesTest.java Fri Oct 21 12:32:57 2016 -0700
@@ -210,11 +210,8 @@
             props.put(k.getName().concat(".dummy"), "value");
             final File f = File.createTempFile(k.getName(), ".properties");
             try {
- final FileOutputStream out = new FileOutputStream(f);
- try {
+ try (FileOutputStream out = new FileOutputStream(f)) {
                     props.store(out, "testFromLogManagerAbsent");
- } finally {
- out.close();
                 }
                 System.setProperty(cfgKey, f.getAbsolutePath());
                 final Method m = k.getDeclaredMethod("readConfiguration");
@@ -397,8 +394,16 @@
         p.setProperty("mail.smtp.localhost", host);
         Session s = Session.getInstance(p);
         Transport t = s.getTransport(InternetAddress.getLocalAddress(s));
- String h = LogManagerProperties.getLocalHost(t);
- Assert.assertEquals(host, h);
+ try {
+ String h = LogManagerProperties.getLocalHost(t);
+ if (h != null || isPrivateSpec(t.getClass())) {
+ Assert.assertEquals(host, h);
+ }
+ } catch (NoSuchMethodException notOfficial) {
+ if (isPrivateSpec(t.getClass())) {
+ fail(t.toString());
+ }
+ }
     }
 
     @Test
@@ -440,9 +445,7 @@
         try {
             long ms = LogManagerProperties.parseDurationToMillis("PT0.345S");
             assertEquals(345L, ms);
- } catch (ClassNotFoundException ignore) {
- assertFalse(ignore.toString(), hasJavaTimeModule());
- } catch (NoClassDefFoundError ignore) {
+ } catch (ClassNotFoundException | NoClassDefFoundError ignore) {
             assertFalse(ignore.toString(), hasJavaTimeModule());
         }
     }
@@ -452,9 +455,7 @@
         try {
             long ms = LogManagerProperties.parseDurationToMillis("PT20.345S");
             assertEquals((20L * 1000L) + 345L, ms);
- } catch (ClassNotFoundException ignore) {
- assertFalse(ignore.toString(), hasJavaTimeModule());
- } catch (NoClassDefFoundError ignore) {
+ } catch (ClassNotFoundException | NoClassDefFoundError ignore) {
             assertFalse(ignore.toString(), hasJavaTimeModule());
         }
     }
@@ -464,9 +465,7 @@
         try {
             long ms = LogManagerProperties.parseDurationToMillis("PT15M");
             assertEquals(15L * 60L * 1000L, ms);
- } catch (ClassNotFoundException ignore) {
- assertFalse(ignore.toString(), hasJavaTimeModule());
- } catch (NoClassDefFoundError ignore) {
+ } catch (ClassNotFoundException | NoClassDefFoundError ignore) {
             assertFalse(ignore.toString(), hasJavaTimeModule());
         }
     }
@@ -476,9 +475,7 @@
         try {
             long ms = LogManagerProperties.parseDurationToMillis("PT10H");
             assertEquals(10L * 60L * 60L * 1000L, ms);
- } catch (ClassNotFoundException ignore) {
- assertFalse(ignore.toString(), hasJavaTimeModule());
- } catch (NoClassDefFoundError ignore) {
+ } catch (ClassNotFoundException | NoClassDefFoundError ignore) {
             assertFalse(ignore.toString(), hasJavaTimeModule());
         }
     }
@@ -488,9 +485,7 @@
         try {
             long ms = LogManagerProperties.parseDurationToMillis("P2D");
             assertEquals(2L * 24L * 60L * 60L * 1000L, ms);
- } catch (ClassNotFoundException ignore) {
- assertFalse(ignore.toString(), hasJavaTimeModule());
- } catch (NoClassDefFoundError ignore) {
+ } catch (ClassNotFoundException | NoClassDefFoundError ignore) {
             assertFalse(ignore.toString(), hasJavaTimeModule());
         }
     }
@@ -503,9 +498,7 @@
             assertEquals((2L * 24L * 60L * 60L * 1000L)
                     + (3L * 60L * 60L * 1000L) + (4L * 60L * 1000L)
                     + ((20L * 1000L) + 345), ms);
- } catch (ClassNotFoundException ignore) {
- assertFalse(ignore.toString(), hasJavaTimeModule());
- } catch (NoClassDefFoundError ignore) {
+ } catch (ClassNotFoundException | NoClassDefFoundError ignore) {
             assertFalse(ignore.toString(), hasJavaTimeModule());
         }
     }
@@ -764,8 +757,13 @@
 
             final Session session = Session.getInstance(mp);
             final Object t = session.getTransport("smtp");
- final String clazzName = "com.sun.mail.smtp.SMTPTransport";
- assertEquals(clazzName, t.getClass().getName());
+ if (isPrivateSpec(t.getClass())) {
+ final String clazzName = "com.sun.mail.smtp.SMTPTransport";
+ assertEquals(clazzName, t.getClass().getName());
+ } else {
+ assertNotNull(t);
+ session.getProperty(keyShort); //Force a read through session.
+ }
             assertTrue(contains(mp, keyShort, "true"));
         } finally {
             manager.reset();
@@ -1229,10 +1227,8 @@
                 mod.setInt(f, f.getModifiers() & ~Modifier.FINAL);
                 return mod;
             }
- } catch (RuntimeException re) {
+ } catch (RuntimeException | ReflectiveOperationException re) {
             Assume.assumeNoException(re);
- } catch (Exception e) {
- Assume.assumeNoException(e);
         }
         throw new AssertionError();
     }

diff -r d802403c6f62 -r 8ae6606d365b mail/src/test/java/com/sun/mail/util/logging/MailHandlerTest.java
--- a/mail/src/test/java/com/sun/mail/util/logging/MailHandlerTest.java Mon Oct 17 13:46:00 2016 -0700
+++ b/mail/src/test/java/com/sun/mail/util/logging/MailHandlerTest.java Fri Oct 21 12:32:57 2016 -0700
@@ -40,7 +40,6 @@
  */
 package com.sun.mail.util.logging;
 
-import com.sun.mail.util.SocketConnectException;
 import java.io.*;
 import java.lang.management.CompilationMXBean;
 import java.lang.management.ManagementFactory;
@@ -1225,7 +1224,12 @@
     public void testEncoding() throws Exception {
         final String enc = "iso8859_1";
         //names are different but equal encodings.
- assertFalse(enc, enc.equals(MimeUtility.mimeCharset(enc)));
+ final String found = MimeUtility.mimeCharset(enc);
+ Class<?> k = Session.getInstance(new Properties())
+ .getTransport("smtp").getClass();
+ if (isPrivateSpec(k)) {
+ assertFalse(enc + "==" + found, enc.equals(found));
+ }
 
         LogManager manager = LogManager.getLogManager();
         final MailHandler instance = new MailHandler(createInitProperties(""));
@@ -2751,11 +2755,8 @@
         final File f = File.createTempFile(name, ".properties", findClassPathDir());
         Locale.setDefault(Locale.US);
         try {
- FileOutputStream fos = new FileOutputStream(f);
- try {
+ try (FileOutputStream fos = new FileOutputStream(f)) {
                 props.store(fos, "No Comment");
- } finally {
- fos.close();
             }
 
             String bundleName = f.getName().substring(0, f.getName().lastIndexOf('.'));
@@ -2848,11 +2849,8 @@
         final File f = File.createTempFile(name, "_"
                 + Locale.ENGLISH.getLanguage() + ".properties", findClassPathDir());
         try {
- FileOutputStream fos = new FileOutputStream(f);
- try {
+ try (FileOutputStream fos = new FileOutputStream(f)) {
                 props.store(fos, "No Comment");
- } finally {
- fos.close();
             }
 
             String bundleName = f.getName().substring(0, f.getName().lastIndexOf('_'));
@@ -3052,11 +3050,8 @@
         }
         final File f = File.createTempFile(name, prefix + ".properties", findClassPathDir());
         try {
- FileOutputStream fos = new FileOutputStream(f);
- try {
+ try (FileOutputStream fos = new FileOutputStream(f)) {
                 props.store(fos, "No Comment");
- } finally {
- fos.close();
             }
 
             Logger log;
@@ -3157,10 +3152,8 @@
                 }
             } catch (final IOException ioe) {
                 fail = ioe;
- } catch (final URISyntaxException use) {
+ } catch (final URISyntaxException | IllegalArgumentException use) {
                 fail = (IOException) new IOException(use.toString()).initCause(use);
- } catch (final IllegalArgumentException iae) {
- fail = (IOException) new IOException(iae.toString()).initCause(iae);
             }
         }
 
@@ -3597,7 +3590,9 @@
         props.put("mail.transport.protocol", "smtp");
         Session s = Session.getInstance(props);
         Transport t = s.getTransport();
- assertEquals(UNKNOWN_HOST, t.getURLName().getHost());
+ if (isPrivateSpec(t.getClass())) {
+ assertEquals(UNKNOWN_HOST, t.getURLName().getHost());
+ }
     }
 
     @Test
@@ -3821,8 +3816,7 @@
         try {
             instance.setAttachmentNames(new String[1]);
             fail("Mismatch with attachment formatters.");
- } catch (NullPointerException pass) {
- } catch (IndexOutOfBoundsException pass) {
+ } catch (NullPointerException | IndexOutOfBoundsException pass) {
         } catch (RuntimeException re) {
             fail(re.toString());
         }
@@ -3887,8 +3881,7 @@
         try {
             instance.setAttachmentNames(new Formatter[2]);
             fail("formatter mismatch.");
- } catch (NullPointerException pass) {
- } catch (IndexOutOfBoundsException pass) {
+ } catch (NullPointerException | IndexOutOfBoundsException pass) {
         } catch (RuntimeException re) {
             fail(re.toString());
         }
@@ -4036,7 +4029,9 @@
         for (Exception exception : em.exceptions) {
             if (exception instanceof MessagingException) {
                 continue;
- } else if (exception instanceof RuntimeException && exception.getMessage().indexOf(instance.getFilter().toString()) > -1 && exception.getMessage().indexOf(Arrays.asList(instance.getAttachmentFilters()).toString()) > -1) {
+ } else if (exception instanceof RuntimeException
+ && exception.getMessage().contains(instance.getFilter().toString())
+ && exception.getMessage().contains(Arrays.asList(instance.getAttachmentFilters()).toString())) {
                 seenFormat++;
                 continue; //expected.
             } else {
@@ -4070,7 +4065,8 @@
         for (Exception exception : em.exceptions) {
             if (exception instanceof MessagingException) {
                 continue;
- } else if (exception instanceof RuntimeException && exception.getMessage().contains(instance.getFilter().toString())) {
+ } else if (exception instanceof RuntimeException
+ && exception.getMessage().contains(instance.getFilter().toString())) {
                 seenFormat++;
                 continue; //expected.
             } else {
@@ -4113,7 +4109,8 @@
         for (Exception exception : em.exceptions) {
             if (exception instanceof MessagingException) {
                 continue;
- } else if (exception instanceof RuntimeException && exception.getMessage().indexOf(instance.getFilter().toString()) > -1) {
+ } else if (exception instanceof RuntimeException
+ && exception.getMessage().contains(instance.getFilter().toString())) {
                 seenFormat++;
                 continue; //expected.
             } else {
@@ -4761,8 +4758,7 @@
                 assertEquals(1, h.getAttachmentFormatters().length);
                 h.setAttachmentFilters((Filter[]) null);
                 fail("Missing secure check.");
- } catch (SecurityException pass) {
- } catch (NullPointerException pass) {
+ } catch (SecurityException | NullPointerException pass) {
             } catch (Exception fail) {
                 fail(fail.toString());
             }
@@ -4780,8 +4776,7 @@
                 assertEquals(1, h.getAttachmentFormatters().length);
                 h.setAttachmentNames((String[]) null);
                 fail("Missing secure check.");
- } catch (SecurityException pass) {
- } catch (NullPointerException pass) {
+ } catch (SecurityException | NullPointerException pass) {
             } catch (Exception fail) {
                 fail(fail.toString());
             }
@@ -4790,8 +4785,7 @@
                 assertEquals(1, h.getAttachmentFormatters().length);
                 h.setAttachmentNames((Formatter[]) null);
                 fail("Missing secure check.");
- } catch (SecurityException pass) {
- } catch (NullPointerException pass) {
+ } catch (SecurityException | NullPointerException pass) {
             } catch (Exception fail) {
                 fail(fail.toString());
             }
@@ -4830,8 +4824,7 @@
             try {
                 h.setAuthenticator((Authenticator) null);
                 fail("Missing secure check.");
- } catch (SecurityException pass) {
- } catch (NullPointerException pass) {
+ } catch (SecurityException | NullPointerException pass) {
             } catch (Exception fail) {
                 fail(fail.toString());
             }
@@ -4839,8 +4832,7 @@
             try {
                 h.setComparator((Comparator<? super LogRecord>) null);
                 fail("Missing secure check.");
- } catch (SecurityException pass) {
- } catch (NullPointerException pass) {
+ } catch (SecurityException | NullPointerException pass) {
             } catch (Exception fail) {
                 fail(fail.toString());
             }
@@ -4864,8 +4856,7 @@
             try {
                 h.setLevel((Level) null);
                 fail("Missing secure check.");
- } catch (SecurityException pass) {
- } catch (NullPointerException pass) {
+ } catch (SecurityException | NullPointerException pass) {
             } catch (Exception fail) {
                 fail(fail.toString());
             }
@@ -4913,8 +4904,7 @@
             try {
                 h.setFormatter((Formatter) null);
                 fail("Missing secure check.");
- } catch (SecurityException pass) {
- } catch (NullPointerException pass) {
+ } catch (SecurityException | NullPointerException pass) {
             } catch (Exception fail) {
                 fail(fail.toString());
             }
@@ -4946,8 +4936,7 @@
             try {
                 h.setErrorManager((ErrorManager) null);
                 fail("Missing secure check.");
- } catch (SecurityException pass) {
- } catch (NullPointerException pass) {
+ } catch (SecurityException | NullPointerException pass) {
             } catch (Exception fail) {
                 fail(fail.toString());
             }
@@ -4995,8 +4984,7 @@
             try {
                 h.setMailProperties((Properties) null);
                 fail("Missing secure check.");
- } catch (SecurityException pass) {
- } catch (NullPointerException pass) {
+ } catch (SecurityException | NullPointerException pass) {
             } catch (Exception fail) {
                 fail(fail.toString());
             }
@@ -5004,8 +4992,7 @@
             try {
                 h.setPushFilter((Filter) null);
                 fail("Missing secure check.");
- } catch (SecurityException pass) {
- } catch (NullPointerException pass) {
+ } catch (SecurityException | NullPointerException pass) {
             } catch (Exception fail) {
                 fail(fail.toString());
             }
@@ -5029,8 +5016,7 @@
             try {
                 h.setPushLevel((Level) null);
                 fail("Missing secure check.");
- } catch (SecurityException pass) {
- } catch (NullPointerException pass) {
+ } catch (SecurityException | NullPointerException pass) {
             } catch (Exception fail) {
                 fail(fail.toString());
             }
@@ -5046,8 +5032,7 @@
             try {
                 h.setSubject((Formatter) null);
                 fail("Missing secure check.");
- } catch (SecurityException pass) {
- } catch (NullPointerException pass) {
+ } catch (SecurityException | NullPointerException pass) {
             } catch (Exception fail) {
                 fail(fail.toString());
             }
@@ -5055,8 +5040,7 @@
             try {
                 h.setSubject((String) null);
                 fail("Missing secure check.");
- } catch (SecurityException pass) {
- } catch (NullPointerException pass) {
+ } catch (SecurityException | NullPointerException pass) {
             } catch (Exception fail) {
                 fail(fail.toString());
             }
@@ -5166,8 +5150,7 @@
             try {
                 hardRef = new MailHandler(-100);
                 fail("Missing secure check.");
- } catch (SecurityException pass) {
- } catch (IllegalArgumentException pass) {
+ } catch (SecurityException | IllegalArgumentException pass) {
             } catch (Exception fail) {
                 fail(fail.toString());
             }
@@ -5175,8 +5158,7 @@
             try {
                 hardRef = new MailHandler((Properties) null);
                 fail("Missing secure check.");
- } catch (SecurityException pass) {
- } catch (NullPointerException pass) {
+ } catch (SecurityException | NullPointerException pass) {
             } catch (Exception fail) {
                 fail(fail.toString());
             }
@@ -5240,15 +5222,12 @@
         msg.addFrom(from);
         msg.setRecipients(Message.RecipientType.TO, from);
         ByteArrayOutputStream out = new ByteArrayOutputStream(384);
+ msg.setHeader("Content-Transfer-Encoding", "base64");
         msg.saveChanges();
         try {
             msg.writeTo(out);
             fail("Verify type 'remote' may send a message with no content.");
- } catch (MessagingException expect) {
- msg.setContent("", "text/plain");
- msg.saveChanges();
- msg.writeTo(out);
- } catch (IOException expect) {
+ } catch (MessagingException | IOException expect) {
             msg.setContent("", "text/plain");
             msg.saveChanges();
             msg.writeTo(out);
@@ -5267,6 +5246,7 @@
         Address[] from = InternetAddress.parse("me_at_localhost", false);
         msg.addFrom(from);
         msg.setRecipients(Message.RecipientType.TO, from);
+ msg.setHeader("Content-Transfer-Encoding", "base64");
         msg.saveChanges();
         try {
             msg.writeTo(new ByteArrayOutputStream(384));
@@ -5662,6 +5642,27 @@
             instance.close();
         }
 
+ props.put("verify", "login");
+ instance = new MailHandler();
+ try {
+ em = new InternalErrorManager();
+ instance.setErrorManager(em);
+ instance.setMailProperties(props);
+
+ for (Exception exception : em.exceptions) {
+ final Throwable t = exception;
+ if (isConnectOrTimeout(t)) {
+ continue;
+ }
+ if (t instanceof AddressException == false) {
+ dump(t);
+ fail(t.toString());
+ }
+ }
+ } finally {
+ instance.close();
+ }
+
         props.put("verify", "remote");
         instance = new MailHandler();
         try {
@@ -6825,7 +6826,13 @@
     }
 
     private static boolean isConnectOrTimeout(Throwable t) {
- if (t instanceof MessagingException || t instanceof SocketConnectException) {
+ if (t instanceof MessagingException) {
+ Throwable cause = t.getCause();
+ if (cause == null) { //GNU JavaMail doesn't support 1.4 chaining.
+ cause = ((MessagingException) t).getNextException();
+ }
+ return isConnectOrTimeout(cause);
+ } else if (isInstanceof(t, "com.sun.mail.util.SocketConnectException")) {
             return isConnectOrTimeout(t.getCause());
         } else {
             return t instanceof java.net.ConnectException
@@ -6834,6 +6841,21 @@
         }
     }
 
+ private static boolean isInstanceof(Object o, String s) {
+ if (s == null) {
+ throw new NullPointerException();
+ }
+
+ if (o != null) {
+ for (Class<?> k = o.getClass(); k != null; k = k.getSuperclass()) {
+ if (s.equals(k.getClass().getName())) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
     private static boolean isNoRecipientAddress(Throwable t) {
         if (t instanceof MessagingException) {
             return String.valueOf(t).contains("No recipient addresses");
@@ -6950,12 +6972,9 @@
                 assertEquals("urgent", message.getHeader("Priority")[0]);
                 assertEquals("auto-generated", message.getHeader("auto-submitted")[0]);
                 message.saveChanges();
- } catch (RuntimeException RE) {
+ } catch (RuntimeException | MessagingException RE) {
                 dump(RE);
                 fail(RE.toString());
- } catch (MessagingException ME) {
- dump(ME);
- fail(ME.toString());
             }
         }
     }
@@ -7014,12 +7033,9 @@
                 } else {
                     assertEquals("", locale.getLanguage());
                 }
- } catch (MessagingException me) {
+ } catch (MessagingException | IOException me) {
                 dump(me);
                 fail(me.toString());
- } catch (IOException ioe) {
- dump(ioe);
- fail(ioe.toString());
             }
         }
     }
@@ -7040,12 +7056,9 @@
                 assertNull(message.getHeader("Priority"));
                 assertEquals("auto-generated", message.getHeader("auto-submitted")[0]);
                 message.saveChanges();
- } catch (RuntimeException RE) {
+ } catch (RuntimeException | MessagingException RE) {
                 dump(RE);
                 fail(RE.toString());
- } catch (MessagingException ME) {
- dump(ME);
- fail(ME.toString());
             }
         }
     }