Merge
diff --git a/.hgtags-top-repo b/.hgtags-top-repo
index a47005a..81e454f 100644
--- a/.hgtags-top-repo
+++ b/.hgtags-top-repo
@@ -658,3 +658,6 @@
 bebb5ab92c46792b4736c2a9b1a71259d66177fc jdk7u291-b01
 bebb5ab92c46792b4736c2a9b1a71259d66177fc jdk7u291-ga
 bebb5ab92c46792b4736c2a9b1a71259d66177fc jdk7u301-b00
+69eb8e28a42df1cbcd30c4f1f3714bb2a199394a jdk7u301-b01
+69eb8e28a42df1cbcd30c4f1f3714bb2a199394a jdk7u301-ga
+69eb8e28a42df1cbcd30c4f1f3714bb2a199394a jdk7u311-b00
diff --git a/corba/.hgtags b/corba/.hgtags
index 92cb01a..59a980f 100644
--- a/corba/.hgtags
+++ b/corba/.hgtags
@@ -660,3 +660,6 @@
 6e512d6f5ba82c817e84ca9ca1d5eed0aa26fa9e jdk7u291-b01
 6e512d6f5ba82c817e84ca9ca1d5eed0aa26fa9e jdk7u291-ga
 6e512d6f5ba82c817e84ca9ca1d5eed0aa26fa9e jdk7u301-b00
+ea96e8115e5e113e6d3a30097c1155ba430f7613 jdk7u301-b01
+ea96e8115e5e113e6d3a30097c1155ba430f7613 jdk7u301-ga
+ea96e8115e5e113e6d3a30097c1155ba430f7613 jdk7u311-b00
diff --git a/hotspot/.hgtags b/hotspot/.hgtags
index 00c038c..6799d08 100644
--- a/hotspot/.hgtags
+++ b/hotspot/.hgtags
@@ -896,3 +896,6 @@
 e228cf201f8eb70da0bdb1f6821eac48d6eb2620 jdk7u291-b01
 e228cf201f8eb70da0bdb1f6821eac48d6eb2620 jdk7u291-ga
 e228cf201f8eb70da0bdb1f6821eac48d6eb2620 jdk7u301-b00
+35022cb9d7788c3afb3e41c09680ad8a2652910b jdk7u301-b01
+35022cb9d7788c3afb3e41c09680ad8a2652910b jdk7u301-ga
+35022cb9d7788c3afb3e41c09680ad8a2652910b jdk7u311-b00
diff --git a/hotspot/src/share/vm/code/dependencies.cpp b/hotspot/src/share/vm/code/dependencies.cpp
index ec473b1..4b26c13 100644
--- a/hotspot/src/share/vm/code/dependencies.cpp
+++ b/hotspot/src/share/vm/code/dependencies.cpp
@@ -884,8 +884,8 @@
   klassOop find_witness_in(KlassDepChange& changes,
                            klassOop context_type,
                            bool participants_hide_witnesses);
-  bool witnessed_reabstraction_in_supers(klassOop k);
  public:
+  bool witnessed_reabstraction_in_supers(klassOop k);
   klassOop find_witness_subtype(klassOop context_type, KlassDepChange* changes = NULL) {
     assert(doing_subtype_search(), "must set up a subtype search");
     // When looking for unexpected concrete types,
@@ -997,15 +997,8 @@
     }
   }
 
-  if (is_witness(new_type)) {
-    if (!ignore_witness(new_type)) {
-      return new_type;
-    }
-  } else if (!doing_subtype_search()) {
-    // No witness found, but is_witness() doesn't detect method re-abstraction in case of spot-checking.
-    if (witnessed_reabstraction_in_supers(new_type)) {
-      return new_type;
-    }
+  if (is_witness(new_type) && !ignore_witness(new_type)) {
+    return new_type;
   }
 
   return NULL;
@@ -1384,16 +1377,87 @@
   return num;
 }
 
+
+// Try to determine whether root method in some context is concrete or not based on the information about the unique method
+// in that context. It exploits the fact that concrete root method is always inherited into the context when there's a unique method.
+// Hence, unique method holder is always a supertype of the context class when root method is concrete.
+// Examples for concrete_root_method
+//      C (C.m uniqm)
+//      |
+//      CX (ctxk) uniqm is inherited into context.
+//
+//      CX (ctxk) (CX.m uniqm) here uniqm is defined in ctxk.
+// Examples for !concrete_root_method
+//      CX (ctxk)
+//      |
+//      C (C.m uniqm) uniqm is in subtype of ctxk.
+bool Dependencies::is_concrete_root_method(methodOop uniqm, klassOop ctxk) {
+  if (uniqm == NULL) {
+    return false; // match Dependencies::is_concrete_method() behavior
+  }
+  // Theoretically, the "direction" of subtype check matters here.
+  // On one hand, in case of interface context with a single implementor, uniqm can be in a superclass of the implementor which
+  // is not related to context class.
+  // On another hand, uniqm could come from an interface unrelated to the context class, but right now it is not possible:
+  // it is required that uniqm->method_holder() is the participant (uniqm->method_holder() <: ctxk), hence a default method
+  // can't be used as unique.
+  if (ctxk->klass_part()->is_interface()) {
+    klassOop implementor = instanceKlass::cast(ctxk)->implementor();
+    assert(implementor != ctxk, "single implementor only"); // should have been invalidated earlier
+    ctxk = implementor;
+  }
+  klassOop holder = uniqm->method_holder();
+  assert(!holder->is_interface(), "no default methods allowed");
+  assert(ctxk->klass_part()->is_subclass_of(holder) || holder->klass_part()->is_subclass_of(ctxk), "not related");
+  return ctxk->klass_part()->is_subclass_of(holder);
+}
+
 // If a class (or interface) has a unique concrete method uniqm, return NULL.
 // Otherwise, return a class that contains an interfering method.
 klassOop Dependencies::check_unique_concrete_method(klassOop ctxk, methodOop uniqm,
                                                     KlassDepChange* changes) {
-  // Here is a missing optimization:  If uniqm->is_final(),
-  // we don't really need to search beneath it for overrides.
-  // This is probably not important, since we don't use dependencies
-  // to track final methods.  (They can't be "definalized".)
   ClassHierarchyWalker wf(uniqm->method_holder(), uniqm);
-  return wf.find_witness_definer(ctxk, changes);
+  klassOop witness = wf.find_witness_definer(ctxk, changes);
+  if (witness != NULL) {
+    return witness;
+  }
+  if (!Dependencies::is_concrete_root_method(uniqm, ctxk) || changes != NULL) {
+    klassOop conck = find_witness_AME(ctxk, uniqm, changes);
+    if (conck != NULL) {
+      // Found a concrete subtype 'conck' which does not override abstract root method.
+      return conck;
+    }
+  }
+  return NULL;
+}
+
+// Search for AME.
+// There are two version of checks.
+//   1) Spot checking version(Classload time). Newly added class is checked for AME.
+//      Checks whether abstract/overpass method is inherited into/declared in newly added concrete class.
+//   2) Compile time analysis for abstract/overpass(abstract klass) root_m. The non uniqm subtrees are checked for concrete classes.
+klassOop Dependencies::find_witness_AME(klassOop ctxk, methodOop m, KlassDepChange* changes) {
+  if (m != NULL) {
+    if (changes != NULL) {
+      // Spot checking version.
+      ClassHierarchyWalker wf(m);
+      klassOop new_type = changes->new_type();
+      if (wf.witnessed_reabstraction_in_supers(new_type)) {
+        return new_type;
+      }
+    } else {
+      // Note: It is required that uniqm->method_holder() is the participant (see ClassHierarchyWalker::found_method()).
+      ClassHierarchyWalker wf(m->method_holder());
+      klassOop conck = wf.find_witness_subtype(ctxk);
+      if (conck != NULL) {
+        methodOop cm = instanceKlass::cast(conck)->find_instance_method(m->name(), m->signature(), Klass::skip_private);
+        if (!Dependencies::is_concrete_method(cm)) {
+          return conck;
+        }
+      }
+    }
+  }
+  return NULL;
 }
 
 // Find the set of all non-abstract methods under ctxk that match m.
@@ -1416,7 +1480,11 @@
       // (This can happen if m is inherited into ctxk and fm overrides it.)
       return NULL;
     }
+  } else if (Dependencies::find_witness_AME(ctxk, fm) != NULL) {
+    // Found a concrete subtype which does not override abstract root method.
+    return NULL;
   }
+  assert(Dependencies::is_concrete_root_method(fm, ctxk) == Dependencies::is_concrete_method(m, ctxk), "mismatch");
 #ifndef PRODUCT
   // Make sure the dependency mechanism will pass this discovery:
   if (VerifyDependencies && fm != NULL) {
diff --git a/hotspot/src/share/vm/code/dependencies.hpp b/hotspot/src/share/vm/code/dependencies.hpp
index 860d69e..a4cd655 100644
--- a/hotspot/src/share/vm/code/dependencies.hpp
+++ b/hotspot/src/share/vm/code/dependencies.hpp
@@ -290,6 +290,9 @@
   static bool is_concrete_method(methodOop m);  // m is invocable
   static Klass* find_finalizable_subclass(Klass* k);
 
+  static bool is_concrete_root_method(methodOop uniqm, klassOop ctxk);
+  static klassOop find_witness_AME(klassOop ctxk, methodOop m, KlassDepChange* changes = NULL);
+
   // These versions of the concreteness queries work through the CI.
   // The CI versions are allowed to skew sometimes from the VM
   // (oop-based) versions.  The cost of such a difference is a
diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp
index c1a16a3..41c5674 100644
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp
@@ -1074,60 +1074,66 @@
 
 // find_instance_method looks up the name/signature in the local methods array
 // and skips over static methods
-methodOop instanceKlass::find_instance_method(Symbol* name, Symbol* signature) {
-  return instanceKlass::find_instance_method(methods(), name, signature);
+methodOop instanceKlass::find_instance_method(Symbol* name, Symbol* signature,
+                                              PrivateLookupMode private_mode)
+{
+  return instanceKlass::find_instance_method(methods(), name, signature, private_mode);
 }
 
 // find_instance_method looks up the name/signature in the local methods array
 // and skips over static methods
-methodOop instanceKlass::find_instance_method(objArrayOop methods, Symbol* name, Symbol* signature) {
-  methodOop meth = instanceKlass::find_method_impl(methods, name, signature, true);
+methodOop instanceKlass::find_instance_method(objArrayOop methods, Symbol* name, Symbol* signature,
+                                              PrivateLookupMode private_mode)
+{
+  methodOop meth = instanceKlass::find_method_impl(methods, name, signature, true, private_mode == skip_private);
   return meth;
 }
 
 // find_method looks up the name/signature in the local methods array
 methodOop instanceKlass::find_method(objArrayOop methods, Symbol* name, Symbol* signature) {
-  return instanceKlass::find_method_impl(methods, name, signature, false);
+  return instanceKlass::find_method_impl(methods, name, signature, false, false);
 }
 
-methodOop instanceKlass::find_method_impl(objArrayOop methods, Symbol* name, Symbol* signature, bool skipping_static) {
-  int hit = find_method_index(methods, name, signature, skipping_static);
+methodOop instanceKlass::find_method_impl(objArrayOop methods, Symbol* name, Symbol* signature, bool skipping_static, bool skipping_private) {
+  int hit = find_method_index(methods, name, signature, skipping_static, skipping_private);
   return hit >= 0 ? (methodOop) methods->obj_at(hit): NULL;
 }
 
-bool instanceKlass::method_matches(methodOop m, Symbol* signature, bool skipping_static) {
-    return (m->signature() == signature) && (!skipping_static || !m->is_static());
+bool instanceKlass::method_matches(methodOop m, Symbol* signature, bool skipping_static, bool skipping_private) {
+    return  ((m->signature() == signature) &&
+            (!skipping_static || !m->is_static()) &&
+            (!skipping_private || !m->is_private()));
 }
 
 // Used indirectly by find_method
 // find_method_index looks in the local methods array to return the index
 // of the matching name/signature
-int instanceKlass::find_method_index(objArrayOop methods, Symbol* name, Symbol* signature, bool skipping_static) {
+int instanceKlass::find_method_index(objArrayOop methods, Symbol* name, Symbol* signature, bool skipping_static, bool skipping_private) {
   int hit = binary_search(methods, name);
   if (hit != -1) {
     methodOop m = (methodOop) methods->obj_at(hit);
 
     // Do linear search to find matching signature.  First, quick check
     // for common case
-    if (method_matches(m, signature, skipping_static)) return hit;
+    if (method_matches(m, signature, skipping_static, skipping_private)) return hit;
     // search downwards through overloaded methods
     int i;
     for (i = hit - 1; i >= 0; --i) {
         methodOop m = (methodOop) methods->obj_at(i);
         assert(m->is_method(), "must be method");
         if (m->name() != name) break;
-        if (method_matches(m, signature, skipping_static)) return i;
+        if (method_matches(m, signature, skipping_static, skipping_private)) return i;
     }
     // search upwards
     for (i = hit + 1; i < methods->length(); ++i) {
         methodOop m = (methodOop) methods->obj_at(i);
         assert(m->is_method(), "must be method");
         if (m->name() != name) break;
-        if (method_matches(m, signature, skipping_static)) return i;
+        if (method_matches(m, signature, skipping_static, skipping_private)) return i;
     }
     // not found
 #ifdef ASSERT
-    int index = skipping_static ? -1 : linear_search(methods, name, signature);
+    int index = (skipping_static || skipping_private) ? -1 : linear_search(methods, name, signature);
     assert(index == -1, err_msg("binary search should have found entry %d", index));
 #endif
   }
diff --git a/hotspot/src/share/vm/oops/instanceKlass.hpp b/hotspot/src/share/vm/oops/instanceKlass.hpp
index ace5129..63bdd9e 100644
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp
@@ -495,14 +495,17 @@
   static methodOop find_method(objArrayOop methods, Symbol* name, Symbol* signature);
 
   // find a local method, but skip static methods
-  methodOop find_instance_method(Symbol* name, Symbol* signature);
-  static methodOop find_instance_method(objArrayOop methods, Symbol* name, Symbol* signature);
+  methodOop find_instance_method(Symbol* name, Symbol* signature,
+                                 PrivateLookupMode private_mode = Klass::find_private);
+  static methodOop find_instance_method(objArrayOop methods, Symbol* name, Symbol* signature,
+                                        PrivateLookupMode private_mode = Klass::find_private);
 
   // true if method matches signature and conforms to skipping_X conditions.
-  static bool method_matches(methodOop m, Symbol* signature, bool skipping_static);
+  static bool method_matches(methodOop m, Symbol* signature, bool skipping_static, bool skipping_private);
 
   // find a local method index in default_methods (returns -1 if not found)
-  static int find_method_index(objArrayOop methods, Symbol* name, Symbol* signature, bool skipping_static);
+
+  static int find_method_index(objArrayOop methods, Symbol* name, Symbol* signature, bool skipping_static, bool skipping_private);
 
   // lookup operation (returns NULL if not found)
   methodOop uncached_lookup_method(Symbol* name, Symbol* signature) const;
@@ -986,7 +989,7 @@
   klassOop array_klass_impl(bool or_null, TRAPS);
 
   // find a local method (returns NULL if not found)
-  static methodOop find_method_impl(objArrayOop methods, Symbol* name, Symbol* signature, bool skipping_static);
+  static methodOop find_method_impl(objArrayOop methods, Symbol* name, Symbol* signature, bool skipping_static, bool skipping_private);
 
 public:
   // sharing support
diff --git a/hotspot/src/share/vm/oops/klass.hpp b/hotspot/src/share/vm/oops/klass.hpp
index ed7f6cb..879cf35 100644
--- a/hotspot/src/share/vm/oops/klass.hpp
+++ b/hotspot/src/share/vm/oops/klass.hpp
@@ -276,6 +276,8 @@
   }
 
  public:
+  enum PrivateLookupMode  { find_private,  skip_private };
+
   // Allocation
   const Klass_vtbl& vtbl_value() const { return *this; }  // used only on "example instances"
   static KlassHandle base_create_klass(KlassHandle& klass, int size, const Klass_vtbl& vtbl, TRAPS);
diff --git a/jaxp/.hgtags b/jaxp/.hgtags
index cb8401c..762d377 100644
--- a/jaxp/.hgtags
+++ b/jaxp/.hgtags
@@ -661,3 +661,6 @@
 4ffef5b738a8c07a734fd89e819f456a3711d7e4 jdk7u291-b01
 4ffef5b738a8c07a734fd89e819f456a3711d7e4 jdk7u291-ga
 4ffef5b738a8c07a734fd89e819f456a3711d7e4 jdk7u301-b00
+f5d08bc7dff82930a843070ef437cea93bb4ae64 jdk7u301-b01
+f5d08bc7dff82930a843070ef437cea93bb4ae64 jdk7u301-ga
+f5d08bc7dff82930a843070ef437cea93bb4ae64 jdk7u311-b00
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XML11EntityScanner.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XML11EntityScanner.java
index ac26f80..95b5e5a 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XML11EntityScanner.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XML11EntityScanner.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -40,6 +40,8 @@
  * @author Michael Glavassevich, IBM
  * @author Neil Graham, IBM
  * @version $Id: XML11EntityScanner.java,v 1.5 2010-11-01 04:39:40 joehw Exp $
+ *
+ * @LastModified: Apr 2021
  */
 
 public class XML11EntityScanner
@@ -697,7 +699,7 @@
                     sawIncompleteSurrogatePair)){
                     fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
                                                "IllegalQName",
-                                               null,
+                                               new Object[]{rawname},
                                                XMLErrorReporter.SEVERITY_FATAL_ERROR);
                 }
                 //check the result: localpart
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java
index 2c81d5c..a9c49fb 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -55,6 +55,7 @@
  * @author Arnaud  Le Hors, IBM
  * @author K.Venugopal Sun Microsystems
  *
+ * @LastModified: Apr 2021
  */
 public class XMLEntityScanner implements XMLLocator  {
 
@@ -860,6 +861,14 @@
                     prefix = fSymbolTable.addSymbol(fCurrentEntity.ch,
                             offset, prefixLength);
                     int len = length - prefixLength - 1;
+                    int startLocal = index +1;
+                    if (!XMLChar.isNCNameStart(fCurrentEntity.ch[startLocal])){
+                        fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
+                                                 "IllegalQName",
+                                                  new Object[]{rawname},
+                                                  XMLErrorReporter.SEVERITY_FATAL_ERROR);
+                    }
+
                     //check the result: localpart
                     checkLimit(Limit.MAX_NAME_LIMIT, fCurrentEntity, index + 1, len);
                     localpart = fSymbolTable.addSymbol(fCurrentEntity.ch,
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties
index c7a23c2..b7bbf67 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties
@@ -277,7 +277,7 @@
         
 # Namespaces support
 # 4. Using Qualified Names
-        IllegalQName = Element or attribute do not match QName production: QName::=(NCName':')?NCName. 
+        IllegalQName = Element or attribute \"{0}\" do not match QName production: QName::=(NCName':')?NCName.
         ElementXMLNSPrefix = Element \"{0}\" cannot have \"xmlns\" as its prefix.
         ElementPrefixUnbound = The prefix \"{0}\" for element \"{1}\" is not bound.
         AttributePrefixUnbound = The prefix \"{2}\" for attribute \"{1}\" associated with an element type \"{0}\" is not bound.
diff --git a/jaxp/src/com/sun/org/apache/xml/internal/serializer/ToStream.java b/jaxp/src/com/sun/org/apache/xml/internal/serializer/ToStream.java
index 2301763..20f87a9 100644
--- a/jaxp/src/com/sun/org/apache/xml/internal/serializer/ToStream.java
+++ b/jaxp/src/com/sun/org/apache/xml/internal/serializer/ToStream.java
@@ -39,6 +39,7 @@
 import com.sun.org.apache.xml.internal.serializer.utils.MsgKey;
 import com.sun.org.apache.xml.internal.serializer.utils.Utils;
 import com.sun.org.apache.xml.internal.serializer.utils.WrappedRuntimeException;
+import jdk.xml.internal.JdkXmlUtils;
 import org.w3c.dom.Node;
 import org.xml.sax.Attributes;
 import org.xml.sax.ContentHandler;
@@ -51,6 +52,7 @@
  * serializers (xml, html, text ...) that write output to a stream.
  *
  * @xsl.usage internal
+ * @LastModified: Apr 2021
  */
 abstract public class ToStream extends SerializerBase
 {
@@ -1882,21 +1884,21 @@
             String doctypeSystem = getDoctypeSystem();
             if (null != doctypeSystem)
             {
-                if (null == doctypePublic)
-                    writer.write(" SYSTEM \"");
-                else
-                    writer.write(" \"");
+                char quote = JdkXmlUtils.getQuoteChar(doctypeSystem);
+                if (null == doctypePublic) {
+                    writer.write(" SYSTEM");
+                }
+                writer.write(" ");
+                writer.write(quote);
 
                 writer.write(doctypeSystem);
-
+                writer.write(quote);
                 if (closeDecl)
                 {
-                    writer.write("\">");
+                    writer.write(">");
                     writer.write(m_lineSep, 0, m_lineSepLen);
                     closeDecl = false; // done closing
                 }
-                else
-                    writer.write('\"');
             }
             boolean dothis = false;
             if (dothis)
diff --git a/jaxp/src/jdk/xml/internal/JdkXmlUtils.java b/jaxp/src/jdk/xml/internal/JdkXmlUtils.java
index 35ff206..012fa77 100644
--- a/jaxp/src/jdk/xml/internal/JdkXmlUtils.java
+++ b/jaxp/src/jdk/xml/internal/JdkXmlUtils.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -249,6 +249,22 @@
         return tf;
     }
 
+    /**
+     * Returns the character to be used to quote the input content. Between
+     * single and double quotes, this method returns the one that is not found
+     * in the input. Returns double quote by default.
+     *
+     * @param s the input string
+     * @return returns the quote not found in the input
+     */
+    public static char getQuoteChar(String s) {
+        if (s != null && s.indexOf('"') > -1) {
+            return '\'';
+        } else {
+            return '"';
+        }
+    }
+
     private static XMLReader getXMLReaderWSAXFactory(boolean overrideDefaultParser) {
         SAXParserFactory saxFactory = getSAXFactory(overrideDefaultParser);
         try {
diff --git a/jaxws/.hgtags b/jaxws/.hgtags
index af75dc2..2d4ff90 100644
--- a/jaxws/.hgtags
+++ b/jaxws/.hgtags
@@ -660,3 +660,6 @@
 156d24d6052eba8c7f4364c3b0b5eb558da9df43 jdk7u291-b01
 156d24d6052eba8c7f4364c3b0b5eb558da9df43 jdk7u291-ga
 156d24d6052eba8c7f4364c3b0b5eb558da9df43 jdk7u301-b00
+d28a9f888fb98f05e44e77dff7dde7384dbe6e30 jdk7u301-b01
+d28a9f888fb98f05e44e77dff7dde7384dbe6e30 jdk7u301-ga
+d28a9f888fb98f05e44e77dff7dde7384dbe6e30 jdk7u311-b00
diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/org/objectweb/asm/ClassReader.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/org/objectweb/asm/ClassReader.java
index ed98247..67ec13c 100644
--- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/org/objectweb/asm/ClassReader.java
+++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/org/objectweb/asm/ClassReader.java
@@ -561,6 +561,9 @@
                 access |= Opcodes.ACC_SYNTHETIC;
             } else if ("SourceDebugExtension".equals(attrName)) {
                 int len = readInt(v + 2);
+                if (len > b.length - (v + 6)) {
+                    throw new IllegalArgumentException();
+                }
                 sourceDebug = readUTF(v + 6, len, new char[len]);
             } else if (ANNOTATIONS && "RuntimeInvisibleAnnotations".equals(attrName)) {
                 ianns = v + 6;
@@ -896,6 +899,9 @@
                 int maxLocals = readUnsignedShort(v + 2);
                 int codeLength = readInt(v + 4);
                 v += 8;
+                if (codeLength > b.length - v) {
+                    throw new IllegalArgumentException();
+                }
 
                 int codeStart = v;
                 int codeEnd = v + codeLength;
diff --git a/jdk/.hgtags b/jdk/.hgtags
index 7c66dc4..8740346 100644
--- a/jdk/.hgtags
+++ b/jdk/.hgtags
@@ -651,3 +651,6 @@
 da9f439a68d68914ff36e55e516a94f596a627fe jdk7u291-b01
 da9f439a68d68914ff36e55e516a94f596a627fe jdk7u291-ga
 da9f439a68d68914ff36e55e516a94f596a627fe jdk7u301-b00
+95f660595bd2d7bd008fedf68222ed558caf6185 jdk7u301-b01
+95f660595bd2d7bd008fedf68222ed558caf6185 jdk7u301-ga
+95f660595bd2d7bd008fedf68222ed558caf6185 jdk7u311-b00
diff --git a/jdk/make/java/zip/mapfile-vers b/jdk/make/java/zip/mapfile-vers
index 7c29865..f83f96d 100644
--- a/jdk/make/java/zip/mapfile-vers
+++ b/jdk/make/java/zip/mapfile-vers
@@ -65,6 +65,7 @@
 		Java_java_util_zip_ZipFile_open;
 		Java_java_util_zip_ZipFile_read;
 		Java_java_util_zip_ZipFile_startsWithLOC;
+		Java_java_util_zip_ZipFile_getManifestNum;
 
 		ZIP_Close;
 		ZIP_CRC32;
diff --git a/jdk/make/java/zip/reorder-i586 b/jdk/make/java/zip/reorder-i586
index 73ea674..7eec24f 100644
--- a/jdk/make/java/zip/reorder-i586
+++ b/jdk/make/java/zip/reorder-i586
@@ -20,6 +20,7 @@
 text: .text%Java_java_util_zip_ZipFile_open;
 text: .text%Java_java_util_zip_ZipFile_getTotal;
 text: .text%Java_java_util_zip_ZipFile_startsWithLOC;
+text: .text%Java_java_util_zip_ZipFile_getManifestNum;
 text: .text%Java_java_util_zip_ZipFile_getEntry;
 text: .text%Java_java_util_zip_ZipFile_freeEntry;
 text: .text%Java_java_util_zip_ZipFile_getEntryTime;
diff --git a/jdk/make/java/zip/reorder-sparc b/jdk/make/java/zip/reorder-sparc
index a5cde39..4656386 100644
--- a/jdk/make/java/zip/reorder-sparc
+++ b/jdk/make/java/zip/reorder-sparc
@@ -19,6 +19,7 @@
 text: .text%Java_java_util_zip_ZipFile_open;
 text: .text%Java_java_util_zip_ZipFile_getTotal;
 text: .text%Java_java_util_zip_ZipFile_startsWithLOC;
+text: .text%Java_java_util_zip_ZipFile_getManifestNum;
 text: .text%Java_java_util_zip_ZipFile_getEntry;
 text: .text%Java_java_util_zip_ZipFile_freeEntry;
 text: .text%Java_java_util_zip_ZipFile_getEntryTime;
diff --git a/jdk/make/java/zip/reorder-sparcv9 b/jdk/make/java/zip/reorder-sparcv9
index 32ebae1..45c00b1 100644
--- a/jdk/make/java/zip/reorder-sparcv9
+++ b/jdk/make/java/zip/reorder-sparcv9
@@ -19,6 +19,7 @@
 text: .text%Java_java_util_zip_ZipFile_open;
 text: .text%Java_java_util_zip_ZipFile_getTotal;
 text: .text%Java_java_util_zip_ZipFile_startsWithLOC;
+text: .text%Java_java_util_zip_ZipFile_getManifestNum;
 text: .text%Java_java_util_zip_ZipFile_getEntry;
 text: .text%Java_java_util_zip_ZipFile_freeEntry;
 text: .text%Java_java_util_zip_ZipFile_getEntryTime;
diff --git a/jdk/src/share/classes/com/sun/jndi/ldap/DefaultLdapDnsProvider.java b/jdk/src/share/classes/com/sun/jndi/ldap/DefaultLdapDnsProvider.java
new file mode 100644
index 0000000..b6d32b4
--- /dev/null
+++ b/jdk/src/share/classes/com/sun/jndi/ldap/DefaultLdapDnsProvider.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.jndi.ldap;
+
+import com.sun.jndi.ldap.spi.LdapDnsProvider;
+import com.sun.jndi.ldap.spi.LdapDnsProviderResult;
+import javax.naming.NamingException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class DefaultLdapDnsProvider {
+
+    public LdapDnsProviderResult lookupEndpoints(String url,
+                                                 Map<?,?> env)
+            throws NamingException
+    {
+        if (url == null || env == null) {
+            throw new NullPointerException();
+        }
+
+        String domainName;
+        List<String> endpoints = new ArrayList<>();
+        LdapURL ldapUrl = new LdapURL(url);
+        String dn = ldapUrl.getDN();
+        String host = ldapUrl.getHost();
+        int port = ldapUrl.getPort();
+        String[] hostports;
+
+        // handle a URL with no hostport (ldap:/// or ldaps:///)
+        // locate the LDAP service using the URL's distinguished name
+        if (host == null
+                && port == -1
+                && dn != null
+                && (domainName = ServiceLocator.mapDnToDomainName(dn)) != null
+                && (hostports = ServiceLocator.getLdapService(domainName, env)) != null) {
+            // Generate new URLs that include the discovered hostports.
+            // Reuse the original URL scheme.
+            String scheme = ldapUrl.getScheme() + "://";
+            String query = ldapUrl.getQuery();
+            String urlSuffix = ldapUrl.getPath() + (query != null ? query : "");
+            for (String hostPort : hostports) {
+                // the hostports come from the DNS SRV records
+                // we assume the SRV record is scheme aware
+                endpoints.add(scheme + hostPort + urlSuffix);
+            }
+        } else {
+            // we don't have enough information to set the domain name
+            // correctly
+            domainName = "";
+            endpoints.add(url);
+        }
+
+        LdapDnsProviderResult res = new LdapDnsProviderResult(domainName, endpoints);
+        if (res.getEndpoints().isEmpty() && res.getDomainName().isEmpty()) {
+            return null;
+        } else {
+            return res;
+        }
+    }
+
+}
diff --git a/jdk/src/share/classes/com/sun/jndi/ldap/LdapCtxFactory.java b/jdk/src/share/classes/com/sun/jndi/ldap/LdapCtxFactory.java
index d6ab731..fe05a59 100644
--- a/jdk/src/share/classes/com/sun/jndi/ldap/LdapCtxFactory.java
+++ b/jdk/src/share/classes/com/sun/jndi/ldap/LdapCtxFactory.java
@@ -35,6 +35,7 @@
 import javax.naming.spi.InitialContextFactory;
 import javax.naming.ldap.Control;
 
+import com.sun.jndi.ldap.spi.LdapDnsProviderResult;
 import com.sun.jndi.url.ldap.ldapURLContextFactory;
 
 final public class LdapCtxFactory implements ObjectFactory, InitialContextFactory {
@@ -158,41 +159,73 @@
     }
 
     private static DirContext getUsingURL(String url, Hashtable<?,?> env)
-            throws NamingException {
-        DirContext ctx = null;
-        LdapURL ldapUrl = new LdapURL(url);
-        String dn = ldapUrl.getDN();
-        String host = ldapUrl.getHost();
-        int port = ldapUrl.getPort();
-        String[] hostports;
-        String domainName = null;
+            throws NamingException
+    {
+        try {
+            LdapDnsProviderResult r =
+                LdapDnsProviderService.getInstance().lookupEndpoints(url, env);
+            LdapCtx ctx;
+            NamingException lastException = null;
 
-        // handle a URL with no hostport (ldap:/// or ldaps:///)
-        // locate the LDAP service using the URL's distinguished name
-        if (host == null &&
-            port == -1 &&
-            dn != null &&
-            (domainName = ServiceLocator.mapDnToDomainName(dn)) != null &&
-            (hostports = ServiceLocator.getLdapService(domainName, env))
-                != null) {
-            // Generate new URLs that include the discovered hostports.
-            // Reuse the original URL scheme.
-            String scheme = ldapUrl.getScheme() + "://";
-            String[] newUrls = new String[hostports.length];
-            String query = ldapUrl.getQuery();
-            String urlSuffix = ldapUrl.getPath() + (query != null ? query : "");
-            for (int i = 0; i < hostports.length; i++) {
-                newUrls[i] = scheme + hostports[i] + urlSuffix;
+            /*
+             * Prior to this change we had been assuming that the url.getDN()
+             * should be converted to a domain name via
+             * ServiceLocator.mapDnToDomainName(url.getDN())
+             *
+             * However this is incorrect as we can't assume that the supplied
+             * url.getDN() is the same as the dns domain for the directory
+             * server.
+             *
+             * This means that we depend on the dnsProvider to return both
+             * the list of urls of individual hosts from which we attempt to
+             * create an LdapCtx from *AND* the domain name that they serve
+             *
+             * In order to do this the dnsProvider must return an
+             * {@link LdapDnsProviderResult}.
+             *
+             */
+            for (String u : r.getEndpoints()) {
+                try {
+                    ctx = getLdapCtxFromUrl(
+                            r.getDomainName(), url, new LdapURL(u), env);
+                    return ctx;
+                } catch (NamingException e) {
+                    // try the next element
+                    lastException = e;
+                }
             }
-            ctx = getUsingURLs(newUrls, env);
-            // Associate the derived domain name with the context
-            ((LdapCtx)ctx).setDomainName(domainName);
 
-        } else {
-            ctx = new LdapCtx(dn, host, port, env, ldapUrl.useSsl());
-            // Record the URL that created the context
-            ((LdapCtx)ctx).setProviderUrl(url);
+            if (lastException != null) {
+                throw lastException;
+            }
+
+            // lookupEndpoints returned an LdapDnsProviderResult with an empty
+            // list of endpoints
+            throw new NamingException("Could not resolve a valid ldap host");
+        } catch (NamingException e) {
+            // lookupEndpoints(url, env) may throw a NamingException, which
+            // there is no need to wrap.
+            throw e;
+        } catch (Exception e) {
+            NamingException ex = new NamingException();
+            ex.setRootCause(e);
+            throw ex;
         }
+    }
+
+    private static LdapCtx getLdapCtxFromUrl(String domain,
+                                             String url,
+                                             LdapURL u,
+                                             Hashtable<?,?> env)
+            throws NamingException
+    {
+        String dn = u.getDN();
+        String host = u.getHost();
+        int port = u.getPort();
+        LdapCtx ctx = new LdapCtx(dn, host, port, env, u.useSsl());
+        ctx.setDomainName(domain);
+        // Record the URL that created the context
+        ctx.setProviderUrl(url);
         return ctx;
     }
 
@@ -202,19 +235,17 @@
      * Not pretty, but potentially more informative than returning null.
      */
     private static DirContext getUsingURLs(String[] urls, Hashtable<?,?> env)
-            throws NamingException {
-        NamingException ne = null;
-        DirContext ctx = null;
-        for (int i = 0; i < urls.length; i++) {
+            throws NamingException
+    {
+        NamingException ex = null;
+        for (String u : urls) {
             try {
-                return getUsingURL(urls[i], env);
-            } catch (AuthenticationException e) {
-                throw e;
+                return getUsingURL(u, env);
             } catch (NamingException e) {
-                ne = e;
+                ex = e;
             }
         }
-        throw ne;
+        throw ex;
     }
 
     /**
diff --git a/jdk/src/share/classes/com/sun/jndi/ldap/LdapDnsProviderService.java b/jdk/src/share/classes/com/sun/jndi/ldap/LdapDnsProviderService.java
new file mode 100644
index 0000000..a8b5cc3
--- /dev/null
+++ b/jdk/src/share/classes/com/sun/jndi/ldap/LdapDnsProviderService.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.jndi.ldap;
+
+import java.security.PrivilegedAction;
+import java.util.*;
+import javax.naming.NamingException;
+import com.sun.jndi.ldap.spi.LdapDnsProvider;
+import com.sun.jndi.ldap.spi.LdapDnsProviderResult;
+import sun.misc.JavaSecurityAccess;
+import sun.misc.SharedSecrets;
+import sun.security.util.SecurityConstants;
+
+/**
+ * The {@code LdapDnsProviderService} is responsible for creating and providing
+ * access to the registered {@code LdapDnsProvider}s. The {@link ServiceLoader}
+ * is used to find and register any implementations of {@link LdapDnsProvider}.
+ *
+ * <p> Instances of this class are safe for use by multiple threads.
+ */
+final class LdapDnsProviderService {
+
+    private static volatile LdapDnsProviderService service;
+    private static final Object LOCK = new int[0];
+    private final ServiceLoader<LdapDnsProvider> providers;
+
+    /**
+     * Creates a new instance of LdapDnsProviderService
+     */
+    private LdapDnsProviderService() {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm == null) {
+            providers = ServiceLoader.load(
+                    LdapDnsProvider.class,
+                    ClassLoader.getSystemClassLoader());
+        } else {
+            final PrivilegedAction<ServiceLoader<LdapDnsProvider>> pa =
+                    new PrivilegedAction<ServiceLoader<LdapDnsProvider>>() {
+                        @Override
+                        public ServiceLoader<LdapDnsProvider> run() {
+                            return ServiceLoader.load(
+                                    LdapDnsProvider.class,
+                                    ClassLoader.getSystemClassLoader());
+                        }
+                    };
+
+            JavaSecurityAccess jsa = SharedSecrets.getJavaSecurityAccess();
+            providers = jsa.doPrivileged(
+                    pa,
+                    null,
+                    new RuntimePermission("ldapDnsProvider"),
+                    SecurityConstants.GET_CLASSLOADER_PERMISSION);
+        }
+    }
+
+    /**
+     * Retrieves the singleton instance of LdapDnsProviderService.
+     */
+    static LdapDnsProviderService getInstance() {
+        if (service != null) return service;
+        synchronized (LOCK) {
+            if (service != null) return service;
+            service = new LdapDnsProviderService();
+        }
+        return service;
+    }
+
+    /**
+     * Retrieves result from the first provider that successfully resolves
+     * the endpoints. If no results are found when calling installed
+     * subclasses of {@code LdapDnsProvider} then this method will fall back
+     * to the {@code DefaultLdapDnsProvider}.
+     *
+     * @throws NamingException if the {@code url} in not valid or an error
+     *                         occurred while performing the lookup.
+     */
+    LdapDnsProviderResult lookupEndpoints(String url, Hashtable<?,?> env)
+        throws NamingException
+    {
+        LdapDnsProviderResult result = null;
+        Hashtable<?, ?> envCopy = new Hashtable<>(env);
+
+        synchronized (LOCK) {
+            Iterator<LdapDnsProvider> iterator = providers.iterator();
+            while (result == null && iterator.hasNext()) {
+                result = iterator.next().lookupEndpoints(url, envCopy);
+                if (result != null && result.getEndpoints().isEmpty()) {
+                    result = null;
+                }
+            }
+        }
+
+        if (result == null) {
+            result = new DefaultLdapDnsProvider().lookupEndpoints(url, env);
+            if (result == null) {
+                return new LdapDnsProviderResult("", Collections.<String>emptyList());
+            }
+        }
+
+        return result;
+    }
+
+}
diff --git a/jdk/src/share/classes/com/sun/jndi/ldap/ServiceLocator.java b/jdk/src/share/classes/com/sun/jndi/ldap/ServiceLocator.java
index 5bbd58d..09c6fe5 100644
--- a/jdk/src/share/classes/com/sun/jndi/ldap/ServiceLocator.java
+++ b/jdk/src/share/classes/com/sun/jndi/ldap/ServiceLocator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,11 +25,7 @@
 
 package com.sun.jndi.ldap;
 
-import java.util.Arrays;
-import java.util.Hashtable;
-import java.util.Random;
-import java.util.StringTokenizer;
-import java.util.List;
+import java.util.*;
 
 import javax.naming.*;
 import javax.naming.directory.*;
@@ -113,6 +109,23 @@
      * @return An ordered list of hostports for the LDAP service or null if
      *         the service has not been located.
      */
+    static String[] getLdapService(String domainName, Map<?,?> environment) {
+        if (environment instanceof Hashtable) {
+            return getLdapService(domainName, (Hashtable)environment);
+        }
+        return getLdapService(domainName, new Hashtable<>(environment));
+    }
+
+    /**
+     * Locates the LDAP service for a given domain.
+     * Queries DNS for a list of LDAP Service Location Records (SRV) for a
+     * given domain name.
+     *
+     * @param domainName A string domain name.
+     * @param environment The possibly null environment of the context.
+     * @return An ordered list of hostports for the LDAP service or null if
+     *         the service has not been located.
+     */
     static String[] getLdapService(String domainName, Hashtable<?,?> environment) {
 
         if (domainName == null || domainName.length() == 0) {
diff --git a/jdk/src/share/classes/com/sun/jndi/ldap/spi/LdapDnsProvider.java b/jdk/src/share/classes/com/sun/jndi/ldap/spi/LdapDnsProvider.java
new file mode 100644
index 0000000..8642f26
--- /dev/null
+++ b/jdk/src/share/classes/com/sun/jndi/ldap/spi/LdapDnsProvider.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.jndi.ldap.spi;
+
+import javax.naming.Context;
+import javax.naming.NamingException;
+import java.util.Map;
+
+/**
+ * Service-provider class for DNS lookups when performing LDAP operations.
+ *
+ * <p> An LDAP DNS provider is a concrete subclass of this class that
+ * has a zero-argument constructor. LDAP DNS providers are located using the
+ * ServiceLoader facility, as specified by
+ * {@linkplain javax.naming.directory.InitialDirContext InitialDirectContext}.
+ *
+ * The
+ * {@link java.util.ServiceLoader ServiceLoader} is used to create and register
+ * implementations of {@code LdapDnsProvider}.
+ *
+ * <p> An LDAP DNS provider can be used in environments where the default
+ * DNS resolution mechanism is not sufficient to accurately pinpoint the
+ * correct LDAP servers needed to perform LDAP operations. For example, in an
+ * environment containing a mix of {@code ldap} and {@code ldaps} servers
+ * you may want the {@linkplain javax.naming.ldap.LdapContext LdapContext}
+ * to query {@code ldaps} servers only.
+ *
+ * @since 12
+ */
+public abstract class LdapDnsProvider {
+
+    // The {@code RuntimePermission("ldapDnsProvider")} is
+    // necessary to subclass and instantiate the {@code LdapDnsProvider} class.
+    private static final RuntimePermission DNSPROVIDER_PERMISSION =
+            new RuntimePermission("ldapDnsProvider");
+
+    /**
+     * Creates a new instance of {@code LdapDnsProvider}.
+     *
+     * @throws SecurityException if a security manager is present and its
+     *                           {@code checkPermission} method doesn't allow
+     *                           the {@code RuntimePermission("ldapDnsProvider")}.
+     */
+    protected LdapDnsProvider() {
+        this(checkPermission());
+    }
+
+    private LdapDnsProvider(Void unused) {
+        // nothing to do.
+    }
+
+    private static Void checkPermission() {
+        final SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(DNSPROVIDER_PERMISSION);
+        }
+        return null;
+    }
+
+    /**
+     * Lookup the endpoints and domain name for the given {@link Context}
+     * {@link Context#PROVIDER_URL provider URL} and environment. The resolved
+     * endpoints and domain name are returned as an
+     * {@link LdapDnsProviderResult}.
+     *
+     * <p> An endpoint is a {@code String} representation of an LDAP URL which
+     * points to an LDAP server to be used for LDAP operations. The syntax of
+     * an LDAP URL is defined by <a href="http://www.ietf.org/rfc/rfc2255.txt">
+     * <i>RFC&nbsp;2255: The LDAP URL Format</i></a>.
+     *
+     * @param url   The {@link Context} {@link Context#PROVIDER_URL provider URL}
+     * @param env   The {@link Context} environment.
+     *
+     * @return  an {@link LdapDnsProviderResult} or null if the lookup fails.
+     *
+     * @throws NamingException      if the {@code url} is not valid or an error
+     *                              occurred while performing the lookup.
+     * @throws NullPointerException if either {@code url} or {@code env} are
+     *                              {@code null}.
+     */
+    public abstract LdapDnsProviderResult lookupEndpoints(
+            String url, Map<?,?> env) throws NamingException;
+
+}
diff --git a/jdk/src/share/classes/com/sun/jndi/ldap/spi/LdapDnsProviderResult.java b/jdk/src/share/classes/com/sun/jndi/ldap/spi/LdapDnsProviderResult.java
new file mode 100644
index 0000000..066e044
--- /dev/null
+++ b/jdk/src/share/classes/com/sun/jndi/ldap/spi/LdapDnsProviderResult.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.jndi.ldap.spi;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * The result of a DNS lookup for an LDAP URL.
+ *
+ * <p> This class is used by an {@link LdapDnsProvider} to return the result
+ * of a DNS lookup for a given LDAP URL. The result consists of a domain name
+ * and its associated ldap server endpoints.
+ *
+ * <p> A {@code null} {@code domainName} is equivalent to and represented
+ * by an empty string.
+ *
+ * @since 12
+ */
+public final class LdapDnsProviderResult {
+
+    private final String domainName;
+    private final List<String> endpoints;
+
+    /**
+     * Construct an LdapDnsProviderResult consisting of a resolved domain name
+     * and the ldap server endpoints that serve the domain.
+     *
+     * @param domainName    the resolved domain name; can be null.
+     * @param endpoints     the possibly empty list of resolved ldap server
+     *                      endpoints
+     *
+     * @throws NullPointerException   if {@code endpoints} contains {@code null}
+     *                                elements.
+     * @throws ClassCastException     if {@code endpoints} contains non-
+     *                                {@code String} elements.
+     */
+    public LdapDnsProviderResult(String domainName, List<String> endpoints) {
+        this.domainName = (domainName == null) ? "" : domainName;
+        this.endpoints = new ArrayList<>(endpoints);
+    }
+
+    /**
+     * Returns the domain name resolved from the ldap URL. This method returns
+     * the empty string if the {@code LdapDnsProviderResult} is created with a
+     * null domain name.
+     *
+     * @return  the resolved domain name
+     */
+    public String getDomainName() {
+        return domainName;
+    }
+
+    /**
+     * Returns the possibly empty list of individual server endpoints resolved
+     * from the ldap URL.
+     *
+     * @return  a possibly empty unmodifiable {@link List} containing the
+     *          resolved ldap server endpoints
+     */
+    public List<String> getEndpoints() {
+        return endpoints;
+    }
+
+}
diff --git a/jdk/src/share/classes/com/sun/security/ntlm/NTLM.java b/jdk/src/share/classes/com/sun/security/ntlm/NTLM.java
index 24f58af..b846830 100644
--- a/jdk/src/share/classes/com/sun/security/ntlm/NTLM.java
+++ b/jdk/src/share/classes/com/sun/security/ntlm/NTLM.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2021, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -149,7 +149,7 @@
         int readShort(int offset) throws NTLMException {
             try {
                 return (internal[offset] & 0xff) +
-                        ((internal[offset+1] & 0xff << 8));
+                        (((internal[offset+1] & 0xff) << 8));
             } catch (ArrayIndexOutOfBoundsException ex) {
                 throw new NTLMException(NTLMException.PACKET_READ_ERROR,
                         "Input message incorrect size");
diff --git a/jdk/src/share/classes/java/awt/datatransfer/MimeType.java b/jdk/src/share/classes/java/awt/datatransfer/MimeType.java
index f58cffb..0cd52b2 100644
--- a/jdk/src/share/classes/java/awt/datatransfer/MimeType.java
+++ b/jdk/src/share/classes/java/awt/datatransfer/MimeType.java
@@ -25,6 +25,7 @@
 
 package java.awt.datatransfer;
 
+import java.io.ByteArrayOutputStream;
 import java.io.Externalizable;
 import java.io.ObjectOutput;
 import java.io.ObjectInput;
@@ -325,9 +326,12 @@
 ClassNotFoundException {
         String s = in.readUTF();
         if (s == null || s.length() == 0) { // long mime type
-            byte[] ba = new byte[in.readInt()];
-            in.readFully(ba);
-            s = new String(ba);
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            int len = in.readInt();
+            while (len-- > 0) {
+                baos.write(in.readByte());
+            }
+            s = baos.toString();
         }
         try {
             parse(s);
diff --git a/jdk/src/share/classes/java/util/jar/JarFile.java b/jdk/src/share/classes/java/util/jar/JarFile.java
index 4232ac0..775fdc6 100644
--- a/jdk/src/share/classes/java/util/jar/JarFile.java
+++ b/jdk/src/share/classes/java/util/jar/JarFile.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -73,6 +73,9 @@
         SharedSecrets.setJavaUtilJarAccess(new JavaUtilJarAccessImpl());
     }
 
+    private static final sun.misc.JavaUtilZipFileAccess JUZFA =
+            sun.misc.SharedSecrets.getJavaUtilZipFileAccess();
+
     /**
      * The JAR manifest file name.
      */
@@ -179,7 +182,13 @@
                 if (verify) {
                     byte[] b = getBytes(manEntry);
                     if (!jvInitialized) {
-                        jv = new JarVerifier(b);
+                        if (JUZFA.getManifestNum(this) == 1) {
+                            jv = new JarVerifier(manEntry.getName(), b);
+                        } else {
+                            if (JarVerifier.debug != null) {
+                                JarVerifier.debug.println("Multiple MANIFEST.MF found. Treat JAR file as unsigned");
+                            }
+                        }
                     }
                     man = new Manifest(jv, new ByteArrayInputStream(b));
                 } else {
diff --git a/jdk/src/share/classes/java/util/jar/JarInputStream.java b/jdk/src/share/classes/java/util/jar/JarInputStream.java
index 67f27be..3bda111 100644
--- a/jdk/src/share/classes/java/util/jar/JarInputStream.java
+++ b/jdk/src/share/classes/java/util/jar/JarInputStream.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -95,7 +95,7 @@
             man.read(new ByteArrayInputStream(bytes));
             closeEntry();
             if (doVerify) {
-                jv = new JarVerifier(bytes);
+                jv = new JarVerifier(e.getName(), bytes);
                 mev = new ManifestEntryVerifier(man);
             }
             return (JarEntry)super.getNextEntry();
diff --git a/jdk/src/share/classes/java/util/jar/JarVerifier.java b/jdk/src/share/classes/java/util/jar/JarVerifier.java
index 34bf00c..f528de4 100644
--- a/jdk/src/share/classes/java/util/jar/JarVerifier.java
+++ b/jdk/src/share/classes/java/util/jar/JarVerifier.java
@@ -84,6 +84,9 @@
     /** the bytes for the manDig object */
     byte manifestRawBytes[] = null;
 
+    /** the manifest name this JarVerifier is created upon */
+    final String manifestName;
+
     /** controls eager signature validation */
     boolean eagerValidation;
 
@@ -93,7 +96,8 @@
     /** collect -DIGEST-MANIFEST values for blacklist */
     private List<Object> manifestDigests;
 
-    public JarVerifier(byte rawBytes[]) {
+    public JarVerifier(String name, byte rawBytes[]) {
+        manifestName = name;
         manifestRawBytes = rawBytes;
         sigFileSigners = new Hashtable<>();
         verifiedSigners = new Hashtable<>();
@@ -180,7 +184,7 @@
 
         // only set the jev object for entries that have a signature
         // (either verified or not)
-        if (!name.equals(JarFile.MANIFEST_NAME)) {
+        if (!name.equalsIgnoreCase(JarFile.MANIFEST_NAME)) {
             if (sigFileSigners.get(name) != null ||
                     verifiedSigners.get(name) != null) {
                 mev.setEntry(name, je);
@@ -272,7 +276,8 @@
                             }
 
                             sfv.setSignatureFile(bytes);
-                            sfv.process(sigFileSigners, manifestDigests);
+                            sfv.process(sigFileSigners, manifestDigests,
+                                    manifestName);
                         }
                     }
                     return;
@@ -315,7 +320,7 @@
                         sfv.setSignatureFile(bytes);
                     }
                 }
-                sfv.process(sigFileSigners, manifestDigests);
+                sfv.process(sigFileSigners, manifestDigests, manifestName);
 
             } catch (IOException ioe) {
                 // e.g. sun.security.pkcs.ParsingException
@@ -430,9 +435,9 @@
         manDig = null;
         // MANIFEST.MF is always treated as signed and verified,
         // move its signers from sigFileSigners to verifiedSigners.
-        if (sigFileSigners.containsKey(JarFile.MANIFEST_NAME)) {
-            CodeSigner[] codeSigners = sigFileSigners.remove(JarFile.MANIFEST_NAME);
-            verifiedSigners.put(JarFile.MANIFEST_NAME, codeSigners);
+        if (sigFileSigners.containsKey(manifestName)) {
+            CodeSigner[] codeSigners = sigFileSigners.remove(manifestName);
+            verifiedSigners.put(manifestName, codeSigners);
         }
     }
 
@@ -886,7 +891,7 @@
      */
     boolean isTrustedManifestEntry(String name) {
         // How many signers? MANIFEST.MF is always verified
-        CodeSigner[] forMan = verifiedSigners.get(JarFile.MANIFEST_NAME);
+        CodeSigner[] forMan = verifiedSigners.get(manifestName);
         if (forMan == null) {
             return true;
         }
diff --git a/jdk/src/share/classes/java/util/zip/ZipFile.java b/jdk/src/share/classes/java/util/zip/ZipFile.java
index 2978b37..8d0cd17 100644
--- a/jdk/src/share/classes/java/util/zip/ZipFile.java
+++ b/jdk/src/share/classes/java/util/zip/ZipFile.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2021, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,6 +39,7 @@
 import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.WeakHashMap;
+import java.util.jar.JarFile;
 import java.security.AccessController;
 import sun.security.action.GetPropertyAction;
 import static java.util.zip.ZipConstants64.*;
@@ -59,6 +60,7 @@
     private final int total;       // total number of entries
     private final boolean locsig;  // if zip file starts with LOCSIG (usually true)
     private volatile boolean closeRequested = false;
+    private int manifestNum = 0;       // number of META-INF/MANIFEST.MF, case insensitive
 
     private static final int STORED = ZipEntry.STORED;
     private static final int DEFLATED = ZipEntry.DEFLATED;
@@ -207,6 +209,7 @@
                                                Integer.toHexString(mode));
         }
         String name = file.getPath();
+        file = new File(name);
         SecurityManager sm = System.getSecurityManager();
         if (sm != null) {
             sm.checkRead(name);
@@ -224,6 +227,7 @@
         this.name = name;
         this.total = getTotal(jzfile);
         this.locsig = startsWithLOC(jzfile);
+        this.manifestNum = getManifestNum(jzfile);
     }
 
     /**
@@ -762,6 +766,9 @@
                 public boolean startsWithLocHeader(ZipFile zip) {
                     return zip.startsWithLocHeader();
                 }
+                public int getManifestNum(JarFile zip) {
+                    return ((ZipFile)zip).getManifestNum();
+                }
              }
         );
     }
@@ -774,10 +781,23 @@
         return locsig;
     }
 
+    /*
+     * Returns the number of the META-INF/MANIFEST.MF entries, case insensitive.
+     * When this number is greater than 1, JarVerifier will treat a file as
+     * unsigned.
+     */
+    private int getManifestNum() {
+        synchronized (this) {
+            ensureOpen();
+            return manifestNum;
+        }
+    }
+
     private static native long open(String name, int mode, long lastModified,
                                     boolean usemmap) throws IOException;
     private static native int getTotal(long jzfile);
     private static native boolean startsWithLOC(long jzfile);
+    private static native int getManifestNum(long jzfile);
     private static native int read(long jzfile, long jzentry,
                                    long pos, byte[] b, int off, int len);
 
diff --git a/jdk/src/share/classes/sun/font/TrueTypeFont.java b/jdk/src/share/classes/sun/font/TrueTypeFont.java
index 443f0df..ff80214 100644
--- a/jdk/src/share/classes/sun/font/TrueTypeFont.java
+++ b/jdk/src/share/classes/sun/font/TrueTypeFont.java
@@ -547,6 +547,10 @@
                     throw new FontFormatException("bad table, tag="+table.tag);
                 }
             }
+            ByteBuffer maxpTable = getTableBuffer(maxpTag);
+            if (maxpTable.getChar(4) == 0) {
+                throw new FontFormatException("zero glyphs");
+            }
             initNames();
         } catch (Exception e) {
             if (FontUtilities.isLogging()) {
@@ -1007,24 +1011,36 @@
 
     private void setStrikethroughMetrics(ByteBuffer os_2Table, int upem) {
         if (os_2Table == null || os_2Table.capacity() < 30 || upem < 0) {
-            stSize = .05f;
-            stPos = -.4f;
+            stSize = 0.05f;
+            stPos = -0.4f;
             return;
         }
         ShortBuffer sb = os_2Table.asShortBuffer();
         stSize = sb.get(13) / (float)upem;
         stPos = -sb.get(14) / (float)upem;
+        if (stSize < 0f) {
+            stSize = 0.05f;
+        }
+        if (Math.abs(stPos) > 2.0f) {
+            stPos = -0.4f;
+        }
     }
 
     private void setUnderlineMetrics(ByteBuffer postTable, int upem) {
         if (postTable == null || postTable.capacity() < 12 || upem < 0) {
-            ulSize = .05f;
-            ulPos = .1f;
+            ulSize = 0.05f;
+            ulPos = 0.1f;
             return;
         }
         ShortBuffer sb = postTable.asShortBuffer();
         ulSize = sb.get(5) / (float)upem;
         ulPos = -sb.get(4) / (float)upem;
+        if (ulSize < 0f) {
+            ulSize = 0.05f;
+        }
+        if (Math.abs(ulPos) > 2.0f) {
+            ulPos = 0.1f;
+        }
     }
 
     @Override
diff --git a/jdk/src/share/classes/sun/misc/JavaUtilZipFileAccess.java b/jdk/src/share/classes/sun/misc/JavaUtilZipFileAccess.java
index f7f878b..29334d8 100644
--- a/jdk/src/share/classes/sun/misc/JavaUtilZipFileAccess.java
+++ b/jdk/src/share/classes/sun/misc/JavaUtilZipFileAccess.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,8 +25,10 @@
 
 package sun.misc;
 
+import java.util.jar.JarFile;
 import java.util.zip.ZipFile;
 
 public interface JavaUtilZipFileAccess {
     public boolean startsWithLocHeader(ZipFile zip);
+    public int getManifestNum(JarFile zip);
 }
diff --git a/jdk/src/share/classes/sun/net/ftp/impl/FtpClient.java b/jdk/src/share/classes/sun/net/ftp/impl/FtpClient.java
index 9197a79..3b67c64 100644
--- a/jdk/src/share/classes/sun/net/ftp/impl/FtpClient.java
+++ b/jdk/src/share/classes/sun/net/ftp/impl/FtpClient.java
@@ -24,8 +24,25 @@
  */
 package sun.net.ftp.impl;
 
-import java.net.*;
-import java.io.*;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.Closeable;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.UnsupportedEncodingException;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Proxy;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.UnknownHostException;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.security.PrivilegedExceptionAction;
@@ -33,6 +50,7 @@
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Calendar;
 import java.util.Date;
 import java.util.Iterator;
@@ -45,7 +63,11 @@
 import javax.net.ssl.SSLSocketFactory;
 import sun.misc.BASE64Decoder;
 import sun.misc.BASE64Encoder;
-import sun.net.ftp.*;
+import sun.net.ftp.FtpDirEntry;
+import sun.net.ftp.FtpDirParser;
+import sun.net.ftp.FtpProtocolException;
+import sun.net.ftp.FtpReplyCode;
+import sun.net.util.IPAddressUtil;
 import sun.util.logging.PlatformLogger;
 
 
@@ -108,15 +130,16 @@
     private static Pattern[] patterns;
     private static Pattern linkp = Pattern.compile("(\\p{Print}+) \\-\\> (\\p{Print}+)$");
     private DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM, java.util.Locale.US);
-
+    private static final boolean acceptPasvAddressVal;
     static {
         final int vals[] = {0, 0};
         final String encs[] = {null};
-
+        final String acceptPasvAddress[] = {null};
         AccessController.doPrivileged(
                 new PrivilegedAction<Object>() {
 
                     public Object run() {
+                        acceptPasvAddress[0] = System.getProperty("jdk.net.ftp.trustPasvAddress", "false");
                         vals[0] = Integer.getInteger("sun.net.client.defaultReadTimeout", 300_000).intValue();
                         vals[1] = Integer.getInteger("sun.net.client.defaultConnectTimeout", 300_000).intValue();
                         encs[0] = System.getProperty("file.encoding", "ISO8859_1");
@@ -148,6 +171,8 @@
         for (int i = 0; i < patStrings.length; i++) {
             patterns[i] = Pattern.compile(patStrings[i]);
         }
+
+        acceptPasvAddressVal = Boolean.parseBoolean(acceptPasvAddress[0]);
     }
 
     /**
@@ -625,7 +650,6 @@
             //
             // The regular expression is a bit more complex this time, because
             // the parenthesis are optionals and we have to use 3 groups.
-
             if (pasvPat == null) {
                 pasvPat = Pattern.compile("227 .* \\(?(\\d{1,3},\\d{1,3},\\d{1,3},\\d{1,3}),(\\d{1,3}),(\\d{1,3})\\)?");
             }
@@ -637,8 +661,15 @@
             port = Integer.parseInt(m.group(3)) + (Integer.parseInt(m.group(2)) << 8);
             // IP address is simple
             String s = m.group(1).replace(',', '.');
-            dest = new InetSocketAddress(s, port);
+            if (!IPAddressUtil.isIPv4LiteralAddress(s))
+                throw new FtpProtocolException("PASV failed : "  + serverAnswer);
+            if (acceptPasvAddressVal) {
+                dest = new InetSocketAddress(s, port);
+            } else {
+                dest = validatePasvAddress(port, s, server.getInetAddress());
+            }
         }
+
         // Got everything, let's open the socket!
         Socket s;
         if (proxy != null) {
@@ -701,6 +732,86 @@
         return s;
     }
 
+    static final String ERROR_MSG = "Address should be the same as originating server";
+
+    /**
+     * Returns an InetSocketAddress, based on value of acceptPasvAddressVal
+     * and other conditions such as the server address returned by pasv
+     * is not a hostname, is a socks proxy, or the loopback. An exception
+     * is thrown if none of the valid conditions are met.
+     */
+    private InetSocketAddress validatePasvAddress(int port, String s, InetAddress address)
+        throws FtpProtocolException
+    {
+        if (address == null) {
+            return InetSocketAddress.createUnresolved(serverAddr.getHostName(), port);
+        }
+        String serverAddress = address.getHostAddress();
+        if (serverAddress.equals(s)) {
+            return new InetSocketAddress(s, port);
+        } else if (address.isLoopbackAddress() && s.startsWith("127.")) { // can be 127.0
+            return new InetSocketAddress(s, port);
+        } else if (address.isLoopbackAddress()) {
+            if (privilegedLocalHost().getHostAddress().equals(s)) {
+                return new InetSocketAddress(s, port);
+            } else {
+                throw new FtpProtocolException(ERROR_MSG);
+            }
+        } else if (s.startsWith("127.")) {
+            if (privilegedLocalHost().equals(address)) {
+                return new InetSocketAddress(s, port);
+            } else {
+                throw new FtpProtocolException(ERROR_MSG);
+            }
+        }
+        String hostName = address.getHostName();
+        if (!(IPAddressUtil.isIPv4LiteralAddress(hostName) || IPAddressUtil.isIPv6LiteralAddress(hostName))) {
+            InetAddress[] names = privilegedGetAllByName(hostName);
+            String resAddress = null;
+            for (int i = 0; i < names.length; i++) {
+                String nameHostAddress = names[i].getHostAddress();
+                if (s.equalsIgnoreCase(nameHostAddress)) {
+                    resAddress = nameHostAddress;
+                    break;
+                }
+            }
+            if (resAddress != null) {
+                return new InetSocketAddress(s, port);
+            }
+        }
+        throw new FtpProtocolException(ERROR_MSG);
+    }
+
+    private static InetAddress privilegedLocalHost() throws FtpProtocolException {
+        try {
+            return AccessController.doPrivileged(
+                    new PrivilegedExceptionAction<InetAddress>() {
+                        public InetAddress run() throws UnknownHostException {
+                            return InetAddress.getLocalHost();
+                    }
+                });
+        } catch (Exception e) {
+            FtpProtocolException ftpEx = new FtpProtocolException(ERROR_MSG);
+            ftpEx.initCause(e);
+            throw ftpEx;
+        }
+    }
+
+    private static InetAddress[] privilegedGetAllByName(final String hostName) throws FtpProtocolException {
+        try {
+            return AccessController.doPrivileged(
+                    new PrivilegedExceptionAction<InetAddress[]>() {
+                        public InetAddress[] run() throws UnknownHostException {
+                            return InetAddress.getAllByName(hostName);
+                        }
+                    });
+        } catch (Exception e) {
+            FtpProtocolException ftpEx = new FtpProtocolException(ERROR_MSG);
+            ftpEx.initCause(e);
+            throw ftpEx;
+        }
+    }
+
     /**
      * Opens a data connection with the server according to the set mode
      * (ACTIVE or PASSIVE) then send the command passed as an argument.
@@ -711,7 +822,6 @@
      */
     private Socket openDataConnection(String cmd) throws sun.net.ftp.FtpProtocolException, IOException {
         Socket clientSocket;
-
         if (passiveMode) {
             try {
                 return openPassiveDataConnection(cmd);
diff --git a/jdk/src/share/classes/sun/net/httpserver/ServerImpl.java b/jdk/src/share/classes/sun/net/httpserver/ServerImpl.java
index 5b1e1d2..14f6ad3 100644
--- a/jdk/src/share/classes/sun/net/httpserver/ServerImpl.java
+++ b/jdk/src/share/classes/sun/net/httpserver/ServerImpl.java
@@ -559,17 +559,42 @@
                 start = space+1;
                 String version = requestLine.substring (start);
                 Headers headers = req.headers();
-                String s = headers.getFirst ("Transfer-encoding");
+                /* check key for illegal characters */
+                for (String k : headers.keySet()) {
+                    if (!isValidHeaderKey(k)) {
+                        reject(Code.HTTP_BAD_REQUEST, requestLine,
+                                "Header key contains illegal characters");
+                        return;
+                    }
+                }
+                /* checks for unsupported combinations of lengths and encodings */
+                if (headers.containsKey("Content-Length") &&
+                        (headers.containsKey("Transfer-encoding") || headers.get("Content-Length").size() > 1)) {
+                    reject(Code.HTTP_BAD_REQUEST, requestLine,
+                            "Conflicting or malformed headers detected");
+                    return;
+                }
                 long clen = 0L;
-                if (s !=null && s.equalsIgnoreCase ("chunked")) {
-                    clen = -1L;
+                String headerValue = null;
+                List<String> teValueList = headers.get("Transfer-encoding");
+                if (teValueList != null && !teValueList.isEmpty()) {
+                    headerValue = teValueList.get(0);
+                }
+                if (headerValue != null) {
+                    if (headerValue.equalsIgnoreCase("chunked") && teValueList.size() == 1) {
+                        clen = -1L;
+                    } else {
+                        reject(Code.HTTP_NOT_IMPLEMENTED,
+                                requestLine, "Unsupported Transfer-Encoding value");
+                        return;
+                    }
                 } else {
-                    s = headers.getFirst ("Content-Length");
-                    if (s != null) {
-                        clen = Long.parseLong(s);
+                    headerValue = headers.getFirst("Content-Length");
+                    if (headerValue != null) {
+                        clen = Long.parseLong(headerValue);
                     }
                     if (clen == 0) {
-                        requestCompleted (connection);
+                        requestCompleted(connection);
                     }
                 }
                 ctx = contexts.findContext (protocol, uri.getPath());
@@ -877,4 +902,24 @@
             return secs * 1000;
         }
     }
+
+    /*
+     * Validates a RFC 7230 header-key.
+     */
+    static boolean isValidHeaderKey(String token) {
+        if (token == null) return false;
+
+        boolean isValidChar;
+        char[] chars = token.toCharArray();
+        String validSpecialChars = "!#$%&'*+-.^_`|~";
+        for (char c : chars) {
+            isValidChar = ((c >= 'a') && (c <= 'z')) ||
+                          ((c >= 'A') && (c <= 'Z')) ||
+                          ((c >= '0') && (c <= '9'));
+            if (!isValidChar && validSpecialChars.indexOf(c) == -1) {
+                return false;
+            }
+        }
+        return !token.isEmpty();
+    }
 }
diff --git a/jdk/src/share/classes/sun/security/tools/jarsigner/Main.java b/jdk/src/share/classes/sun/security/tools/jarsigner/Main.java
index 28cde7b..f40b54a 100644
--- a/jdk/src/share/classes/sun/security/tools/jarsigner/Main.java
+++ b/jdk/src/share/classes/sun/security/tools/jarsigner/Main.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -705,8 +705,12 @@
                     CodeSigner[] signers = je.getCodeSigners();
                     boolean isSigned = (signers != null);
                     anySigned |= isSigned;
-                    hasUnsignedEntry |= !je.isDirectory() && !isSigned
-                                        && !signatureRelated(name);
+
+                    boolean unsignedEntry = !isSigned
+                            && ((!je.isDirectory() && !signatureRelated(name))
+                            // a directory entry but with a suspicious size
+                            || (je.isDirectory() && je.getSize() > 0));
+                    hasUnsignedEntry |= unsignedEntry;
 
                     int inStoreOrScope = inKeyStore(signers);
 
@@ -731,7 +735,9 @@
                           (inManifest ? rb.getString("m") : rb.getString("SPACE")) +
                           (inStore ? rb.getString("k") : rb.getString("SPACE")) +
                           (inScope ? rb.getString("i") : rb.getString("SPACE")) +
-                          ((inStoreOrScope & NOT_ALIAS) != 0 ?"X":" ") +
+                          ((inStoreOrScope & NOT_ALIAS) != 0 ?
+                          rb.getString("X") : rb.getString("SPACE")) +
+                          (unsignedEntry ? rb.getString("q") : rb.getString("SPACE")) +
                           rb.getString("SPACE"));
                         sb.append("|");
                     }
@@ -756,9 +762,13 @@
                         if (signatureRelated(name)) {
                             sb.append("\n" + tab + rb.getString(
                                     ".Signature.related.entries.") + "\n\n");
+                        } else if (unsignedEntry) {
+                            sb.append('\n').append(tab)
+                                    .append(rb.getString(".Unsigned.entries."))
+                                    .append("\n\n");
                         } else {
                             sb.append("\n" + tab + rb.getString(
-                                    ".Unsigned.entries.") + "\n\n");
+                                    ".Directory.entries.") + "\n\n");
                         }
                     }
 
@@ -835,6 +845,11 @@
                     System.out.println(rb.getString(
                         ".X.not.signed.by.specified.alias.es."));
                 }
+
+                if (hasUnsignedEntry) {
+                    System.out.println(rb.getString(
+                            ".q.unsigned.entry"));
+                }
             }
             if (man == null) {
                 System.out.println();
diff --git a/jdk/src/share/classes/sun/security/tools/jarsigner/Resources.java b/jdk/src/share/classes/sun/security/tools/jarsigner/Resources.java
index da460ca..0e3f5240 100644
--- a/jdk/src/share/classes/sun/security/tools/jarsigner/Resources.java
+++ b/jdk/src/share/classes/sun/security/tools/jarsigner/Resources.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -121,6 +121,8 @@
         {"m", "m"},
         {"k", "k"},
         {"i", "i"},
+        {"X", "X"},
+        {"q", "?"},
         {".and.d.more.", "(and %d more)"},
         {".s.signature.was.verified.",
                 "  s = signature was verified "},
@@ -132,9 +134,12 @@
                 "  i = at least one certificate was found in identity scope"},
         {".X.not.signed.by.specified.alias.es.",
                 "  X = not signed by specified alias(es)"},
+        {".q.unsigned.entry",
+                "  ? = unsigned entry"},
         {"no.manifest.", "no manifest."},
         {".Signature.related.entries.","(Signature related entries)"},
         {".Unsigned.entries.", "(Unsigned entries)"},
+        {".Directory.entries.", "(Directory entries)"},
         {"jar.is.unsigned",
                 "jar is unsigned."},
         {"jar.treated.unsigned",
diff --git a/jdk/src/share/classes/sun/security/util/SignatureFileVerifier.java b/jdk/src/share/classes/sun/security/util/SignatureFileVerifier.java
index 024af90..5a97fa6 100644
--- a/jdk/src/share/classes/sun/security/util/SignatureFileVerifier.java
+++ b/jdk/src/share/classes/sun/security/util/SignatureFileVerifier.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -250,7 +250,7 @@
      *
      */
     public void process(Hashtable<String, CodeSigner[]> signers,
-            List<Object> manifestDigests)
+            List<Object> manifestDigests, String manifestName)
         throws IOException, SignatureException, NoSuchAlgorithmException,
             JarException, CertificateException
     {
@@ -259,7 +259,7 @@
         Object obj = null;
         try {
             obj = Providers.startJarVerification();
-            processImpl(signers, manifestDigests);
+            processImpl(signers, manifestDigests, manifestName);
         } finally {
             Providers.stopJarVerification(obj);
         }
@@ -267,7 +267,7 @@
     }
 
     private void processImpl(Hashtable<String, CodeSigner[]> signers,
-            List<Object> manifestDigests)
+            List<Object> manifestDigests, String manifestName)
         throws IOException, SignatureException, NoSuchAlgorithmException,
             JarException, CertificateException
     {
@@ -350,7 +350,7 @@
         }
 
         // MANIFEST.MF is always regarded as signed
-        updateSigners(newSigners, signers, JarFile.MANIFEST_NAME);
+        updateSigners(newSigners, signers, manifestName);
     }
 
     /**
diff --git a/jdk/src/share/native/java/util/zip/ZipFile.c b/jdk/src/share/native/java/util/zip/ZipFile.c
index cf9ded9..04990d5 100644
--- a/jdk/src/share/native/java/util/zip/ZipFile.c
+++ b/jdk/src/share/native/java/util/zip/ZipFile.c
@@ -147,6 +147,14 @@
     return zip->locsig;
 }
 
+JNIEXPORT jint JNICALL
+Java_java_util_zip_ZipFile_getManifestNum(JNIEnv *env, jclass cls, jlong zfile)
+{
+    jzfile *zip = jlong_to_ptr(zfile);
+
+    return zip->manifestNum;
+}
+
 JNIEXPORT void JNICALL
 Java_java_util_zip_ZipFile_close(JNIEnv *env, jclass cls, jlong zfile)
 {
diff --git a/jdk/src/share/native/java/util/zip/zip_util.c b/jdk/src/share/native/java/util/zip/zip_util.c
index 54d35f1..79c52b2 100644
--- a/jdk/src/share/native/java/util/zip/zip_util.c
+++ b/jdk/src/share/native/java/util/zip/zip_util.c
@@ -74,6 +74,8 @@
 #define PATH_MAX 1024
 #endif
 
+#define META_INF_LEN 9 /* "META-INF/".length() */
+
 static jint INITIAL_META_COUNT = 2;   /* initial number of entries in meta name array */
 
 /*
@@ -444,6 +446,25 @@
 }
 
 /*
+ * Check if the bytes represents a name equals to MANIFEST.MF
+ */
+static int
+isManifestName(const char *name, int length)
+{
+    const char *s;
+    if (length != (int)sizeof("MANIFEST.MF") - 1)
+        return 0;
+    for (s = "MANIFEST.MF"; *s != '\0'; s++) {
+        char c = *name++;
+        // Avoid toupper; it's locale-dependent
+        if (c >= 'a' && c <= 'z') c += 'A' - 'a';
+        if (*s != c)
+            return 0;
+    }
+    return 1;
+}
+
+/*
  * Increases the capacity of zip->metanames.
  * Returns non-zero in case of allocation error.
  */
@@ -513,6 +534,7 @@
 {
     free(zip->entries); zip->entries = NULL;
     free(zip->table);   zip->table   = NULL;
+    zip->manifestNum = 0;
     freeMetaNames(zip);
 }
 
@@ -663,6 +685,8 @@
     for (j = 0; j < tablelen; j++)
         table[j] = ZIP_ENDCHAIN;
 
+    zip->manifestNum = 0;
+
     /* Iterate through the entries in the central directory */
     for (i = 0, cp = cenbuf; cp <= cenend - CENHDR; i++, cp += CENSIZE(cp)) {
         /* Following are unsigned 16-bit */
@@ -690,9 +714,12 @@
             ZIP_FORMAT_ERROR("invalid CEN header (bad header size)");
 
         /* if the entry is metadata add it to our metadata names */
-        if (isMetaName((char *)cp+CENHDR, nlen))
+        if (isMetaName((char *)cp+CENHDR, nlen)) {
+            if (isManifestName((char *)cp+CENHDR+META_INF_LEN, nlen-META_INF_LEN))
+                zip->manifestNum++;
             if (addMetaName(zip, (char *)cp+CENHDR, nlen) != 0)
                 goto Catch;
+        }
 
         /* Record the CEN offset and the name hash in our hash cell. */
         entries[i].cenpos = cenpos + (cp - cenbuf);
diff --git a/jdk/src/share/native/java/util/zip/zip_util.h b/jdk/src/share/native/java/util/zip/zip_util.h
index 124e3f7..0441e9a8 100644
--- a/jdk/src/share/native/java/util/zip/zip_util.h
+++ b/jdk/src/share/native/java/util/zip/zip_util.h
@@ -227,6 +227,7 @@
     char **metanames;     /* array of meta names (may have null names) */
     jint metacurrent;     /* the next empty slot in metanames array */
     jint metacount;       /* number of slots in metanames array */
+    jint manifestNum;     /* number of META-INF/MANIFEST.MF, case insensitive */
     jlong lastModified;   /* last modified time */
     jlong locpos;         /* position of first LOC header (usually 0) */
 } jzfile;
diff --git a/jdk/test/com/sun/jndi/ldap/LdapDnsProviderTest.java b/jdk/test/com/sun/jndi/ldap/LdapDnsProviderTest.java
new file mode 100644
index 0000000..1bc4a30
--- /dev/null
+++ b/jdk/test/com/sun/jndi/ldap/LdapDnsProviderTest.java
@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.security.Permission;
+import java.util.Hashtable;
+import java.util.concurrent.Callable;
+import java.util.concurrent.FutureTask;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.naming.directory.InitialDirContext;
+import javax.naming.directory.SearchControls;
+
+/**
+ * @test
+ * @bug 8160768
+ * @summary ctx provider tests for ldap
+ * @compile dnsprovider/TestDnsProvider.java
+ * @run main/othervm LdapDnsProviderTest
+ * @run main/othervm LdapDnsProviderTest nosm
+ * @run main/othervm LdapDnsProviderTest smnodns
+ * @run main/othervm LdapDnsProviderTest smdns
+ * @run main/othervm LdapDnsProviderTest nosmbaddns
+ */
+
+class DNSSecurityManager extends SecurityManager {
+
+
+
+    /* run main/othervm LdapDnsProviderTest
+
+     * run main/othervm LdapDnsProviderTest nosm
+     * run main/othervm LdapDnsProviderTest smnodns
+     * run main/othervm LdapDnsProviderTest smdns
+     * run main/othervm LdapDnsProviderTest nosmbaddns
+     */
+
+    private boolean dnsProvider = false;
+
+    public void setAllowDnsProvider(boolean allow) {
+        dnsProvider = allow;
+    }
+
+    @Override
+    public void checkPermission(Permission p) {
+        if (p.getName().equals("ldapDnsProvider") && !dnsProvider) {
+            throw new SecurityException(p.getName());
+        }
+    }
+}
+
+class ProviderTest implements Callable<Boolean> {
+
+    private final String url;
+    private final String expected;
+    private final Hashtable<String, String> env = new Hashtable<>(11);
+
+    public ProviderTest(String url, String expected) {
+        this.url = url;
+        this.expected = expected;
+        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
+    }
+
+    boolean shutItDown(InitialContext ctx) {
+        try {
+            if (ctx != null) ctx.close();
+            return true;
+        } catch (NamingException ex) {
+            return false;
+        }
+    }
+
+    public Boolean call() {
+        boolean passed;
+        InitialContext ctx = null;
+
+        if (url != null) {
+            env.put(Context.PROVIDER_URL, url);
+        }
+
+        try {
+            ctx = new InitialDirContext(env);
+            SearchControls scl = new SearchControls();
+            scl.setSearchScope(SearchControls.SUBTREE_SCOPE);
+            ((InitialDirContext)ctx).search(
+                    "ou=People,o=Test", "(objectClass=*)", scl);
+            throw new RuntimeException("Search should not complete");
+        } catch (NamingException e) {
+            e.printStackTrace();
+            passed = e.toString().contains(expected);
+        } finally {
+            shutItDown(ctx);
+        }
+        return passed;
+    }
+}
+
+public class LdapDnsProviderTest {
+
+    private static final String TEST_CLASSES =
+            System.getProperty("test.classes", ".");
+
+    public static void writeFile(String content, File dstFile)
+        throws IOException
+    {
+        try (FileOutputStream dst = new FileOutputStream(dstFile)) {
+            byte[] buf = content.getBytes();
+            dst.write(buf, 0, buf.length);
+        }
+    }
+
+    public static void installServiceConfigurationFile(String content) {
+        String filename = "com.sun.jndi.ldap.spi.LdapDnsProvider";
+
+        File dstDir = new File(TEST_CLASSES, "META-INF/services");
+        if (!dstDir.exists()) {
+            if (!dstDir.mkdirs()) {
+                throw new RuntimeException(
+                    "could not create META-INF/services directory " + dstDir);
+            }
+        }
+        File dstFile = new File(dstDir, filename);
+
+        try {
+            writeFile(content, dstFile);
+        } catch (IOException e) {
+            throw new RuntimeException("could not install " + dstFile, e);
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        if (args.length > 0 && args[0].equals("nosm")) {
+            // no security manager, serviceloader
+            installServiceConfigurationFile("dnsprovider.TestDnsProvider");
+            runTest("ldap:///dc=example,dc=com", "yupyupyup:389");
+        } else if (args.length > 0 && args[0].equals("smnodns")) {
+            // security manager & serviceloader
+            installServiceConfigurationFile("dnsprovider.TestDnsProvider");
+            // install security manager
+            System.setSecurityManager(new DNSSecurityManager());
+            runTest("ldap:///dc=example,dc=com", "ServiceConfigurationError");
+        } else if (args.length > 0 && args[0].equals("smdns")) {
+            // security manager & serviceloader
+            DNSSecurityManager sm = new DNSSecurityManager();
+            installServiceConfigurationFile("dnsprovider.TestDnsProvider");
+            // install security manager
+            System.setSecurityManager(sm);
+            sm.setAllowDnsProvider(true);
+            runTest("ldap:///dc=example,dc=com", "yupyupyup:389");
+        } else if (args.length > 0 && args[0].equals("nosmbaddns")) {
+            // no security manager, no serviceloader
+            // DefaultLdapDnsProvider
+            installServiceConfigurationFile("dnsprovider.MissingDnsProvider");
+            // no SecurityManager
+            runTest("ldap:///dc=example,dc=com", "not found");
+        } else {
+            // no security manager, no serviceloader
+            // DefaultLdapDnsProvider
+            System.err.println("TEST_CLASSES:");
+            System.err.println(TEST_CLASSES);
+            File f = new File(
+                    TEST_CLASSES, "META-INF/services/com.sun.jndi.ldap.spi.LdapDnsProvider");
+            if (f.exists()) {
+                f.delete();
+            }
+
+            // no SecurityManager
+            runTest("ldap:///dc=example,dc=com", "localhost:389");
+            runTest("ldap://localhost/dc=example,dc=com", "localhost:389");
+            runTest("ldap://localhost:111/dc=example,dc=com", "localhost:111");
+            runTest("ldaps://localhost:111/dc=example,dc=com", "localhost:111");
+            runTest("ldaps://localhost/dc=example,dc=com", "localhost:636");
+            runTest(null, "localhost:389");
+            runTest("", "ConfigurationException");
+        }
+    }
+
+    private static void runTest(String url, String expected) {
+        FutureTask<Boolean> future =
+            new FutureTask<>(
+                    new ProviderTest(url, expected));
+        new Thread(future).start();
+
+        System.err.println("Testing: " + url + ", " + expected);
+        while (!future.isDone()) {
+            try {
+                if (!future.get()) {
+                    System.err.println("Test failed");
+                    throw new RuntimeException(
+                            "Test failed, ProviderTest returned false");
+                }
+            } catch (Exception e) {
+                if (!e.toString().contains(expected)) {
+                    System.err.println("Test failed");
+                    throw new RuntimeException(
+                            "Test failed, unexpected result");
+                }
+            }
+        }
+        System.err.println("Test passed");
+    }
+
+}
+
diff --git a/jdk/test/com/sun/jndi/ldap/dnsprovider/TestDnsProvider.java b/jdk/test/com/sun/jndi/ldap/dnsprovider/TestDnsProvider.java
new file mode 100644
index 0000000..6a8798d
--- /dev/null
+++ b/jdk/test/com/sun/jndi/ldap/dnsprovider/TestDnsProvider.java
@@ -0,0 +1,18 @@
+package dnsprovider;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import com.sun.jndi.ldap.spi.LdapDnsProvider;
+import com.sun.jndi.ldap.spi.LdapDnsProviderResult;
+
+public class TestDnsProvider extends LdapDnsProvider {
+    @Override
+    public LdapDnsProviderResult lookupEndpoints(String url,
+                                                           Map<?, ?> env)
+    {
+        List<String> endpoints = new ArrayList<>();
+        endpoints.add("ldap://yupyupyup:389");
+        return new LdapDnsProviderResult("test.com", endpoints);
+    }
+}
diff --git a/jdk/test/com/sun/security/auth/module/LdapLoginModule/CheckConfigs.policy b/jdk/test/com/sun/security/auth/module/LdapLoginModule/CheckConfigs.policy
index 8febfcd..b022858 100644
--- a/jdk/test/com/sun/security/auth/module/LdapLoginModule/CheckConfigs.policy
+++ b/jdk/test/com/sun/security/auth/module/LdapLoginModule/CheckConfigs.policy
@@ -6,6 +6,7 @@
     //permission java.net.SocketPermission "*:389", "connect";
     //permission java.net.SocketPermission "*:636", "connect";
     //permission javax.security.auth.AuthPermission "modifyPrincipals";
+    permission java.lang.RuntimePermission "ldapDnsProvider";
 };
 
 
diff --git a/jdk/test/sun/security/tools/jarsigner/concise_jarsigner.sh b/jdk/test/sun/security/tools/jarsigner/concise_jarsigner.sh
index 89681df..17619d6 100644
--- a/jdk/test/sun/security/tools/jarsigner/concise_jarsigner.sh
+++ b/jdk/test/sun/security/tools/jarsigner/concise_jarsigner.sh
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2021, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -22,7 +22,7 @@
 #
 
 # @test
-# @bug 6802846 8172529 8227758
+# @bug 6802846 8172529 8227758 8260960
 # @summary jarsigner needs enhanced cert validation(options)
 #
 # @run shell/timeout=240 concise_jarsigner.sh
@@ -106,17 +106,20 @@
 LINES=`$JARSIGNER -verify a.jar -verbose:grouped | grep $YEAR | wc -l`
 [ $LINES = 12 ] || exit $LINENO
 
-# 4 groups: MANIFST, unrelated, signed, unsigned
+# 5 groups: MANIFEST, signature related entries, directory entries,
+# signed entries, and unsigned entries.
 LINES=`$JARSIGNER -verify a.jar -verbose:summary | grep $YEAR | wc -l`
-[ $LINES = 4 ] || exit $LINENO
+[ $LINES = 5 ] || exit $LINENO
 
-# still 4 groups, but MANIFEST group has no other file
+# still 5 groups, but MANIFEST group and directory entry group
+# have no other file
 LINES=`$JARSIGNER -verify a.jar -verbose:summary | grep "more)" | wc -l`
 [ $LINES = 3 ] || exit $LINENO
 
-# 5 groups: MANIFEST, unrelated, signed by a1/a2, signed by a2, unsigned
+# 6 groups: MANIFEST, signature related entries, directory entries,
+# signed entries by a1/a2, signed entries by a2, and unsigned entries.
 LINES=`$JARSIGNER -verify a.jar -verbose:summary -certs | grep $YEAR | wc -l`
-[ $LINES = 5 ] || exit $LINENO
+[ $LINES = 6 ] || exit $LINENO
 
 # 2 for MANIFEST, 2*2 for A1/A2, 2 for A3/A4
 LINES=`$JARSIGNER -verify a.jar -verbose -certs | grep "\[certificate" | wc -l`
@@ -130,7 +133,8 @@
 LINES=`$JARSIGNER -verify a.jar -verbose:summary -certs | grep "\[certificate" | wc -l`
 [ $LINES = 5 ] || exit $LINENO
 
-# still 5 groups, but MANIFEST group has no other file
+# still 6 groups, but MANIFEST group and directory entry group
+# have no other file
 LINES=`$JARSIGNER -verify a.jar -verbose:summary -certs | grep "more)" | wc -l`
 [ $LINES = 4 ] || exit $LINENO
 
diff --git a/langtools/.hgtags b/langtools/.hgtags
index e1e4e08..8c5cae16 100644
--- a/langtools/.hgtags
+++ b/langtools/.hgtags
@@ -660,3 +660,6 @@
 92eaf0cd9396049f8807b7aaede5ac3f662745e7 jdk7u291-b01
 92eaf0cd9396049f8807b7aaede5ac3f662745e7 jdk7u291-ga
 92eaf0cd9396049f8807b7aaede5ac3f662745e7 jdk7u301-b00
+c573fe30d9f3729801c776d1f615517292604524 jdk7u301-b01
+c573fe30d9f3729801c776d1f615517292604524 jdk7u301-ga
+c573fe30d9f3729801c776d1f615517292604524 jdk7u311-b00
diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/legacy.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/legacy.properties
index 2504451..7583047 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/legacy.properties
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/legacy.properties
@@ -143,6 +143,7 @@
 com.sun.jndi.ldap.ext = tiger legacy
 com.sun.jndi.ldap.pool = tiger legacy
 com.sun.jndi.ldap.sasl = tiger legacy
+com.sun.jndi.ldap.spi = tiger legacy
 com.sun.jndi.rmi.registry = tiger legacy
 com.sun.jndi.toolkit.corba = tiger legacy
 com.sun.jndi.toolkit.ctx = tiger legacy
diff --git a/langtools/src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java b/langtools/src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java
index 9ee550e..1cf1af3 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java
@@ -476,6 +476,7 @@
             "org.w3c.dom.css",
             "org.w3c.dom.events",
             "org.w3c.dom.views",
+            "com.sun.jndi.ldap.spi",
             "com.sun.management",
             "com.sun.security.auth",
             "com.sun.security.auth.callback",