commits@javamail.java.net

[javamail~mercurial:907] MailHandler error manager support for mail.mime.allowutf8 (Bug K6216)

From: <shannon_at_java.net>
Date: Sat, 4 Mar 2017 00:06:23 +0000

Project: javamail
Repository: mercurial
Revision: 907
Author: shannon
Date: 2017-03-03 23:52:59 UTC
Link:

Log Message:
------------
Ignore blank lines in javamail.providers file.
Use doPrivileged when looking for the <java.home>/conf directory.
Update signatures for JavaMail 1.6.
Update release date.
Fix minor FindBugs error.
Better error message when trying to watch a closed IMAP Folder.
MailHandler error manager support for mail.mime.allowutf8 (Bug K6216)
MailHandlerTest fix InaccessibleObjectException errors on JDK9.
MailHandlerTest add test for reflective calls to PreDestroy and PostConstruct.
MailHandlerTest add test for no dependencies on javax.annotations
MailHandlerTest add test for UTF-8 headers (Bug K6216)
AbstractLogging add class testing method for dependencies on javax.annotations
FileErrorManager support for mail.mime.allowutf8 (Bug K6216)

(From Jason)


Revisions:
----------
901
902
903
904
905
906
907


Modified Paths:
---------------
mail/src/main/java/javax/mail/Session.java
mail.sig
doc/spec/JavaMail-1.6-changes.txt
mail/src/main/java/com/sun/mail/smtp/SMTPTransport.java
mail/src/main/java/com/sun/mail/imap/IdleManager.java
mail/src/test/java/com/sun/mail/imap/IMAPIdleManagerTest.java
logging/src/main/java/FileErrorManager.java
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/MailHandlerTest.java


Diffs:
------
diff -r 619dd8dd6335 -r 94fc48617395 mail/src/main/java/javax/mail/Session.java
--- a/mail/src/main/java/javax/mail/Session.java Tue Feb 21 14:36:18 2017 -0800
+++ b/mail/src/main/java/javax/mail/Session.java Tue Feb 28 14:18:41 2017 -0800
@@ -1000,6 +1000,8 @@
 
                 if (currLine.startsWith("#"))
                     continue;
+ if (currLine.trim().length() == 0)
+ continue; // skip blank line
                 Provider.Type type = null;
                 String protocol = null, className = null;
                 String vendor = null, version = null;


diff -r 94fc48617395 -r 46d71e4588e6 mail/src/main/java/javax/mail/Session.java
--- a/mail/src/main/java/javax/mail/Session.java Tue Feb 28 14:18:41 2017 -0800
+++ b/mail/src/main/java/javax/mail/Session.java Tue Feb 28 14:29:30 2017 -0800
@@ -214,13 +214,20 @@
     static {
         String dir = null;
         try {
- String home = System.getProperty("java.home");
- String newdir = home + File.separator + "conf";
- File conf = new File(newdir);
- if (conf.exists())
- dir = newdir + File.separator;
- else
- dir = home + File.separator + "lib" + File.separator;
+ dir = AccessController.doPrivileged(
+ new PrivilegedAction<String>() {
+ @Override
+ public String run() {
+ String home = System.getProperty("java.home");
+ String newdir = home + File.separator + "conf";
+ File conf = new File(newdir);
+ if (conf.exists())
+ return newdir + File.separator;
+ else
+ return home + File.separator +
+ "lib" + File.separator;
+ }
+ });
         } catch (Exception ex) {
             // ignore any exceptions
         }
@@ -947,8 +954,10 @@
 
         // load system-wide javamail.providers from the
         // <java.home>/{conf,lib} directory
- if (confDir != null)
- loadFile(confDir + "javamail.providers", loader);
+ try {
+ if (confDir != null)
+ loadFile(confDir + "javamail.providers", loader);
+ } catch (SecurityException ex) {}
 
         // load the META-INF/javamail.providers file supplied by an application
         loadAllResources("META-INF/javamail.providers", cl, loader);
@@ -1079,8 +1088,10 @@
 
         // load system-wide javamail.address.map from the
         // <java.home>/{conf,lib} directory
- if (confDir != null)
- loadFile(confDir + "javamail.address.map", loader);
+ try {
+ if (confDir != null)
+ loadFile(confDir + "javamail.address.map", loader);
+ } catch (SecurityException ex) {}
 
         if (addressMap.isEmpty()) {
             logger.config("failed to load address map, using defaults");


diff -r 46d71e4588e6 -r c0dc8d119ba6 mail.sig
--- a/mail.sig Tue Feb 28 14:29:30 2017 -0800
+++ b/mail.sig Tue Feb 28 14:31:00 2017 -0800
@@ -73,13 +73,17 @@
 meth public boolean contains(javax.mail.Flags$Flag)
 meth public boolean contains(javax.mail.Flags)
 meth public boolean equals(java.lang.Object)
+meth public boolean retainAll(javax.mail.Flags)
 meth public int hashCode()
 meth public java.lang.Object clone()
+meth public java.lang.String toString()
 meth public java.lang.String[] getUserFlags()
 meth public javax.mail.Flags$Flag[] getSystemFlags()
 meth public void add(java.lang.String)
 meth public void add(javax.mail.Flags$Flag)
 meth public void add(javax.mail.Flags)
+meth public void clearSystemFlags()
+meth public void clearUserFlags()
 meth public void remove(java.lang.String)
 meth public void remove(javax.mail.Flags$Flag)
 meth public void remove(javax.mail.Flags)
@@ -496,7 +500,7 @@
 meth public void setProtocolForAddress(java.lang.String,java.lang.String)
 meth public void setProvider(javax.mail.Provider) throws javax.mail.NoSuchProviderException
 supr java.lang.Object
-hfds addressMap,authTable,authenticator,debug,defaultSession,logger,out,props,providers,providersByClassName,providersByProtocol,q
+hfds addressMap,authTable,authenticator,confDir,debug,defaultSession,logger,out,props,providers,providersByClassName,providersByProtocol,q
 
 CLSS public abstract javax.mail.Store
 cons protected <init>(javax.mail.Session,javax.mail.URLName)
@@ -539,6 +543,7 @@
 
 CLSS public abstract interface javax.mail.UIDFolder
 fld public final static long LASTUID = -1
+fld public final static long MAXUID = 4294967295
 innr public static FetchProfileItem
 meth public abstract javax.mail.Message getMessageByUID(long) throws javax.mail.MessagingException
 meth public abstract javax.mail.Message[] getMessagesByUID(long,long) throws javax.mail.MessagingException
@@ -820,6 +825,8 @@
 meth public javax.mail.internet.InternetAddress[] getGroup(boolean) throws javax.mail.internet.AddressException
 meth public static java.lang.String toString(javax.mail.Address[])
 meth public static java.lang.String toString(javax.mail.Address[],int)
+meth public static java.lang.String toUnicodeString(javax.mail.Address[])
+meth public static java.lang.String toUnicodeString(javax.mail.Address[],int)
 meth public static javax.mail.internet.InternetAddress getLocalAddress(javax.mail.Session)
 meth public static javax.mail.internet.InternetAddress[] parse(java.lang.String) throws javax.mail.internet.AddressException
 meth public static javax.mail.internet.InternetAddress[] parse(java.lang.String,boolean) throws javax.mail.internet.AddressException
@@ -829,11 +836,12 @@
 meth public void setPersonal(java.lang.String,java.lang.String) throws java.io.UnsupportedEncodingException
 meth public void validate() throws javax.mail.internet.AddressException
 supr javax.mail.Address
-hfds ignoreBogusGroupName,rfc822phrase,serialVersionUID,specialsNoDot,specialsNoDotNoAt,useCanonicalHostName
+hfds allowUtf8,ignoreBogusGroupName,rfc822phrase,serialVersionUID,specialsNoDot,specialsNoDotNoAt,useCanonicalHostName
 
 CLSS public javax.mail.internet.InternetHeaders
 cons public <init>()
 cons public <init>(java.io.InputStream) throws javax.mail.MessagingException
+cons public <init>(java.io.InputStream,boolean) throws javax.mail.MessagingException
 fld protected java.util.List<javax.mail.internet.InternetHeaders$InternetHeader> headers
 innr protected final static InternetHeader
 meth public java.lang.String getHeader(java.lang.String,java.lang.String)
@@ -847,6 +855,7 @@
 meth public void addHeader(java.lang.String,java.lang.String)
 meth public void addHeaderLine(java.lang.String)
 meth public void load(java.io.InputStream) throws javax.mail.MessagingException
+meth public void load(java.io.InputStream,boolean) throws javax.mail.MessagingException
 meth public void removeHeader(java.lang.String)
 meth public void setHeader(java.lang.String,java.lang.String)
 supr java.lang.Object
@@ -937,7 +946,7 @@
 meth public void setText(java.lang.String,java.lang.String,java.lang.String) throws javax.mail.MessagingException
 meth public void writeTo(java.io.OutputStream) throws java.io.IOException,javax.mail.MessagingException
 supr javax.mail.BodyPart
-hfds cacheMultipart,decodeFileName,encodeFileName,ignoreMultipartEncoding,setContentTypeFileName,setDefaultTextCharset
+hfds allowutf8,cacheMultipart,decodeFileName,encodeFileName,ignoreMultipartEncoding,setContentTypeFileName,setDefaultTextCharset
 hcls EncodedFileDataSource,MimePartDataHandler
 
 CLSS public javax.mail.internet.MimeMessage
@@ -1034,7 +1043,7 @@
 meth public void writeTo(java.io.OutputStream) throws java.io.IOException,javax.mail.MessagingException
 meth public void writeTo(java.io.OutputStream,java.lang.String[]) throws java.io.IOException,javax.mail.MessagingException
 supr javax.mail.Message
-hfds answeredFlag,mailDateFormat,strict
+hfds allowutf8,answeredFlag,mailDateFormat,strict
 
 CLSS public static javax.mail.internet.MimeMessage$RecipientType
  outer javax.mail.internet.MimeMessage
@@ -1128,7 +1137,7 @@
 meth public static java.lang.String quote(java.lang.String,java.lang.String)
 meth public static java.lang.String unfold(java.lang.String)
 supr java.lang.Object
-hfds ALL_ASCII,MOSTLY_ASCII,MOSTLY_NONASCII,decodeStrict,defaultJavaCharset,defaultMIMECharset,encodeEolStrict,foldEncodedWords,foldText,ignoreUnknownEncoding,java2mime,mime2java,nonAsciiCharsetMap
+hfds ALL_ASCII,MOSTLY_ASCII,MOSTLY_NONASCII,allowUtf8,decodeStrict,defaultJavaCharset,defaultMIMECharset,encodeEolStrict,foldEncodedWords,foldText,ignoreUnknownEncoding,java2mime,mime2java,nonAsciiCharsetMap
 
 CLSS public javax.mail.internet.NewsAddress
 cons public <init>()


diff -r c0dc8d119ba6 -r 7f0dab1d0f7a doc/spec/JavaMail-1.6-changes.txt
--- a/doc/spec/JavaMail-1.6-changes.txt Tue Feb 28 14:31:00 2017 -0800
+++ b/doc/spec/JavaMail-1.6-changes.txt Tue Feb 28 14:31:19 2017 -0800
@@ -2,7 +2,7 @@
                 JavaMail 1.6
                 ============
 
- (Updated XXX, 2017)
+ (Updated August 28, 2017)
 
 Following is a description of the changes to the JavaMail
 API introduced in JavaMail 1.6. The numbers in parentheses
@@ -31,7 +31,7 @@
         }
 
 The Repeatable annotation is not known to Java SE 7 and will be ignored
-when JavaMail 1.6 is used on Java SE 7 (as expected).
+(as expected) when JavaMail 1.6 is used on Java SE 7.
 
 
 ===================================================================
@@ -434,7 +434,7 @@
 ===================================================================
 
 8. MimeMultipart should throw ParseException for parsing errors (6069)
----------------------------------------------------------------
+----------------------------------------------------------------------
 
 ParseException indicates an error parsing MIME messages. In addition
 to applying to MIME headers, it seems reasonable to expand it to cover


diff -r 7f0dab1d0f7a -r fd72b2143ca0 mail/src/main/java/com/sun/mail/smtp/SMTPTransport.java
--- a/mail/src/main/java/com/sun/mail/smtp/SMTPTransport.java Tue Feb 28 14:31:19 2017 -0800
+++ b/mail/src/main/java/com/sun/mail/smtp/SMTPTransport.java Wed Mar 01 14:12:10 2017 -0800
@@ -2618,8 +2618,8 @@
             if (!utf8 && c >= 128) // not ASCII
                 throw new IllegalArgumentException(
                             "Non-ASCII character in SMTP submitter: " + s);
- if (c < '!' || c > '~' || c == '+' || c == '=' ||
- c >= 128) { // not ASCII
+ if (c < '!' || c > '~' || c == '+' || c == '=') {
+ // not printable ASCII
                 if (sb == null) {
                     sb = new StringBuffer(s.length() + 4);
                     sb.append(s.substring(0, i));


diff -r fd72b2143ca0 -r 001ecd362539 mail/src/main/java/com/sun/mail/imap/IdleManager.java
--- a/mail/src/main/java/com/sun/mail/imap/IdleManager.java Wed Mar 01 14:12:10 2017 -0800
+++ b/mail/src/main/java/com/sun/mail/imap/IdleManager.java Wed Mar 01 14:13:28 2017 -0800
@@ -1,7 +1,7 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright (c) 2014-2016 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014-2017 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
@@ -200,8 +200,13 @@
             throw new MessagingException("Can only watch IMAP folders");
         IMAPFolder ifolder = (IMAPFolder)folder;
         SocketChannel sc = ifolder.getChannel();
- if (sc == null)
- throw new MessagingException("Folder is not using SocketChannels");
+ if (sc == null) {
+ if (folder.isOpen())
+ throw new MessagingException(
+ "Folder is not using SocketChannels");
+ else
+ throw new MessagingException("Folder is not open");
+ }
         if (logger.isLoggable(Level.FINEST))
             logger.log(Level.FINEST, "IdleManager watching {0}",
                                                         folderName(ifolder));

diff -r fd72b2143ca0 -r 001ecd362539 mail/src/test/java/com/sun/mail/imap/IMAPIdleManagerTest.java
--- a/mail/src/test/java/com/sun/mail/imap/IMAPIdleManagerTest.java Wed Mar 01 14:12:10 2017 -0800
+++ b/mail/src/test/java/com/sun/mail/imap/IMAPIdleManagerTest.java Wed Mar 01 14:13:28 2017 -0800
@@ -1,7 +1,7 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright (c) 2009-2016 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009-2017 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
@@ -240,6 +240,110 @@
         }
     }
 
+ @Test
+ public void testNotOpened() {
+ TestServer server = null;
+ IdleManager idleManager = null;
+ try {
+ server = new TestServer(new IMAPHandler());
+ server.start();
+
+ final Properties properties = new Properties();
+ properties.setProperty("mail.imap.host", "localhost");
+ properties.setProperty("mail.imap.port", "" + server.getPort());
+ properties.setProperty("mail.imap.usesocketchannels", "true");
+ final Session session = Session.getInstance(properties);
+ //session.setDebug(true);
+
+ ExecutorService executor = Executors.newCachedThreadPool();
+ idleManager = new IdleManager(session, executor);
+
+ final IMAPStore store = (IMAPStore)session.getStore("imap");
+ Folder folder = null;
+ try {
+ store.connect("test", "test");
+ folder = store.getFolder("INBOX");
+ idleManager.watch(folder);
+
+ fail("No exception");
+ } catch (MessagingException mex) {
+ // make sure we get the expected exception
+ assertTrue(mex.getMessage().contains("open"));
+ // success!
+ } catch (Exception ex) {
+ System.out.println("Failed with exception: " + ex);
+ ex.printStackTrace();
+ fail(ex.toString());
+ } finally {
+ try {
+ folder.close(false);
+ } catch (Exception ex2) { }
+ store.close();
+ }
+ } catch (final Exception e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ } finally {
+ if (idleManager != null)
+ idleManager.stop();
+ if (server != null) {
+ server.quit();
+ }
+ }
+ }
+
+ @Test
+ public void testNoSocketChannel() {
+ TestServer server = null;
+ IdleManager idleManager = null;
+ try {
+ server = new TestServer(new IMAPHandler());
+ server.start();
+
+ final Properties properties = new Properties();
+ properties.setProperty("mail.imap.host", "localhost");
+ properties.setProperty("mail.imap.port", "" + server.getPort());
+ final Session session = Session.getInstance(properties);
+ //session.setDebug(true);
+
+ ExecutorService executor = Executors.newCachedThreadPool();
+ idleManager = new IdleManager(session, executor);
+
+ final IMAPStore store = (IMAPStore)session.getStore("imap");
+ Folder folder = null;
+ try {
+ store.connect("test", "test");
+ folder = store.getFolder("INBOX");
+ folder.open(Folder.READ_WRITE);
+ idleManager.watch(folder);
+
+ fail("No exception");
+ } catch (MessagingException mex) {
+ // make sure we get the expected exception
+ assertTrue(!mex.getMessage().contains("open"));
+ // success!
+ } catch (Exception ex) {
+ System.out.println("Failed with exception: " + ex);
+ ex.printStackTrace();
+ fail(ex.toString());
+ } finally {
+ try {
+ folder.close(false);
+ } catch (Exception ex2) { }
+ store.close();
+ }
+ } catch (final Exception e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ } finally {
+ if (idleManager != null)
+ idleManager.stop();
+ if (server != null) {
+ server.quit();
+ }
+ }
+ }
+
     /**
      * Base class for custom handler.
      */


diff -r 001ecd362539 -r ff7e0fbbe4e5 logging/src/main/java/FileErrorManager.java
--- a/logging/src/main/java/FileErrorManager.java Wed Mar 01 14:13:28 2017 -0800
+++ b/logging/src/main/java/FileErrorManager.java Fri Mar 03 15:52:59 2017 -0800
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2009-2014 Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2009-2014 Jason Mehrens. All Rights Reserved.
+ * Copyright (c) 2009-2017 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009-2017 Jason Mehrens. All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -126,12 +126,9 @@
         if (isRawEmail(msg)) {
             try {
                 storeEmail(msg);
- } catch (final IOException IOE) {
+ } catch (final IOException | RuntimeException IOE) {
                 next.error(msg, ex, code);
                 super.error(emailStore.toString(), IOE, ErrorManager.GENERIC_FAILURE);
- } catch (final RuntimeException RE) {
- next.error(msg, ex, code);
- super.error(emailStore.toString(), RE, ErrorManager.GENERIC_FAILURE);
             }
         } else {
             next.error(msg, ex, code);
@@ -223,12 +220,10 @@
             }
         }
 
- try { //Raw email is ASCII.
- PrintStream ps = new PrintStream(wrap(out), false, "US-ASCII");
+ try (PrintStream ps = new PrintStream(wrap(out), false, "UTF-8")) {
             ps.print(email);
             ps.flush();
             tmp = null; //Don't delete 'tmp' if all bytes were written.
- ps.close();
         } finally {
             close(out);
             delete(tmp); //Only deletes if not null.
@@ -289,6 +284,7 @@
         if (dir == null) {
             dir = AccessController.doPrivileged(new PrivilegedAction<String>() {
 
+ @Override
                 public String run() {
                     return System.getProperty("java.io.tmpdir", ".");
                 }
@@ -303,6 +299,7 @@
      * @param out the stream to wrap.
      * @return the original or wrapped output stream.
      */
+ @SuppressWarnings("UseSpecificCatch")
     private OutputStream wrap(OutputStream out) {
         assert out != null;
         Class<?> k;

diff -r 001ecd362539 -r ff7e0fbbe4e5 mail/src/main/java/com/sun/mail/util/logging/MailHandler.java
--- a/mail/src/main/java/com/sun/mail/util/logging/MailHandler.java Wed Mar 01 14:13:28 2017 -0800
+++ b/mail/src/main/java/com/sun/mail/util/logging/MailHandler.java Fri Mar 03 15:52:59 2017 -0800
@@ -1,8 +1,8 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright (c) 2009-2016 Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2009-2016 Jason Mehrens. All rights reserved.
+ * Copyright (c) 2009-2017 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009-2017 Jason Mehrens. 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
@@ -4086,8 +4086,8 @@
             try { //JDK-8025251
                 int nbytes = Math.max(msg.getSize() + MIN_HEADER_SIZE, MIN_HEADER_SIZE);
                 ByteArrayOutputStream out = new ByteArrayOutputStream(nbytes);
- msg.writeTo(out);
- return out.toString("US-ASCII"); //Raw message is always ASCII.
+ msg.writeTo(out); //Headers can be UTF-8 or US-ASCII.
+ return out.toString("UTF-8");
             } finally {
                 getAndSetContextClassLoader(ccl);
             }

diff -r 001ecd362539 -r ff7e0fbbe4e5 mail/src/test/java/com/sun/mail/util/logging/AbstractLogging.java
--- a/mail/src/test/java/com/sun/mail/util/logging/AbstractLogging.java Wed Mar 01 14:13:28 2017 -0800
+++ b/mail/src/test/java/com/sun/mail/util/logging/AbstractLogging.java Fri Mar 03 15:52:59 2017 -0800
@@ -1,8 +1,8 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2016 Jason Mehrens. All rights reserved.
+ * Copyright (c) 2016-2017 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016-2017 Jason Mehrens. 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
@@ -44,6 +44,7 @@
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.lang.annotation.Annotation;
+import java.lang.reflect.AccessibleObject;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
@@ -285,6 +286,36 @@
     }
 
     /**
+ * Checks that the given class is not dependent on the
+ * {_at_code javax.annotation} classes as they are not present in all
+ * environments.
+ *
+ * @param k the class to inspect.
+ * @throws Exception if there is a problem.
+ */
+ final void testNoDependencyOnJavaxAnnotations(Class<?> k) throws Exception {
+ for (Method m : k.getDeclaredMethods()) {
+ testNoJavaxAnnotation(m);
+ }
+
+ for (Field f : k.getDeclaredFields()) {
+ testNoJavaxAnnotation(f);
+ }
+
+ for (Constructor<?> c : k.getDeclaredConstructors()) {
+ testNoJavaxAnnotation(c);
+ }
+
+ for (Class<?> i : k.getInterfaces()) {
+ testNoJavaxAnnotation(i);
+ }
+
+ for (Class<?> d : k.getDeclaredClasses()) {
+ testNoDependencyOnJavaxAnnotations(d);
+ }
+ }
+
+ /**
      * WebappClassLoader.clearReferencesStaticFinal() method will ignore fields
      * that have type names that start with 'java.' or 'javax.'. This test
      * checks that the given class conforms to this rule so it doesn't become a
@@ -370,4 +401,17 @@
         }
         return false;
     }
+
+ private void testNoJavaxAnnotation(AccessibleObject fm) throws Exception {
+ for (Annotation a : fm.getAnnotations()) {
+ testNoJavaxAnnotation(a.annotationType());
+ }
+ }
+
+ private void testNoJavaxAnnotation(Class<?> k) throws Exception {
+ for (; k != null; k = k.getSuperclass()) {
+ assertFalse(k.toString(),
+ k.getName().startsWith("javax.annotation"));
+ }
+ }
 }

diff -r 001ecd362539 -r ff7e0fbbe4e5 mail/src/test/java/com/sun/mail/util/logging/MailHandlerTest.java
--- a/mail/src/test/java/com/sun/mail/util/logging/MailHandlerTest.java Wed Mar 01 14:13:28 2017 -0800
+++ b/mail/src/test/java/com/sun/mail/util/logging/MailHandlerTest.java Fri Mar 03 15:52:59 2017 -0800
@@ -1,8 +1,8 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright (c) 2009-2016 Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2009-2016 Jason Mehrens. All rights reserved.
+ * Copyright (c) 2009-2017 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009-2017 Jason Mehrens. 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
@@ -45,6 +45,7 @@
 import java.lang.management.ManagementFactory;
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.net.*;
 import java.util.*;
@@ -565,6 +566,47 @@
     }
 
     @Test
+ public void testReflectiveLifeCycleAccess() throws Exception {
+ final Class<?> k = MailHandler.class;
+ final Method construct = k.getDeclaredMethod("postConstruct");
+ final Method destory = k.getDeclaredMethod("preDestroy");
+ testLifeCycleProtypes(construct);
+ testLifeCycleProtypes(destory);
+
+ MailHandler h = new MailHandler();
+ try {
+ h.setMailProperties(createInitProperties(""));
+ InternalErrorManager em = new InternalErrorManager();
+ h.setErrorManager(em);
+
+ construct.invoke(h);
+ destory.invoke(h);
+
+ for (Throwable t : em.exceptions) {
+ dump(t);
+ }
+ assertEquals(true, em.exceptions.isEmpty());
+ } finally {
+ h.close();
+ }
+ }
+
+ private void testLifeCycleProtypes(Method m) throws Exception {
+ final String s = m.toString();
+ assertTrue(s, MailHandler.class.equals(m.getDeclaringClass()));
+ assertTrue(s, Modifier.isPublic(m.getModifiers()));
+ assertFalse(s, Modifier.isStatic(m.getModifiers()));
+ assertTrue(s, Void.TYPE.equals(m.getReturnType()));
+ assertTrue(s, m.getParameterCount() == 0);
+ assertTrue(s, m.getExceptionTypes().length == 0);
+ }
+
+ @Test
+ public void testNoDependencyOnJavaxAnnotations() throws Exception {
+ testNoDependencyOnJavaxAnnotations(MailHandler.class);
+ }
+
+ @Test
     public void testPreDestroyLinkageError() throws Exception {
         testLinkageErrorWithStack("preDestroy");
     }
@@ -2673,6 +2715,12 @@
         assertEquals(expected, type);
     }
 
+ private ErrorManager getSuperErrorManager(MailHandler h) throws Exception {
+ Method hem = MailHandler.class.getDeclaredMethod("defaultErrorManager");
+ hem.setAccessible(true);
+ return (ErrorManager) hem.invoke(h);
+ }
+
     private String getInlineContentType(Formatter f) throws Exception {
         final String[] value = new String[1];
         MailHandler instance = new MailHandler(createInitProperties(""));
@@ -4469,11 +4517,52 @@
     }
 
     @Test
+ public void testReportErrorUtf8Addresses() throws Exception {
+ final String test = "test\u03b1";
+ final String saddr = test + '@' + UNKNOWN_HOST;
+ final String sender = test + saddr;
+ Properties props = createInitProperties("");
+ props.put("mail.to", saddr);
+ props.put("mail.cc", saddr);
+ props.put("mail.bcc", saddr);
+ props.put("mail.from", saddr);
+ props.put("mail.sender", sender);
+ props.put("mail.mime.allowutf8", "true");
+ MailHandler instance = new MailHandler(props);
+ instance.setEncoding("UTF-8");
+ instance.setFormatter(new SimpleFormatter());
+ instance.setErrorManager(new MessageErrorManager(instance.getMailProperties()) {
+
+ @Override
+ protected void error(MimeMessage message, Throwable t, int code) {
+ try {
+ assertEquals(saddr, toString(message.getFrom()[0]));
+ assertEquals(saddr, toString(message.getRecipients(Message.RecipientType.TO)[0]));
+ assertEquals(saddr, toString(message.getRecipients(Message.RecipientType.CC)[0]));
+ assertEquals(saddr, toString(message.getRecipients(Message.RecipientType.BCC)[0]));
+
+ assertEquals(sender, toString(message.getSender()));
+ assertTrue(String.valueOf(message.getContent()).contains(sender));
+
+ message.saveChanges();
+ } catch (MessagingException | IOException E) {
+ fail(E.toString());
+ }
+ }
+
+ private String toString(Address o) {
+ return ((InternetAddress)o).toUnicodeString();
+ }
+ });
+ instance.publish(new LogRecord(Level.SEVERE, sender));
+ instance.close();
+ }
+
+ @Test
     public void testReportErrorSuper() throws Exception {
+ assertNull(System.getSecurityManager());
         Field mhem = MailHandler.class.getDeclaredField("errorManager");
         mhem.setAccessible(true);
- Field hem = Handler.class.getDeclaredField("errorManager");
- hem.setAccessible(true);
 
         InternalErrorManager superEm = new InternalErrorManager();
         InternalErrorManager em = new InternalErrorManager();
@@ -4481,15 +4570,16 @@
         try {
             Exception tester = new Exception();
             synchronized (h) {
- assertSame(h.getErrorManager(), hem.get(h));
+ assertSame(h.getErrorManager(), getSuperErrorManager(h));
 
                 h.setErrorManager(superEm);
- assertSame(superEm, hem.get(h));
+ assertSame(superEm, getSuperErrorManager(h));
                 assertSame(superEm, mhem.get(h));
 
                 mhem.set(h, em);
                 assertSame(em, h.getErrorManager());
- assertSame(superEm, hem.get(h));
+ assertSame(superEm, getSuperErrorManager(h));
+ assertNotSame(h.getErrorManager(), getSuperErrorManager(h));
                 h.reportError("", tester, ErrorManager.GENERIC_FAILURE);
             }
 
@@ -4506,8 +4596,6 @@
     public void testGaeReportErrorSuper() throws Exception {
         Field mhem = MailHandler.class.getDeclaredField("errorManager");
         mhem.setAccessible(true);
- Field hem = Handler.class.getDeclaredField("errorManager");
- hem.setAccessible(true);
 
         InternalErrorManager em = new InternalErrorManager();
         GaeSecurityManager sm = new GaeSecurityManager();
@@ -4518,12 +4606,21 @@
             try {
                 Exception tester = new Exception();
                 synchronized (h) {
- final Object def = hem.get(h);
+ sm.secure = false;
+ final Object def = getSuperErrorManager(h);
+ assertSame(def, getSuperErrorManager(h));
+ sm.secure = true;
+
                     assertEquals(h.getErrorManager().getClass(), def.getClass());
                     assertNotSame(h.getErrorManager(), def);
 
                     h.setErrorManager(em);
- assertSame(def, hem.get(h));
+ sm.secure = false;
+ final Object sem = getSuperErrorManager(h);
+ sm.secure = true;
+ assertSame(def, sem);
+ assertNotSame(h.getErrorManager(), def);
+ assertNotSame(h.getErrorManager(), sem);
                     assertSame(h.getErrorManager(), em);
 
                     h.reportError("", tester, ErrorManager.GENERIC_FAILURE);
@@ -7005,8 +7102,8 @@
             if (msg != null && msg.length() > 0
                     && !msg.startsWith(Level.SEVERE.getName())) {
                 MimeMessage message;
- try { //Raw message is ascii.
- byte[] b = msg.getBytes("US-ASCII");
+ try { //Headers can be UTF-8 or US-ASCII.
+ byte[] b = msg.getBytes("UTF-8");
                     assertTrue(b.length > 0);
 
                     ByteArrayInputStream in = new ByteArrayInputStream(b);